Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions SEToolbox/Models/StructureCubeGridModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1057,6 +1057,48 @@ public bool ConvertToRoundArmor()
return count > 0;
}

public bool SetPivotPntHere(ViewModels.CubeItemViewModel selectedCubeItem)
{
// Is the selectedCubeItem the pivot point?
var definitionS = SpaceEngineersApi.GetCubeDefinition(selectedCubeItem.TypeId, CubeGrid.GridSizeEnum, selectedCubeItem.SubtypeId);
SerializableBlockOrientation blockOrientation = selectedCubeItem.Cube.BlockOrientation;
var cubePos = selectedCubeItem.Cube.Min.ToVector3I();
if (definitionS.Size.X == 1 && definitionS.Size.Y == 1 && definitionS.Size.Z == 1)
{
}
else
{
var orientCenter = definitionS.Center.Transform(blockOrientation).Abs();
cubePos = selectedCubeItem.Cube.Min.ToVector3I() + orientCenter;
}
if(cubePos.X == 0 && cubePos.Y == 0 && cubePos.Z == 0)
{
return false;
}

//Update the position of each cube to be relative to the selected cube.
var position = selectedCubeItem.Position;
foreach (var cube in CubeGrid.CubeBlocks)
{
// Offset the cube's position by the passed position.
cube.Min = new SerializableVector3I(cube.Min.X - cubePos.X, cube.Min.Y - cubePos.Y, cube.Min.Z - cubePos.Z);
}

//Offset the ship's position by the passed position.
var pivot = CubeGrid.PositionAndOrientation.Value.Position;
var scaledPosition = new VRageMath.Vector3D(cubePos.X, cubePos.Y, cubePos.Z);
scaledPosition *= CubeGrid.GridSizeEnum == MyCubeSize.Large ? 2.5 : 1.0;
CubeGrid.PositionAndOrientation = new MyPositionAndOrientation
{
Position = new VRageMath.Vector3D(pivot.X + scaledPosition.X, pivot.Y + scaledPosition.Y, pivot.Z + scaledPosition.Z),
Forward = CubeGrid.PositionAndOrientation.Value.Forward,
Up = CubeGrid.PositionAndOrientation.Value.Up
};


return true;
}

#region Mirror

public bool MirrorModel(bool usePlane, bool oddMirror)
Expand Down
18 changes: 18 additions & 0 deletions SEToolbox/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -3085,4 +3085,22 @@ Reason: {1}</value>
<data name="DialogNoNetworkTitle" xml:space="preserve">
<value>Can not find update</value>
</data>
<data name="WnExplorerMnuExportCAD" xml:space="preserve">
<value>Export CAD</value>
</data>
<data name="WnExplorerMnuExportCADTooltip" xml:space="preserve">
<value>Export model to SECAD ldr file.</value>
</data>
<data name="CtlCubeMnuConvertSetPivotPoint" xml:space="preserve">
<value>Set Pivot Point</value>
</data>
<data name="CtlCubeMnuConvertSetPivotPointHere" xml:space="preserve">
<value>Use as Pivot Point</value>
</data>
<data name="CtlCubeMnuConvertSetPivotPointHereTooltip" xml:space="preserve">
<value>Set the pivot point to the selected cube item</value>
</data>
<data name="PivotPnt" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\PivotPnt.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>
Binary file added SEToolbox/Resources/PivotPnt.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
204 changes: 199 additions & 5 deletions SEToolbox/ViewModels/ExplorerViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace SEToolbox.ViewModels
{
using Sandbox.Common.ObjectBuilders;
using Sandbox.Definitions;
using SEToolbox.Interfaces;
using SEToolbox.Interop;
using SEToolbox.Interop.Asteroids;
Expand Down Expand Up @@ -142,6 +143,8 @@ public ExplorerViewModel(ExplorerModel dataModel, IDialogService dialogService,

public ICommand ExportBlueprintCommand => new DelegateCommand(ExportBlueprintExecuted, ExportBlueprintCanExecute);

public ICommand ExportCADCommand => new DelegateCommand(ExportCADExecuted, ExportCADCanExecute);

public ICommand CreateFloatingItemCommand => new DelegateCommand(CreateFloatingItemExecuted, CreateFloatingItemCanExecute);

public ICommand GenerateVoxelFieldCommand => new DelegateCommand(GenerateVoxelFieldExecuted, GenerateVoxelFieldCanExecute);
Expand Down Expand Up @@ -430,7 +433,7 @@ public void OpenExecuted()

public bool SaveCanExecute()
{
return _dataModel.ActiveWorld != null && _dataModel.ActiveWorld.IsValid &&
return _dataModel.ActiveWorld != null && _dataModel.ActiveWorld.IsValid &&
((_dataModel.ActiveWorld.SaveType != SaveWorldType.DedicatedServerService && _dataModel.ActiveWorld.SaveType != SaveWorldType.CustomAdminRequired)
|| ((_dataModel.ActiveWorld.SaveType == SaveWorldType.DedicatedServerService || _dataModel.ActiveWorld.SaveType == SaveWorldType.CustomAdminRequired)
&& ToolboxUpdater.IsRuningElevated()));
Expand Down Expand Up @@ -774,6 +777,17 @@ public void ExportBlueprintExecuted()
ExportBlueprintToFile(Selections.ToArray());
}

public bool ExportCADCanExecute()
{
return _dataModel.ActiveWorld != null && _dataModel.ActiveWorld.IsValid && Selections.Count > 0 &&
Selections.Any(e => e is StructureCubeGridViewModel);
}

public void ExportCADExecuted()
{
ExportCADToFile(Selections.ToArray());
}

public bool CreateFloatingItemCanExecute()
{
return _dataModel.ActiveWorld != null && _dataModel.ActiveWorld.IsValid;
Expand Down Expand Up @@ -1205,10 +1219,10 @@ public void InertiaTensorExecuted(bool state)
int count = SetInertiaTensor(Selections, true);
IsBusy = false;

_dialogService.ShowMessageBox(this,
string.Format(Res.ClsExplorerGridChangesMade, count),
Res.ClsExplorerTitleChangesMade,
System.Windows.MessageBoxButton.OK,
_dialogService.ShowMessageBox(this,
string.Format(Res.ClsExplorerGridChangesMade, count),
Res.ClsExplorerTitleChangesMade,
System.Windows.MessageBoxButton.OK,
System.Windows.MessageBoxImage.Information);
}

Expand Down Expand Up @@ -2036,6 +2050,186 @@ public void ExportBlueprintToFile(params IStructureViewBase[] viewModels)
}
}

public void ExportCADToFile(params IStructureViewBase[] viewModels)
{
string localBlueprintsFolder = null;
if (string.IsNullOrEmpty(_dataModel.ActiveWorld.DataPath.BlueprintsPath))
{
// There is no blueprints under Dedicated Server, so cannot find the blueprint folder to save to.
_dialogService.ShowMessageBox(this, Res.ErrorNoBlueprintPath, Res.ErrorNoBlueprintPathTitle, System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand);
return;
}
localBlueprintsFolder = Path.Combine(_dataModel.ActiveWorld.DataPath.BlueprintsPath, SpaceEngineersConsts.LocalBlueprintsSubFolder);

var saveFileDialog = _saveFileDialogFactory();
saveFileDialog.Filter = "SECAD Model File|*.ldr";//AppConstants.CADExportFilter;
saveFileDialog.Title = "Export to SECAD";//Res.DialogExportCADTitle;
saveFileDialog.FileName = "export cad.ldr";
saveFileDialog.OverwritePrompt = true;

if (_dialogService.ShowSaveFileDialog(this, saveFileDialog) == DialogResult.OK)
{
// open the file for writing
using (StreamWriter sw = new StreamWriter(saveFileDialog.FileName, false, Encoding.ASCII))
{
// write the header
sw.WriteLine("0 SECAD Model File");
sw.WriteLine("0 Name: " + Path.GetFileNameWithoutExtension(saveFileDialog.FileName));
sw.WriteLine("0 Author: SEToolbox");
sw.WriteLine("0 Unofficial Model");
sw.WriteLine("0 !LICENSE Redistributable under CCAL version 2.0 : see CAreadme.txt");
sw.WriteLine("0 Forward UP");
sw.WriteLine("");

// Rotation matrix around X axis
Matrix matrix = Matrix.CreateFromAxisAngle(Vector3.UnitX, MathHelper.ToRadians(0));

// write the model
foreach (var viewModel in viewModels)
{
if (viewModel is StructureCubeGridViewModel model)
{
foreach (CubeItemViewModel block in model.CubeList)
{
MyCubeBlockDefinition definition = SpaceEngineersApi.GetCubeDefinition(block.TypeId, block.CubeSize, block.SubtypeId);
System.Windows.Media.Brush clr = block.Color;
BindablePoint3DIModel pos = block.Position;
Vector3I sz = definition.Size;
SerializableBlockOrientation blockOrientation = block.Cube.BlockOrientation;

MatrixI mt = new MatrixI(blockOrientation);
Vector3I posT = Vector3.Transform(pos.ToVector3I(), matrix).RoundToVector3I();
mt.ForwardVector = new Vector3I(mt.ForwardVector.X, mt.ForwardVector.Y, mt.ForwardVector.Z);

// mt.Translation = pos.ToVector3I();
// Matrix mtF = mt.GetFloatMatrix();

// Matrix mtPO = new SerializableBlockOrientation(Base6Directions.Direction.Up, Base6Directions.Direction.Forward).ToQuaternion().ToMatrix(); // model.DataModel.PositionAndOrientation.Value.ToMatrix();
// mtPO = Matrix.Invert(mtPO);
// Matrix mtX = Matrix.Multiply(mtPO, mtF);
// mtX = Matrix.Round(ref mtX);

// format for output is 1 < colour > x y z a b c d e f g h i < file >
sw.WriteLine(string.Format("0 TypeId: {0} SubTypeId: {1}", block.TypeId.ToString(), block.SubtypeId));
sw.WriteLine(string.Format("0 {0}|Size:{1,3},{2,3},{3,3}|Orientation:{4,3} {5,3}|Pos:{6,3} {7,3} {8,3}", block.FriendlyName, sz.X, sz.Y, sz.Z,
blockOrientation.Forward.ToString(), blockOrientation.Up.ToString(), pos.X, pos.Y, pos.Z));

//Matrix m0 = mt.GetFloatMatrix();
//Matrix m1 = new Matrix(1,0,0,0,1,0,0,0,-1);
//Matrix.Invert(ref m1, out m1);

//Matrix m2 = Matrix.Multiply(m0, m1);
string posStr = string.Format("{0,3} {1,3} {2,3}", posT.X * 10, posT.Z * 10, posT.Y * 10);

sw.WriteLine("0 RIGHT UP FORWARD");
sw.WriteLine("0 _X_ _Y_ _Z_ _X_ _Y_ _Z_ _X_ _Y_ _Z_");
string vecStr = string.Format("{0,3} {1,3} {2,3} {3,3} {4,3} {5,3} {6,3} {7,3} {8,3}",
mt.RightVector.X, mt.RightVector.Y, mt.RightVector.Z,
mt.UpVector.X, mt.UpVector.Y, mt.UpVector.Z,
mt.ForwardVector.X, mt.ForwardVector.Y, mt.ForwardVector.Z);

sw.WriteLine("0 blockOrientation: {0}", vecStr);
sw.WriteLine("0");
sw.WriteLine("0 RIGHT UP FORWARD");
sw.WriteLine("0 CLR _X_ _Y_ _Z_ _X_ _Y_ _Z_ _X_ _Y_ _Z_ _X_ _Y_ _Z_");

MatrixI localMatrix = new MatrixI(Base6Directions.Direction.Forward, Base6Directions.Direction.Up);
Vector3I normal = definition.Center;
Vector3I normal2 = definition.Size - 1;
Vector3I.TransformNormal(ref normal2, ref localMatrix, out Vector3I result);
Vector3I.TransformNormal(ref normal, ref localMatrix, out Vector3I result2);
Vector3I vector3I = Vector3I.Abs(result);
Vector3I result3 = result2 + block.Cube.Min;

if (result.X != vector3I.X)
{
result3.X += vector3I.X;
}
if (result.Y != vector3I.Y)
{
result3.Y += vector3I.Y;
}
if (result.Z != vector3I.Z)
{
result3.Z += vector3I.Z;
}


string line;
switch (block.TypeId.ToString())
{
case "MyObjectBuilder_Thrust":
line = string.Format("1 9 {1} {2} Thruster.dat", 9, posStr, " 1 0 0 0 1 0 0 0 1");
break;
case "MyObjectBuilder_Reactor":
line = string.Format("1 17 {1} {2} Lrg1x1x1.dat", 17, posStr, vecStr);
break;
case "MyObjectBuilder_LandingGear":
line = string.Format("1 73 {1} {2} LandingGear.dat", 73, posStr, vecStr);
break;
case "MyObjectBuilder_Beacon":
line = string.Format("1 25 {1} {2} Beacon.dat", 25, posStr, vecStr);
break;
case "MyObjectBuilder_Refinery":
line = string.Format("1 70 {1} {2} Refinery.dat", 70, posStr, vecStr);
break;
case "MyObjectBuilder_Assembler":
line = string.Format("1 {0,3} {1} {2} Assembler.dat", 15, posStr, vecStr);
break;
case "MyObjectBuilder_CargoContainer":
line = string.Format("1 19 {1} {2} Lrg1x1x1.dat", 19, posStr, vecStr);
break;
case "MyObjectBuilder_Gyro":
line = string.Format("1 74 {1} {2} Lrg1x1x1.dat", 74, posStr, vecStr);
break;
case "MyObjectBuilder_CubeBlock":
if (block.SubtypeId == "LargeHeavyBlockArmorBlock")
{
line = string.Format("1 8 {1} {2} LightArmour.dat", 8, posStr, vecStr);
}
else
{
line = string.Format("1 {0,-3} {1} {2} LightArmour.dat", 7, posStr, vecStr);
}
break;
case "MyObjectBuilder_ConveyorConnector":
line = string.Format("1 27 {1} {2} Lrg1x1x1.dat", 27, posStr, vecStr);
break;
case "MyObjectBuilder_ShipConnector":
line = string.Format("1 27 {1} {2} Lrg1x1x1.dat", 27, posStr, vecStr);
break;
case "MyObjectBuilder_Cockpit":
line = string.Format("1 2 {1} {2} Cockpit.dat", 2, posStr, vecStr);
break;
case "MyObjectBuilder_ShipWelder":
line = string.Format("1 29 {1} {2} Lrg1x1x2.dat", 29, posStr, vecStr);
break;
case "MyObjectBuilder_OxygenTank":
line = string.Format("1 14 {1} {2} OxygenTank.dat", 14, posStr, vecStr);
break;
case "MyObjectBuilder_OreDetector":
line = string.Format("1 15 {1} {2} OreDetector.dat", 15, posStr, vecStr);
break;
default:
if (block.SubtypeId == "")
{
line = string.Format("1 0 {1} {2} {5}.dat", 0, posStr, vecStr, block.TypeId.ToString());
}
else
{
line = string.Format("1 0 {1} {2} {5}.dat", 0, posStr, vecStr, block.SubtypeId);
}
break;
}
sw.WriteLine(line);
sw.WriteLine("");
}
}
}
}
}
}

public void TestCalcCubesModel(params IStructureViewBase[] viewModels)
{
var bld = new StringBuilder();
Expand Down
16 changes: 16 additions & 0 deletions SEToolbox/ViewModels/StructureCubeGridViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ public StructureCubeGridViewModel(BaseViewModel parentViewModel, StructureCubeGr

public ICommand ConvertCubeToFrameworkCommand => new DelegateCommand<double>(ConvertCubeToFrameworkExecuted, ConvertCubeToFrameworkCanExecute);

public ICommand ConvertCubeSetPivotPntHere => new DelegateCommand(ConvertCubeSetPivotPointHereExecuted, ConvertCubeSetPivotPointHereCanExecute);

public ICommand ReplaceCubesCommand => new DelegateCommand(ReplaceCubesExecuted, ReplaceCubesCanExecute);

public ICommand ColorCubesCommand => new DelegateCommand(ColorCubesExecuted, ColorCubesCanExecute);
Expand Down Expand Up @@ -576,6 +578,20 @@ public bool ConvertCubeToFrameworkCanExecute(double value)
return SelectedCubeItem != null;
}

public void ConvertCubeSetPivotPointHereExecuted()
{
DataModel.SetPivotPntHere(SelectedCubeItem);
MainViewModel.IsModified = true;
MainViewModel.CalcDistances();
IsSubsSystemNotReady = true;
DataModel.InitializeAsync();
}

public bool ConvertCubeSetPivotPointHereCanExecute()
{
return Selections.Count == 1;
}

public void ConvertCubeToFrameworkExecuted(double value)
{
MainViewModel.IsBusy = true;
Expand Down
Loading