Initial Commit

This commit is contained in:
2025-07-04 20:33:06 +03:00
commit 8f09347ae0
9219 changed files with 2447903 additions and 0 deletions
@@ -0,0 +1,117 @@
using Imstk;
using ImstkUnity;
using UnityEditor;
using UnityEngine;
namespace ImstkEditor
{
[CustomEditor(typeof(ImstkUnity.CollisionInteraction), true)]
public class CollisionInteractionEditor : Editor
{
double _friction = 0.0;
double _restitution = 0.0;
double _deformableStiffness1 = 0.2;
double _deformableStiffness2 = 0.2;
double _rigidBodyCompliance = 0.0001;
DynamicalModel _model1;
DynamicalModel _model2;
static string[] _options;
public static string[] CDOptions
{
get
{
if (_options == null)
{
var names = CDObjectFactory.getNames();
_options = new string[names.Count + 1];
_options[0] = "Auto";
for (int i = 0; i < names.Count; ++i)
{
_options[i + 1] = names[i];
}
}
return _options;
}
}
string _message;
public override void OnInspectorGUI()
{
var script = target as ImstkUnity.CollisionInteraction;
EditorGUI.BeginChangeCheck();
_message = "Model 1 " + GetGeometryType(script.model1);
_model1 = EditorGUILayout.ObjectField(_message, script.model1, typeof(DynamicalModel), true) as DynamicalModel;
_message = "Model 2 " + GetGeometryType(script.model2);
_model2 = EditorGUILayout.ObjectField(_message, script.model2, typeof(DynamicalModel), true) as DynamicalModel;
var selected = System.Array.IndexOf(CDOptions, script.collisionTypeName);
selected = EditorGUILayout.Popup("Detection Type", selected, CDOptions);
_message = "Auto Type: ";
if (_model1 != null && _model1.GetCollidingGeometry() != null &&
_model2 != null && _model2.GetCollidingGeometry() != null)
{
_message += ImstkUnity.CollisionInteraction.GetCDType(_model1, _model2);
}
else
{
_message += " None";
}
EditorGUILayout.LabelField(_message);
_friction = EditorGUILayout.DoubleField("Friction", script.friction);
_restitution = EditorGUILayout.DoubleField("Restitution", script.restitution);
var guiContent = new GUIContent("Deform. Stiffness 1", "A good default value is 1/number of iterations from the simulation manager");
_deformableStiffness1 = EditorGUILayout.DoubleField(guiContent, script.deformableStiffness1);
guiContent = new GUIContent("Deform. Stiffness 2", "A good default value is 1/number of iterations from the simulation manager");
_deformableStiffness2 = EditorGUILayout.DoubleField(guiContent, script.deformableStiffness2);
_rigidBodyCompliance = EditorGUILayout.DoubleField("Rigid Compliance", script.rigidBodyCompliance);
if (EditorGUI.EndChangeCheck())
{
script.friction = _friction;
script.restitution = _restitution;
script.model1 = _model1;
script.model2 = _model2;
script.collisionTypeName = CDOptions[selected];
script.deformableStiffness1 = _deformableStiffness1;
script.deformableStiffness2 = _deformableStiffness2;
script.rigidBodyCompliance = _rigidBodyCompliance;
}
}
private string GetGeometryType(DynamicalModel model)
{
if (model == null)
{
return "";
}
Imstk.Geometry geom = model.GetCollidingGeometry();
if (geom == null)
{
return "<no geometry>";
}
else
{
return "<" + geom.getTypeName() + ">";
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e1e3f82b50dba9749aa16e4b978717e3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,66 @@
using ImstkUnity;
using UnityEditor;
using UnityEngine;
namespace ImstkEditor
{
[CustomEditor(typeof(ConnectiveTissue))]
public class ConnectiveTissueEditor : Editor
{
// Local variables for caching editor results
Deformable sideA;
Deformable sideB;
double maxDistance;
double strandsPerFace;
int segmentsPerStrand;
double distanceStiffness;
double uniformMassValue;
double viscousDampingCoeff;
GUIContent sideAContent = new GUIContent("Side A", "One side of the objects that should be connected.");
GUIContent sideBContent = new GUIContent("Side B", "One side of the objects that should be connected.");
GUIContent maxDistContent = new GUIContent("Maximum Distance", "If side a and b are closer than this value" +
" connective tissue strands will be generated. If 0 the distance between the centers will be used");
GUIContent strandsPerFaceContent = new GUIContent("Strands per Face", "Indicates the density of strands " +
"that are being generated, fractions can be used e.g. 0.5 will generate a strand for half the faces");
GUIContent segmentsPerStrandContent = new GUIContent("Segments per Strand", "Determines the number of " +
"segments for each strand");
GUIContent distanceStiffnessContent = new GUIContent("Distance Stiffness", "Determines how much the " +
"connective tissue will resist extension.");
GUIContent massValueContent = new GUIContent("Uniform Mass Value", "Mass per vertex of the object");
GUIContent viscousDampingContent = new GUIContent("Viscous Damping", "Dampens the system");
public override void OnInspectorGUI()
{
var script = target as ConnectiveTissue;
EditorGUI.BeginChangeCheck();
sideA = EditorGUILayout.ObjectField(sideAContent, script.objectA, typeof(ImstkUnity.Deformable), true) as ImstkUnity.Deformable;
sideB = EditorGUILayout.ObjectField(sideBContent,script.objectB, typeof(ImstkUnity.Deformable), true) as ImstkUnity.Deformable;
maxDistance = EditorGUILayout.DoubleField(maxDistContent, script.maxDistance);
strandsPerFace = EditorGUILayout.DoubleField(strandsPerFaceContent, script.strandsPerFace);
segmentsPerStrand = EditorGUILayout.IntField(segmentsPerStrandContent, script.segmentsPerStrand);
distanceStiffness = EditorGUILayout.DoubleField(distanceStiffnessContent, script.distanceStiffness);
uniformMassValue = EditorGUILayout.DoubleField(massValueContent, script.uniformMassValue);
viscousDampingCoeff = EditorGUILayout.DoubleField(viscousDampingContent, script.viscousDampingCoeff);
if (EditorGUI.EndChangeCheck())
{
if ((sideA == null && sideB == null) || sideA != sideB)
{
script.objectA = sideA;
script.objectB = sideB;
}
script.maxDistance = maxDistance;
script.strandsPerFace = strandsPerFace;
script.segmentsPerStrand = segmentsPerStrand;
script.distanceStiffness = distanceStiffness;
script.uniformMassValue = uniformMassValue;
script.viscousDampingCoeff = viscousDampingCoeff;
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2b4588cff62e4364d93013f493396304
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,61 @@
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
namespace ImstkEditor
{
/// <summary>
/// Adds the given define symbols to PlayerSettings define symbols.
/// Just add your own define symbols to the Symbols property at the below.
/// see https://forum.unity.com/threads/scripting-define-symbols-access-in-code.174390/
/// </summary>
[InitializeOnLoad]
public class DefineSymbols : Editor
{
/// <summary>
/// Symbols that will be added to the editor
/// </summary>
public static readonly string[] StaticSymbols = new string[] { };
public static bool runonce = false;
/// <summary>
/// Add define symbols as soon as Unity gets done compiling.
/// </summary>
static DefineSymbols()
{
string definesString = PlayerSettings.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup);
List<string> allDefines = definesString.Split(';').ToList();
List<string> originalDefines = new List<string>(allDefines);
allDefines.AddRange(StaticSymbols.Except(allDefines));
allDefines.AddRange(GetDeviceSymbols().Except(allDefines));
if (Enumerable.SequenceEqual(allDefines, originalDefines)) return;
PlayerSettings.SetScriptingDefineSymbolsForGroup(
EditorUserBuildSettings.selectedBuildTargetGroup,
string.Join(";", allDefines.ToArray()));
}
/// <summary>
/// Check through the known device names and see if it exists in the factory,
/// if yes, set the appropriate symbol so that the device class will be compiled
/// </summary>
private static List<string> GetDeviceSymbols()
{
var factory = new Imstk.DeviceManagerFactory();
var names = new string[] { "OpenHapticDeviceManager", "IMSTK_USE_OPENHAPTICS",
"HaplyDeviceManager", "IMSTK_USE_HAPLY",
"VRPNDeviceManager", "IMSTK_USE_VRPN" };
var symbols = new List<string>();
for (int i = 0; i < names.Length; i += 2)
{
if (Imstk.DeviceManagerFactory.contains(names[i]))
{
symbols.Add(names[i + 1]);
}
}
return symbols;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5409589cb14fa6e4eb717abe09f3a86b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,195 @@
/*=========================================================================
Library: iMSTK-Unity
Copyright (c) Kitware, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
using ImstkUnity;
using UnityEngine;
using UnityEditor;
namespace ImstkEditor
{
[CustomEditor(typeof(Deformable))]
public class DeformableEditor : DynamicalModelEditor
{
bool _cleanVisualMesh = false;
bool _bodyDamping = false;
double _linearDampingCoeff = 0.0;
double _angularDampingCoeff = 0.0;
public override void OnInspectorGUI()
{
Deformable script = target as Deformable;
EditorGUI.BeginChangeCheck();
GeometryFilter visualGeomFilter = EditorUtils.GeomFilterField("Visual Geometry", script.visualGeomFilter);
GeometryFilter physicsGeomFilter = EditorUtils.GeomFilterField("Physics Geometry", script.physicsGeomFilter);
GeometryFilter collisionGeomFilter = EditorUtils.GeomFilterField("Collision Geometry", script.collisionGeomFilter);
if (visualGeomFilter != null && visualGeomFilter == physicsGeomFilter)
{
bool val = script.cleanVisualMesh;
if (visualGeomFilter != script.visualGeomFilter)
{
val = visualGeomFilter.type == GeometryType.UnityMesh;
}
GUILayout.BeginVertical(EditorStyles.helpBox);
EditorGUILayout.HelpBox(
"Some Mesh import may create `duplicate vertices` this will cause your physics object" +
" to fall apart at seams that might not be visible in the data. use the `Clean Visual Mesh` option" +
" to prevent this." ,MessageType.Warning);
_cleanVisualMesh = EditorGUILayout.Toggle("Clean Visual Mesh", val);
GUILayout.EndVertical();
}
GUILayout.BeginVertical(EditorStyles.helpBox);
bool useDistanceConstraint = EditorGUILayout.Toggle("Distance Stiffness", script.useDistanceConstraint);
double distanceStiffness = script.distanceStiffness;
if (useDistanceConstraint)
distanceStiffness = EditorGUILayout.DoubleField("Stiffness", script.distanceStiffness);
GUILayout.EndVertical();
GUILayout.BeginVertical(EditorStyles.helpBox);
bool useBendConstraint = EditorGUILayout.Toggle("Bend Stiffness", script.useBendConstraint);
double bendStiffness = script.bendStiffness;
int bendStride = script.maxBendStride;
if (useBendConstraint)
{
bendStiffness = EditorGUILayout.DoubleField("Stiffness", script.bendStiffness);
bendStride = EditorGUILayout.IntField("Stride", script.maxBendStride);
}
GUILayout.EndVertical();
GUILayout.BeginVertical(EditorStyles.helpBox);
bool useDihedralConstraint = EditorGUILayout.Toggle("Dihedral Stiffness", script.useDihedralConstraint);
double dihedralStiffness = script.dihedralStiffness;
if (useDihedralConstraint)
dihedralStiffness = EditorGUILayout.DoubleField("Stiffness", script.dihedralStiffness);
GUILayout.EndVertical();
GUILayout.BeginVertical(EditorStyles.helpBox);
bool useAreaConstraint = EditorGUILayout.Toggle("Area Stiffness", script.useAreaConstraint);
double areaStiffness = script.areaStiffness;
if (useAreaConstraint)
areaStiffness = EditorGUILayout.DoubleField("Stiffness", script.areaStiffness);
GUILayout.EndVertical();
GUILayout.BeginVertical(EditorStyles.helpBox);
bool useVolumeConstraint = EditorGUILayout.Toggle("Volume Stiffness", script.useVolumeConstraint);
double volumeStiffness = script.volumeStiffness;
if (useVolumeConstraint)
volumeStiffness = EditorGUILayout.DoubleField("Stiffness", script.volumeStiffness);
GUILayout.EndVertical();
GUILayout.BeginVertical(EditorStyles.helpBox);
bool useFEMConstraint = EditorGUILayout.Toggle("FEM", script.useFEMConstraint);
double youngsModulus = script.youngsModulus;
double possionsRatio = script.possionsRatio;
bool useYoungsModulus = script.useYoungsModulus;
double mu = script.mu;
double lambda = script.lambda;
Imstk.PbdFemConstraint.MaterialType materialType = script.materialType;
if (useFEMConstraint)
{
useYoungsModulus = EditorGUILayout.Toggle("Use Youngs Modulus", script.useYoungsModulus);
if (useYoungsModulus)
{
youngsModulus = EditorGUILayout.DoubleField("Youngs Modulus", script.youngsModulus);
possionsRatio = EditorGUILayout.DoubleField("Possions Ratio", script.possionsRatio);
}
else
{
mu = EditorGUILayout.DoubleField("Mu", script.mu);
lambda = EditorGUILayout.DoubleField("Lambda", script.lambda);
}
materialType = (Imstk.PbdFemConstraint.MaterialType)EditorGUILayout.EnumPopup("Material Type", script.materialType);
}
GUILayout.EndVertical();
GUILayout.BeginVertical(EditorStyles.helpBox);
bool ignoreGravity = EditorGUILayout.Toggle("Ignore Gravity", script.ignoreGravity);
double uniformMassValue = EditorGUILayout.DoubleField("Uniform Mass Value", script.uniformMassValue);
if (script.physicsGeomFilter != null)
{
var physicsGeom = Imstk.Utils.CastTo<Imstk.PointSet>(script.GetPhysicsGeometry());
if (physicsGeom != null)
{
var count = physicsGeom.getNumVertices();
double mass = EditorGUILayout.DoubleField("Mass ", count * uniformMassValue);
if (mass != count * uniformMassValue)
{
uniformMassValue = mass / count;
}
}
}
GUILayout.EndVertical();
GUILayout.BeginVertical(EditorStyles.helpBox);
_bodyDamping = EditorGUILayout.Toggle("Use Body Damping", script.useBodyDamping);
if (_bodyDamping)
{
_linearDampingCoeff = EditorGUILayout.Slider("Linear Damping Coeff", (float)script.linearDampingCoeff, 0, 1);
_angularDampingCoeff = EditorGUILayout.Slider("Angular Damping Coeff", (float)script.angularDampingCoeff, 0, 1);
}
GUILayout.EndVertical();
if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(script, "Change of Parameters");
script.useDistanceConstraint = useDistanceConstraint;
script.distanceStiffness = distanceStiffness;
script.useBendConstraint = useBendConstraint;
script.bendStiffness = bendStiffness;
script.maxBendStride = bendStride;
script.useDihedralConstraint = useDihedralConstraint;
script.dihedralStiffness = dihedralStiffness;
script.useAreaConstraint = useAreaConstraint;
script.areaStiffness = areaStiffness;
script.useVolumeConstraint = useVolumeConstraint;
script.volumeStiffness = volumeStiffness;
script.useFEMConstraint = useFEMConstraint;
script.youngsModulus = youngsModulus;
script.possionsRatio = possionsRatio;
script.mu = mu;
script.lambda = lambda;
script.uniformMassValue = uniformMassValue;
script.useYoungsModulus = useYoungsModulus;
script.materialType = materialType;
script.useBodyDamping = _bodyDamping;
script.linearDampingCoeff = _linearDampingCoeff;
script.angularDampingCoeff = _angularDampingCoeff;
script.visualGeomFilter = visualGeomFilter;
script.cleanVisualMesh = _cleanVisualMesh;
script.physicsGeomFilter = physicsGeomFilter;
script.collisionGeomFilter = collisionGeomFilter;
script.ignoreGravity = ignoreGravity;
}
base.HandleColliders(script);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9387229fe45d625478e06d841a78066b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,146 @@
using ImstkUnity;
using System.Linq;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace ImstkEditor
{
public class DynamicalModelEditor : Editor
{
bool _collisionsFolded = false;
List<DynamicalModel> _allDeformables;
public DynamicalModelEditor()
{
EditorApplication.hierarchyChanged += OnHierarchyChanged;
}
~DynamicalModelEditor()
{
EditorApplication.hierarchyChanged -= OnHierarchyChanged;
}
public void OnEnable()
{
}
private void OnHierarchyChanged()
{
_allDeformables = (Resources.FindObjectsOfTypeAll(typeof(DynamicalModel)) as DynamicalModel[]).ToList<DynamicalModel>();
SimulationManager.Instance().collisions.RemoveAllNull();
}
public void HandleColliders(DynamicalModel script)
{
if (_allDeformables == null)
{
OnHierarchyChanged();
}
EditorGUI.BeginChangeCheck();
var editorData = DrawColliders(script);
if (EditorGUI.EndChangeCheck())
{
var simulationManager = SimulationManager.Instance();
Undo.RegisterCompleteObjectUndo(simulationManager, "Update Collisions");
simulationManager.collisions = editorData;
}
}
protected CollisionInteractions DrawColliders(DynamicalModel script)
{
var allCollisions = SimulationManager.Instance().collisions;
var editorData = new CollisionInteractions(allCollisions);
_collisionsFolded = EditorGUILayout.Foldout(_collisionsFolded, "Colliding Objects");
if (_collisionsFolded)
{
EditorGUILayout.BeginVertical();
for (int i = 0; i < _allDeformables.Count; ++i)
{
var item = _allDeformables[i];
if (item == script) continue;
EditorGUILayout.BeginVertical();
// Title line with Toggle
EditorGUILayout.BeginHorizontal();
var enabled = allCollisions.IsEnabled(script, item);
var autoType = ImstkUnity.CollisionInteraction.GetCDType(script, item);
var newEnabled = false;
EditorGUI.BeginDisabledGroup(autoType == "");
newEnabled = EditorGUILayout.Toggle(enabled, GUILayout.Width(20));
EditorGUI.EndDisabledGroup();
if (enabled != newEnabled)
{
if (newEnabled)
{
editorData.Add(script, item);
}
else
{
editorData.Remove(script, item);
}
}
EditorGUI.BeginDisabledGroup(!newEnabled && autoType == "");
EditorGUILayout.LabelField(item.name);
if (autoType == "")
{
EditorGUILayout.LabelField("No collision type available");
}
EditorGUI.EndDisabledGroup();
EditorGUILayout.EndHorizontal();
if (newEnabled)
{
EditorGUILayout.BeginVertical();
var d = editorData.GetData(script, item);
var _message = "Auto Type: ";
if (d.model1 != null && d.model1.GetCollidingGeometry() != null &&
d.model2 != null && d.model2.GetCollidingGeometry() != null)
{
_message += ImstkUnity.CollisionInteraction.GetCDType(d.model1, d.model2);
}
else
{
_message += " None ";
}
EditorGUILayout.LabelField(_message);
var selected = System.Array.IndexOf(CollisionInteractionEditor.CDOptions, d.collisionTypeName);
if (selected < 0) selected = 0;
selected = EditorGUILayout.Popup("Detection Type", selected, CollisionInteractionEditor.CDOptions);
d.collisionTypeName = CollisionInteractionEditor.CDOptions[selected];
d.friction = EditorGUILayout.DoubleField("Friction", d.friction);
d.restitution = EditorGUILayout.DoubleField("Restitution", d.restitution);
var guiContent = new GUIContent("Deform. Stiffness 1", "A good default value is 1/number of iterations from the simulation manager");
d.deformableStiffness1 = EditorGUILayout.DoubleField(guiContent, d.deformableStiffness1);
guiContent = new GUIContent("Deform. Stiffness 2", "A good default value is 1/number of iterations from the simulation manager");
d.deformableStiffness2 = EditorGUILayout.DoubleField(guiContent, d.deformableStiffness2);
d.rigidBodyCompliance = EditorGUILayout.DoubleField("Rigid Compliance", d.rigidBodyCompliance);
EditorGUILayout.EndVertical();
}
EditorGUILayout.EndVertical();
// Needs to move into the undo section
}
EditorGUILayout.EndVertical();
}
return editorData;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e8717cb3ee56ae44ba778d9c36370886
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
+132
View File
@@ -0,0 +1,132 @@
/*=========================================================================
Library: iMSTK-Unity
Copyright (c) Kitware, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
using System.IO;
using UnityEditor;
using UnityEngine;
using ImstkUnity;
namespace ImstkEditor
{
public static class EditorUtils
{
public static GeometryFilter GeomFilterField(string fieldName, GeometryFilter filter)
{
return EditorGUILayout.ObjectField(fieldName, filter, typeof(GeometryFilter), true) as GeometryFilter;
}
/// <summary>
/// Clears all plugins and iMSTKSharp directory ".cs" files. Reinstalls
/// from installSourcePath
/// </summary>
/// <param name="installSourcePath"></param>
public static void InstallImstk(string installSourcePath)
{
// Get the install directory
if (installSourcePath.Length != 0)
{
// First check the directory exists
if (!Directory.Exists(installSourcePath))
{
Debug.LogError("Failed to install imstk, source location does not exist: " + installSourcePath);
}
// Next check that a file exists to lightly verify we have the right directory
if (!Directory.Exists(installSourcePath + "/lib/cmake/iMSTK-5.0") ||
!File.Exists(installSourcePath + "/lib/cmake/iMSTK-5.0/iMSTKConfig.cmake"))
{
Debug.LogError("Could not find relevant files, check the imstk install directory is specified properly: " + installSourcePath);
}
// Determine the directory what this script resides in and therefore the location of
// the Plugins directory
string[] res = System.IO.Directory.GetFiles(Application.dataPath, "EditorUtils.cs", SearchOption.AllDirectories);
if (res.Length == 0)
{
Debug.LogError("Could not find target directory");
return;
}
string dataPath = res[0].Replace("EditorUtils.cs", "").Replace("\\", "/") + "../../";
// Clear plugins directory and copy all files from bin to plugins
ClearFiles(dataPath + "/Plugins/");
CopyFiles(installSourcePath + "/bin/", dataPath + "/Plugins/", new string[] { ".dll", ".so" });
AssetDatabase.Refresh();
}
}
/// <summary>
/// Clear all files at path
/// </summary>
public static void ClearFiles(string path)
{
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
else
{
string[] files = Directory.GetFiles(path);
for (int i = 0; i < files.Length; i++)
{
File.Delete(files[i]);
}
Directory.Delete(path);
Directory.CreateDirectory(path);
}
}
/// <summary>
/// Copy all files from srcPath to destPath directory
/// </summary>
public static void CopyFiles(string srcPath, string destPath, string[] extFilter)
{
if (!Directory.Exists(srcPath))
{
return;
}
if (!Directory.Exists(destPath))
{
Directory.CreateDirectory(destPath);
}
string[] hi = Directory.GetFiles(srcPath);
for (int i = 0; i < hi.Length; i++)
{
string ext = Path.GetExtension(hi[i]);
bool validExt = false;
for (int j = 0; j < extFilter.Length; j++)
{
if (ext == extFilter[j])
{
validExt = true;
}
}
if (validExt)
{
File.Copy(hi[i], destPath + Path.GetFileName(hi[i]));
}
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f60b332d6af09a04e9fc7bf700b3df3d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,371 @@
/*=========================================================================
Library: iMSTK-Unity
Copyright (c) Kitware, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
using ImstkUnity;
using UnityEngine;
using UnityEditor;
namespace ImstkEditor
{
/// <summary>
/// This class adds menu items for various parts of Unity
/// </summary>
/// It can also do other things
public class GameObjectMenuItems : Editor
{
[MenuItem("GameObject/iMSTK/SimulationManager")]
[MenuItem("CONTEXT/iMSTK/SimulationManager")]
[MenuItem("iMSTK/GameObject/SimulationManager")]
private static void CreateSimulationManagerGameObject()
{
GameObject newObj = new GameObject("SimulationManager");
newObj.AddComponent(typeof(SimulationManager));
}
/// <summary>
/// Creates a GameObject with a Deformable and Tet cube
/// </summary>
[MenuItem("GameObject/iMSTK/Deformables/Cube")]
[MenuItem("CONTEXT/iMSTK/Deformables/Cube")]
[MenuItem("iMSTK/GameObject/Deformables/Cube")]
private static void CreateDeformableVolume()
{
GameObject newObj = GameObject.CreatePrimitive(PrimitiveType.Cube);
newObj.name = "Cube";
DestroyImmediate(newObj.GetComponent<Collider>());
Deformable model = newObj.AddComponent<Deformable>();
model.useDistanceConstraint = false;
model.useAreaConstraint = false;
model.useDihedralConstraint = false;
model.useVolumeConstraint = false;
model.useFEMConstraint = true;
model.viscousDampingCoeff = 0.01;
ImstkMesh tetCubeMesh = Utility.GetTetCubeMesh();
Imstk.TetrahedralMesh imstkTetMesh = tetCubeMesh.ToImstkGeometry() as Imstk.TetrahedralMesh;
ImstkMesh surfMesh = imstkTetMesh.extractSurfaceMesh().ToImstkMesh();
surfMesh.name = tetCubeMesh.name + "_surface";
MeshFilter meshFilter = newObj.GetComponent<MeshFilter>();
meshFilter.sharedMesh = surfMesh.ToMesh();
GeometryFilter visualGeom = newObj.AddComponent<GeometryFilter>();
visualGeom.SetGeometry(meshFilter.sharedMesh);
visualGeom.showHandles = false;
GeometryFilter physicsGeom = newObj.AddComponent<GeometryFilter>();
physicsGeom.SetGeometry(tetCubeMesh);
physicsGeom.showHandles = false;
model.visualGeomFilter = visualGeom;
model.physicsGeomFilter = physicsGeom;
model.collisionGeomFilter = visualGeom;
DeformableMap map = newObj.AddComponent<DeformableMap>();
map.parentGeom = physicsGeom;
map.childGeom = visualGeom;
}
/// <summary>
/// Creates a GameObject with a Deformable and a Plane
/// </summary>
[MenuItem("GameObject/iMSTK/Deformables/Cloth")]
[MenuItem("CONTEXT/iMSTK/Deformables/Cloth")]
[MenuItem("iMSTK/GameObject/Deformables/Cloth")]
private static void CreatePbdCloth()
{
GameObject newObj = GameObject.CreatePrimitive(PrimitiveType.Plane);
newObj.name = "Cloth";
DestroyImmediate(newObj.GetComponent<Collider>());
Deformable model = newObj.AddComponent<Deformable>();
model.useDistanceConstraint = true;
model.useDihedralConstraint = true;
model.useAreaConstraint = false;
model.useVolumeConstraint = false;
model.useFEMConstraint = false;
model.distanceStiffness = 100.0;
model.dihedralStiffness = 10.0;
model.viscousDampingCoeff = 0.01;
model.uniformMassValue = 0.05;
ImstkMesh mesh = Utility.GetXYPlane(19, 19);
MeshFilter meshFilter = newObj.GetComponent<MeshFilter>();
meshFilter.sharedMesh = mesh.ToMesh();
GeometryFilter visualGeom = newObj.AddComponent<GeometryFilter>();
visualGeom.SetGeometry(meshFilter.sharedMesh);
visualGeom.showHandles = false;
model.visualGeomFilter = visualGeom;
model.physicsGeomFilter = visualGeom;
model.collisionGeomFilter = visualGeom;
}
/// <summary>
/// Creates a GameObject with a Deformable and tetrahedral grid
/// </summary>
[MenuItem("GameObject/iMSTK/Deformables/Subdivided Cube")]
[MenuItem("CONTEXT/iMSTK/Deformables/Subdivided Cube")]
[MenuItem("iMSTK/GameObject/Deformables/Subdivided Cube")]
private static void CreatePbdGridVolume()
{
GameObject newObj = GameObject.CreatePrimitive(PrimitiveType.Cube);
newObj.name = "Cube";
DestroyImmediate(newObj.GetComponent<Collider>());
// Add PbdModel to the object
Deformable model = newObj.AddComponent<Deformable>();
model.useDistanceConstraint = false;
model.useAreaConstraint = false;
model.useDihedralConstraint = false;
model.useVolumeConstraint = false;
model.useFEMConstraint = true;
model.viscousDampingCoeff = 0.01;
model.youngsModulus = 5000.0;
model.possionsRatio = 0.4;
model.materialType = Imstk.PbdFemConstraint.MaterialType.StVK;
// Create a new mesh, store the old one
MeshFilter meshFilter = newObj.GetComponentOrCreate<MeshFilter>();
Mesh inputMesh = meshFilter.sharedMesh;
meshFilter.sharedMesh = new Mesh();
meshFilter.sharedMesh.name = inputMesh.name;
// Create a new tet geometry
GeometryFilter physicsGeom = newObj.AddComponent<GeometryFilter>();
ImstkMesh tetMesh = ScriptableObject.CreateInstance<ImstkMesh>();
tetMesh.geomType = GeometryType.TetrahedralMesh;
physicsGeom.SetGeometry(tetMesh);
physicsGeom.showHandles = false;
GeometryFilter visualGeom = newObj.AddComponent<GeometryFilter>();
visualGeom.SetGeometry(meshFilter.sharedMesh);
visualGeom.showHandles = false;
model.visualGeomFilter = visualGeom;
model.physicsGeomFilter = physicsGeom;
model.collisionGeomFilter = visualGeom;
DeformableMap map = newObj.AddComponent<DeformableMap>();
map.parentGeom = physicsGeom;
map.childGeom = visualGeom;
// Use editor to add fill geometries
TetrahedralGridEditor.Init(meshFilter.sharedMesh, physicsGeom.inputImstkGeom as ImstkMesh);
}
/// <summary>
/// Creates a GameObject with a Deformable and line mesh
/// </summary>
[MenuItem("GameObject/iMSTK/Deformables/Thread")]
[MenuItem("CONTEXT/iMSTK/Deformables/Thread")]
[MenuItem("iMSTK/GameObject/Deformables/Thread")]
private static void CreatePbdThread()
{
GameObject newObj = GameObject.CreatePrimitive(PrimitiveType.Cube);
newObj.name = "PbdThread";
DestroyImmediate(newObj.GetComponent<Collider>());
// Add PbdModel to the object
Deformable model = newObj.AddComponent<Deformable>();
model.useDistanceConstraint = true;
model.useBendConstraint = true;
model.useAreaConstraint = false;
model.useDihedralConstraint = false;
model.useVolumeConstraint = false;
model.useFEMConstraint = false;
model.viscousDampingCoeff = 0.01;
model.distanceStiffness = 100.0;
model.bendStiffness = 100.0;
model.maxBendStride = 3;
// Create a new mesh, store the old one
MeshFilter meshFilter = newObj.GetComponentOrCreate<MeshFilter>();
Mesh inputMesh = meshFilter.sharedMesh;
inputMesh.name = "LineMesh";
meshFilter.sharedMesh = new Mesh();
meshFilter.sharedMesh.name = inputMesh.name;
GeometryFilter visualGeom = newObj.AddComponent<GeometryFilter>();
visualGeom.SetGeometry(meshFilter.sharedMesh);
visualGeom.showHandles = false;
model.visualGeomFilter = visualGeom;
model.physicsGeomFilter = visualGeom;
model.collisionGeomFilter = visualGeom;
// Use editor to add fill geometries
LineMeshEditor.Init(meshFilter.sharedMesh);
}
/// <summary>
/// Creates a GameObject with a RbdModel and sphere
/// </summary>
[MenuItem("GameObject/iMSTK/Rigids/Sphere")]
[MenuItem("CONTEXT/iMSTK/Rigids/Sphere")]
[MenuItem("iMSTK/GameObject/Rigids/Sphere")]
private static void CreateRigidSphere()
{
GameObject newObj = GameObject.CreatePrimitive(PrimitiveType.Sphere);
newObj.name = "Rigid Sphere";
DestroyImmediate(newObj.GetComponent<Collider>());
// Add PbdModel to the object
Rigid model = newObj.AddComponent<Rigid>();
model.mass = 1.0;
model.inertia = new Vector3[]
{
new Vector3(1.0f, 0.0f, 0.0f),
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, 0.0f, 1.0f)
};
// Create a new mesh, store the old one
MeshFilter meshFilter = newObj.GetComponentOrCreate<MeshFilter>();
GeometryFilter visualGeom = newObj.AddComponent<GeometryFilter>();
visualGeom.SetGeometry(meshFilter.sharedMesh);
visualGeom.showHandles = false;
Sphere sphere = CreateInstance<Sphere>();
sphere.radius = 0.5f;
sphere.center = Vector3.zero;
GeometryFilter collisionGeom = newObj.AddComponent<GeometryFilter>();
collisionGeom.SetGeometry(sphere);
model.visualGeomFilter = visualGeom;
model.physicsGeomFilter = collisionGeom;
model.collisionGeomFilter = collisionGeom;
}
/// <summary>
/// Creates a GameObject with an OpenHapticsDevice
/// </summary>
[MenuItem("GameObject/iMSTK/Devices/OpenHapticsDevice")]
[MenuItem("CONTEXT/iMSTK/Devices/OpenHapticsDevice")]
[MenuItem("iMSTK/GameObject/Devices/OpenHapticsDevice")]
private static void CreateOpenHapticsDevice()
{
GameObject newObj = new GameObject("OpenHapticsDevice");
newObj.AddComponent(typeof(OpenHapticsDevice));
}
[MenuItem("GameObject/iMSTK/Static Objects/Line")]
[MenuItem("CONTEXT/iMSTK/Static Objects/Line")]
[MenuItem("iMSTK/GameObject/Static Objects/Line")]
private static void CreateLineStaticObject()
{
GameObject newObj = GameObject.CreatePrimitive(PrimitiveType.Sphere);
newObj.name = "StaticLineObject";
DestroyImmediate(newObj.GetComponent<Collider>());
StaticModel model = newObj.AddComponent<StaticModel>();
ImstkMesh mesh = ScriptableObject.CreateInstance<ImstkMesh>();
mesh.geomType = GeometryType.LineMesh;
mesh.vertices = new Vector3[] { new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f) };
mesh.indices = new int[] { 0, 1 };
MeshFilter meshFilter = newObj.GetComponent<MeshFilter>();
meshFilter.sharedMesh = mesh.ToMesh();
meshFilter.sharedMesh.name = "LineMesh";
GeometryFilter collisionGeom = newObj.AddComponent<GeometryFilter>();
collisionGeom.SetGeometry(meshFilter.sharedMesh);
model.collisionGeomFilter = collisionGeom;
}
[MenuItem("GameObject/iMSTK/Static Objects/Sphere")]
[MenuItem("CONTEXT/iMSTK/Static Objects/Sphere")]
[MenuItem("iMSTK/GameObject/Static Objects/Sphere")]
private static void CreateSphereStaticObject()
{
GameObject newObj = GameObject.CreatePrimitive(PrimitiveType.Sphere);
newObj.name = "Static Sphere";
DestroyImmediate(newObj.GetComponent<Collider>());
StaticModel model = newObj.AddComponent<StaticModel>();
Sphere sphere = new Sphere();
GeometryFilter collisionGeom = newObj.AddComponent<GeometryFilter>();
collisionGeom.SetGeometry(sphere);
model.collisionGeomFilter = collisionGeom;
}
[MenuItem("GameObject/iMSTK/Static Objects/Capsule")]
[MenuItem("CONTEXT/iMSTK/Static Objects/Capsule")]
[MenuItem("iMSTK/GameObject/Static Objects/Capsule")]
private static void CreateCapsuleStaticObject()
{
GameObject newObj = GameObject.CreatePrimitive(PrimitiveType.Capsule);
newObj.name = "Static Capsule";
DestroyImmediate(newObj.GetComponent<Collider>());
StaticModel model = newObj.AddComponent<StaticModel>();
Capsule capsule = new Capsule();
GeometryFilter collisionGeom = newObj.AddComponent<GeometryFilter>();
collisionGeom.SetGeometry(capsule);
model.collisionGeomFilter = collisionGeom;
}
[MenuItem("GameObject/iMSTK/Static Objects/Oriented Box")]
[MenuItem("CONTEXT/iMSTK/Static Objects/Oriented Box")]
[MenuItem("iMSTK/GameObject/Static Objects/Oriented Box")]
private static void CreateOrientedBoxStaticObject()
{
GameObject newObj = GameObject.CreatePrimitive(PrimitiveType.Cube);
newObj.name = "StaticOrientedBoxObject";
DestroyImmediate(newObj.GetComponent<Collider>());
StaticModel model = newObj.AddComponent<StaticModel>();
OrientedBox obb = new OrientedBox();
GeometryFilter collisionGeom = newObj.AddComponent<GeometryFilter>();
collisionGeom.SetGeometry(obb);
model.collisionGeomFilter = collisionGeom;
}
[MenuItem("GameObject/iMSTK/Static Objects/Plane")]
[MenuItem("CONTEXT/iMSTK/Static Objects/Plane")]
[MenuItem("iMSTK/GameObject/Static Objects/Plane")]
private static void CreatePlaneStaticObject()
{
GameObject newObj = GameObject.CreatePrimitive(PrimitiveType.Plane);
newObj.name = "StaticPlaneObject";
DestroyImmediate(newObj.GetComponent<Collider>());
StaticModel model = newObj.AddComponent<StaticModel>();
ImstkUnity.Plane plane = new ImstkUnity.Plane();
plane.visualWidth = 5.1f;
GeometryFilter collisionGeom = newObj.AddComponent<GeometryFilter>();
collisionGeom.SetGeometry(plane);
model.collisionGeomFilter = collisionGeom;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bafd05c20034eca4081b3d878dd89662
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,115 @@
/*=========================================================================
Library: iMSTK-Unity
Copyright (c) Kitware, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
using UnityEngine;
using UnityEditor;
namespace ImstkUnity
{
/// <summary>
/// Editor for the asset, most commonly shown when selecting the asset in
/// the project explorer
/// </summary>
[CustomEditor(typeof(Geometry), true)]
class GeometryEditor : Editor
{
private PreviewRenderUtility m_PreviewUtility = null;
private Material previewMaterial = null;
private Mesh previewMesh = null;
public override void OnInspectorGUI()
{
// Check the config file toggle for change
Geometry asset = target as Geometry;
if (asset.IsMesh)
{
ImstkMesh mesh = asset as ImstkMesh;
GUILayout.Label("Vertex Count: " + mesh.vertices.Length);
GUILayout.Label("Index Count: " + mesh.indices.Length);
GUILayout.Label("Cell Count: " + mesh.indices.Length / ImstkMesh.typeToNumPts[mesh.geomType]);
}
GUILayout.Label("Geom Type: " + asset.geomType.ToString());
}
public override bool HasPreviewGUI() { return true; }
public override GUIContent GetPreviewTitle() { return new GUIContent(target.name); }
public override void OnPreviewGUI(Rect r, GUIStyle background)
{
Geometry asset = target as Geometry;
// Preview only works with meshes
if (!asset.IsMesh)
return;
ImstkMesh imstkMesh = asset as ImstkMesh;
if (m_PreviewUtility == null)
{
m_PreviewUtility = new PreviewRenderUtility();
previewMaterial = new Material(Shader.Find("Diffuse"));
// If a tet or hex mesh extract surface for display (we could use some other method to better indicate
// that this is a tet mesh)
if (asset.IsVolume)
{
// Extract the surface mesh for display
Imstk.TetrahedralMesh tetMesh = Imstk.Utils.CastTo<Imstk.TetrahedralMesh>(imstkMesh.ToPointSet());
Imstk.SurfaceMesh surfMesh = tetMesh.extractSurfaceMesh();
previewMesh = surfMesh.ToMesh();
}
}
if (Event.current.type != EventType.Repaint)
{
return;
}
Camera camera = m_PreviewUtility.camera;
float size = previewMesh.bounds.size.magnitude;
Vector3 center = previewMesh.bounds.center;
camera.transform.position = center + new Vector3(0.0f, size * 2.0f, -size * 2.0f);
camera.transform.LookAt(center);
camera.farClipPlane = 300.0f;
m_PreviewUtility.BeginPreview(r, background);
m_PreviewUtility.DrawMesh(previewMesh, Matrix4x4.identity, previewMaterial, 0);
bool fog = RenderSettings.fog;
Unsupported.SetRenderSettingsUseFogNoDirty(false);
m_PreviewUtility.camera.Render();
Unsupported.SetRenderSettingsUseFogNoDirty(fog);
Texture texture = m_PreviewUtility.EndPreview();
GUI.DrawTexture(r, texture, ScaleMode.StretchToFill, false);
}
void OnDisable()
{
previewMaterial = null;
previewMesh = null;
if (m_PreviewUtility != null)
{
m_PreviewUtility.Cleanup();
m_PreviewUtility = null;
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 73289ab03e7c85b418a57465a634e813
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fe4d6df5f481eb2478ab3cf67d3ac5f8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,98 @@
/*=========================================================================
Library: iMSTK-Unity
Copyright (c) Kitware, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
using ImstkUnity;
using UnityEngine;
using UnityEditor;
namespace ImstkEditor
{
/// <summary>
/// Laplacian smoothens an input unity Mesh providing
/// an output one
/// </summary>
public class LaplaceSmoothEditor : EditorWindow
{
public int numIterations = 20;
public double relaxationFactor = 0.01;
public double convergence = 0.0;
public double featureAngle = 45.0;
public double edgeAngle = 15.0;
public bool featureEdgeSmoothing = false;
public bool boundarySmoothing = true;
public Mesh inputMesh = null;
public Mesh outputMesh = null;
public static void Init(Mesh inputMesh, Mesh outputMesh)
{
LaplaceSmoothEditor window = GetWindow(typeof(LaplaceSmoothEditor)) as LaplaceSmoothEditor;
window.inputMesh = inputMesh;
window.outputMesh = outputMesh;
window.UpdateEditorResults();
window.Show();
}
void OnGUI()
{
EditorGUI.BeginChangeCheck();
inputMesh = EditorGUILayout.ObjectField("Input Mesh: ", inputMesh, typeof(Mesh), true) as Mesh;
int tNumIterations = EditorGUILayout.IntField("Number Of Smoothing Iterations: ", numIterations);
double tRelaxationFactor = EditorGUILayout.DoubleField("Relaxation Factor: ", relaxationFactor);
double tConvergence = EditorGUILayout.DoubleField("Convergence: ", convergence);
double tFeatureAngle = EditorGUILayout.DoubleField("Feature Angle: ", featureAngle);
double tEdgeAngle = EditorGUILayout.DoubleField("Edge Angle: ", edgeAngle);
bool tFeatureEdgeSmoothing = EditorGUILayout.Toggle("Use Feature Edge Smoothing: ", featureEdgeSmoothing);
bool tBoundarySmoothing = EditorGUILayout.Toggle("Use Boundary Smoothing: ", boundarySmoothing);
if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(this, "Change of Parameters");
numIterations = MathUtil.Max(tNumIterations, 1);
relaxationFactor = MathUtil.Max(tRelaxationFactor, 0.0);
convergence = MathUtil.Max(tConvergence, 0.0);
featureAngle = MathUtil.Max(tFeatureAngle, 0.0);
edgeAngle = MathUtil.Max(tEdgeAngle, 0.0);
featureEdgeSmoothing = tFeatureEdgeSmoothing;
boundarySmoothing = tBoundarySmoothing;
UpdateEditorResults();
}
}
private void UpdateEditorResults()
{
Imstk.SurfaceMesh surfMesh = inputMesh.ToImstkGeometry() as Imstk.SurfaceMesh;
Imstk.SurfaceMeshSmoothen smoothen = new Imstk.SurfaceMeshSmoothen();
smoothen.setInputMesh(surfMesh);
smoothen.setNumberOfIterations(numIterations);
smoothen.setRelaxationFactor(relaxationFactor);
smoothen.setConvergence(convergence);
smoothen.setFeatureAngle(featureAngle);
smoothen.setEdgeAngle(edgeAngle);
smoothen.setFeatureEdgeSmoothing(featureEdgeSmoothing);
smoothen.setBoundarySmoothing(boundarySmoothing);
smoothen.update();
Imstk.SurfaceMesh outputSurfMesh = Imstk.Utils.CastTo<Imstk.SurfaceMesh>(smoothen.getOutput());
GeomUtil.CopyMesh(outputSurfMesh.ToMesh(), outputMesh);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5ea044bfac569c644b427c75bffa1bd8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,102 @@
/*=========================================================================
Library: iMSTK-Unity
Copyright (c) Kitware, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
using ImstkUnity;
using UnityEngine;
using UnityEditor;
namespace ImstkEditor
{
/// <summary>
/// Generates a plane mesh for MeshFilter
/// </summary>
public class LineMeshEditor : EditorWindow
{
public Vector3 start = Vector3.zero;
public Vector3 direction = new Vector3(1.0f, 0.0f, 0.0f);
public int divisions = 10;
public double length = 1.0;
public Mesh outputMesh = null;
public static void Init(Mesh outputMesh)
{
LineMeshEditor window = GetWindow(typeof(LineMeshEditor)) as LineMeshEditor;
window.outputMesh = outputMesh;
window.UpdateEditorResults();
window.Show();
}
void OnGUI()
{
EditorGUI.BeginChangeCheck();
outputMesh = EditorGUILayout.ObjectField("Input Mesh: ", outputMesh, typeof(Mesh), true) as Mesh;
Vector3 tStart = EditorGUILayout.Vector3Field("Start", start);
Vector3 tDirection = EditorGUILayout.Vector3Field("Direction", direction);
int tDivisions = EditorGUILayout.IntField("Divisions", divisions);
double tLength = EditorGUILayout.DoubleField("Length", length);
if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(this, "Change of Parameters");
start = tStart;
direction = tDirection;
if (direction == Vector3.zero)
{
direction = new Vector3(1.0f, 0.0f, 0.0f);
}
divisions = Mathf.Max(tDivisions, 1);
length = MathUtil.Max(tLength, 0.0);
UpdateEditorResults();
}
}
private void UpdateEditorResults()
{
int numVerts = divisions + 1;
int numCells = divisions;
Vector3[] vertices = new Vector3[numVerts];
int[] indices = new int[numCells * 2];
direction = direction.normalized;
for (int i = 0; i < numVerts; i++)
{
float t = (float)i / (numVerts - 1); // 0-1
vertices[i] = start + direction * t * (float)length;
}
for (int i = 0; i < numCells; i++)
{
indices[i * 2] = i;
indices[i * 2 + 1] = i + 1;
}
outputMesh.triangles = null;
outputMesh.normals = null;
outputMesh.tangents = null;
outputMesh.vertices = vertices;
outputMesh.SetIndices(indices, MeshTopology.Lines, 0);
outputMesh.RecalculateBounds();
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 33c64bf93157c484abdc881055be248f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,73 @@
/*=========================================================================
Library: iMSTK-Unity
Copyright (c) Kitware, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
using ImstkUnity;
using UnityEngine;
using UnityEditor;
namespace ImstkEditor
{
/// <summary>
/// Generates a plane mesh for MeshFilter
/// </summary>
public class PlaneMeshEditor : EditorWindow
{
//public Vector3 size = new Vector3(1.0f, 0.25f, 1.0f);
public Vector2Int dim = new Vector2Int(8, 8);
//public Vector3 center = new Vector3(0.0f, 0.0f, 0.0f);
public Mesh outputMesh = null;
public static void Init(Mesh outputMesh)
{
PlaneMeshEditor window = GetWindow(typeof(PlaneMeshEditor)) as PlaneMeshEditor;
window.outputMesh = outputMesh;
if (outputMesh.name.Length == 0) outputMesh.name = "plane mesh";
window.UpdateEditorResults();
window.Show();
}
void OnGUI()
{
EditorGUI.BeginChangeCheck();
outputMesh = EditorGUILayout.ObjectField("Input Mesh: ", outputMesh, typeof(Mesh), true) as Mesh;
name = EditorGUILayout.TextField("Name: ", outputMesh.name);
//Vector3 tSize = EditorGUILayout.Vector3Field("Size: ", size);
Vector2Int tDim = EditorGUILayout.Vector2IntField("Grid Dimensions: ", dim);
//Vector3 tCenter = EditorGUILayout.Vector3Field("Center: ", center);
// \todo: How to get undo to also call UpdateInputObj?
if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(this, "Change of Parameters");
//size = tSize.cwiseMax(new Vector3(0.0f, 0.0f, 0.0f));
dim = tDim.cwiseMax(new Vector2Int(2, 2));
//center = tCenter;
outputMesh.name = name;
UpdateEditorResults();
}
}
private void UpdateEditorResults()
{
ImstkMesh planeMesh = Utility.GetXYPlane(dim.x, dim.y);
GeomUtil.CopyMesh(planeMesh.ToMesh(), outputMesh);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fe3bffa442f54d04ea8dcec7b28e5535
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,86 @@
/*=========================================================================
Library: iMSTK-Unity
Copyright (c) Kitware, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
using ImstkUnity;
using UnityEngine;
using UnityEditor;
namespace ImstkEditor
{
public enum SubdivideMeshType
{
Linear,
Loop,
Butterfly
}
/// <summary>
/// Laplacian smoothens an input unity Mesh providing
/// an output one
/// </summary>
public class SubdivideMeshEditor : EditorWindow
{
public int numSubdivisions = 1;
public Imstk.SurfaceMeshSubdivide.Type subdivType = Imstk.SurfaceMeshSubdivide.Type.LINEAR;
public Mesh inputMesh = null;
public Mesh outputMesh = null;
public static void Init(Mesh inputMesh, Mesh outputMesh)
{
SubdivideMeshEditor window = GetWindow(typeof(SubdivideMeshEditor)) as SubdivideMeshEditor;
window.inputMesh = inputMesh;
window.outputMesh = outputMesh;
window.UpdateEditorResults();
window.Show();
}
void OnGUI()
{
EditorGUI.BeginChangeCheck();
inputMesh = EditorGUILayout.ObjectField("Input Mesh: ", inputMesh, typeof(Mesh), true) as Mesh;
int tNumSubdivisions = EditorGUILayout.IntField("Number Of Subdivisions: ", numSubdivisions);
Imstk.SurfaceMeshSubdivide.Type tSubdivType =
(Imstk.SurfaceMeshSubdivide.Type)EditorGUILayout.EnumPopup("Subdivision Type: ", subdivType);
if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(this, "Change of Parameters");
numSubdivisions = MathUtil.Max(tNumSubdivisions, 0);
subdivType = tSubdivType;
UpdateEditorResults();
}
}
private void UpdateEditorResults()
{
Imstk.SurfaceMesh surfMesh = inputMesh.ToImstkGeometry() as Imstk.SurfaceMesh;
Imstk.SurfaceMeshSubdivide subdiv = new Imstk.SurfaceMeshSubdivide();
subdiv.setInputMesh(surfMesh);
subdiv.setNumberOfSubdivisions(numSubdivisions);
subdiv.setSubdivisionType(subdivType);
subdiv.update();
Imstk.SurfaceMesh outputSurfMesh = Imstk.Utils.CastTo<Imstk.SurfaceMesh>(subdiv.getOutput());
GeomUtil.CopyMesh(outputSurfMesh.ToMesh(), outputMesh);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3b8962d5e32621842895493399fea036
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,80 @@
/*=========================================================================
Library: iMSTK-Unity
Copyright (c) Kitware, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
using ImstkUnity;
using UnityEngine;
using UnityEditor;
namespace ImstkEditor
{
/// <summary>
/// Generates a tetrahedral mesh PhysicsGeometry
/// </summary>
public class TetrahedralGridEditor : EditorWindow
{
public Vector3 size = new Vector3(1.0f, 0.25f, 1.0f);
public Vector3Int dim = new Vector3Int(8, 4, 8);
public Vector3 center = new Vector3(0.0f, 0.0f, 0.0f);
public Mesh outputSurfMesh = null;
public ImstkMesh outputTetMesh = null;
public static void Init(
Mesh outputSurfMesh,
ImstkMesh outputTetMesh)
{
TetrahedralGridEditor window = GetWindow(typeof(TetrahedralGridEditor)) as TetrahedralGridEditor;
window.outputSurfMesh = outputSurfMesh;
window.outputTetMesh = outputTetMesh;
window.UpdateEditorResults();
window.Show();
}
void OnGUI()
{
EditorGUI.BeginChangeCheck();
outputSurfMesh = EditorGUILayout.ObjectField("Input Surface MeshFilter: ", outputSurfMesh, typeof(Mesh), true) as Mesh;
outputTetMesh = EditorGUILayout.ObjectField("Input Tet GeometryFilter: ", outputTetMesh, typeof(ImstkMesh), true) as ImstkMesh;
Vector3 tSize = EditorGUILayout.Vector3Field("Size: ", size);
Vector3Int tDim = EditorGUILayout.Vector3IntField("Grid Dimensions: ", dim);
Vector3 tCenter = EditorGUILayout.Vector3Field("Center: ", center);
// \todo: How to get undo to also call UpdateInputObj?
if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(this, "Change of Parameters");
size = tSize.cwiseMax(new Vector3(0.0f, 0.0f, 0.0f));
dim = tDim.cwiseMax(new Vector3Int(2, 2, 2));
center = tCenter;
UpdateEditorResults();
}
}
private void UpdateEditorResults()
{
ImstkMesh tetMesh = Utility.GetTetGridMesh(size, dim, center);
GeomUtil.CopyMesh(tetMesh, outputTetMesh);
Imstk.TetrahedralMesh imstkTetMesh = Imstk.Utils.CastTo<Imstk.TetrahedralMesh>(tetMesh.ToImstkGeometry());
Imstk.SurfaceMesh surfMesh = imstkTetMesh.extractSurfaceMesh();
GeomUtil.CopyMesh(surfMesh.ToMesh(), outputSurfMesh);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8f18b03d2fbaf8448913420009e4e51e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,132 @@
/*=========================================================================
Library: iMSTK-Unity
Copyright (c) Kitware, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
using ImstkUnity;
using UnityEngine;
using UnityEditor;
namespace ImstkEditor
{
public enum UVPlaneOptions
{
XY,
YZ,
XZ,
Custom
}
/// <summary>
/// Generates UV plane coords
/// </summary>
public class UVPlaneProjectEditor : EditorWindow
{
public Vector3 planeNormal = new Vector3(0.0f, 1.0f, 0.0f);
public UVPlaneOptions planeOption = UVPlaneOptions.XZ;
public Vector2 uvScale = new Vector2(1.0f, 1.0f);
public Vector2 uvShift = Vector2.zero;
public Mesh inputMesh = null;
public Mesh outputMesh = null;
public static void Init(Mesh inputMesh, Mesh outputMesh)
{
UVPlaneProjectEditor window = GetWindow(typeof(UVPlaneProjectEditor)) as UVPlaneProjectEditor;
window.inputMesh = inputMesh;
window.outputMesh = outputMesh;
window.UpdateEditorResults();
window.Show();
}
void OnGUI()
{
EditorGUI.BeginChangeCheck();
inputMesh = EditorGUILayout.ObjectField("Input Mesh: ", inputMesh, typeof(Mesh), true) as Mesh;
Vector3 tPlaneNormal = EditorGUILayout.Vector3Field("Plane Normal: ", planeNormal);
UVPlaneOptions tPlaneOption = (UVPlaneOptions)EditorGUILayout.EnumPopup("Plane: ", planeOption);
Vector2 tUvScale = EditorGUILayout.Vector2Field("UV Scale", uvScale);
Vector2 tUvShift = EditorGUILayout.Vector2Field("UV Shift", uvShift);
// \todo: How to get undo to also call UpdateInputObj?
if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(this, "Change of Parameters");
// IF the plane normal was changed
if (tPlaneNormal != planeNormal)
{
if (tPlaneNormal == new Vector3(0.0f, 1.0f, 0.0f))
{
tPlaneOption = UVPlaneOptions.XZ;
}
else if (tPlaneNormal == new Vector3(1.0f, 0.0f, 0.0f))
{
tPlaneOption = UVPlaneOptions.YZ;
}
else if (tPlaneNormal == new Vector3(0.0f, 0.0f, 1.0f))
{
tPlaneOption = UVPlaneOptions.XY;
}
else
{
tPlaneOption = UVPlaneOptions.Custom;
}
}
if (tPlaneOption != planeOption)
{
if (tPlaneOption == UVPlaneOptions.XY)
{
tPlaneNormal = new Vector3(0.0f, 0.0f, 1.0f);
}
else if (tPlaneOption == UVPlaneOptions.XZ)
{
tPlaneNormal = new Vector3(0.0f, 1.0f, 0.0f);
}
else if (tPlaneOption == UVPlaneOptions.YZ)
{
tPlaneNormal = new Vector3(1.0f, 0.0f, 0.0f);
}
}
planeNormal = tPlaneNormal;
planeOption = tPlaneOption;
uvScale = tUvScale;
uvShift = tUvShift;
UpdateEditorResults();
}
}
private void UpdateEditorResults()
{
GeomUtil.CopyMesh(inputMesh, outputMesh);
Bounds bounds = outputMesh.bounds;
Vector3 size = bounds.size;
Vector3[] vertices = outputMesh.vertices;
Vector2[] uvs = new Vector2[vertices.Length];
for (int i = 0; i < vertices.Length; i++)
{
uvs[i] = new Vector2(vertices[i].x / size.x, vertices[i].z / size.z) * uvScale + uvShift;
}
outputMesh.SetUVs(0, uvs);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9deef960c4623f0438f908d9a5841cfa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,88 @@
/*=========================================================================
Library: iMSTK-Unity
Copyright (c) Kitware, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
using ImstkUnity;
using UnityEngine;
using UnityEditor;
namespace ImstkEditor
{
/// <summary>
/// Generates UV sphere tcoords via imgui
/// </summary>
public class UVSphereProjectEditor : EditorWindow
{
public float radius = 1.0f;
public float uvScale = 2.0f;
public Vector3 center = new Vector3(0.0f, 0.0f, 0.0f);
public Mesh inputMesh = null;
public Mesh outputMesh = null;
public static void Init(Mesh inputMesh, Mesh outputMesh)
{
UVSphereProjectEditor window = GetWindow(typeof(UVSphereProjectEditor)) as UVSphereProjectEditor;
window.inputMesh = inputMesh;
window.outputMesh = outputMesh;
// Initialize to the bounds of the input mesh
window.center = inputMesh.bounds.center;
window.radius = inputMesh.bounds.size.magnitude * 0.5f;
window.UpdateEditorResults();
window.Show();
}
void OnGUI()
{
EditorGUI.BeginChangeCheck();
inputMesh = EditorGUILayout.ObjectField("Input Mesh: ", inputMesh, typeof(Mesh), true) as Mesh;
Vector3 tCenter = EditorGUILayout.Vector3Field("Center: ", center);
float tRadius = EditorGUILayout.FloatField("Radius: ", radius);
float tUvScale = EditorGUILayout.FloatField("UV Scale: ", uvScale);
// \todo: How to get undo to also call UpdateInputObj?
if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(this, "Change of Parameters");
radius = Mathf.Max(tRadius, 0.0f);
uvScale = tUvScale;
center = tCenter;
UpdateEditorResults();
}
}
private void UpdateEditorResults()
{
GeomUtil.CopyMesh(inputMesh, outputMesh);
Vector3[] vertices = outputMesh.vertices;
Vector2[] uvs = new Vector2[vertices.Length];
for (int i = 0; i < vertices.Length; i++)
{
Vector3 diff = vertices[i] - center;
// Compute phi and theta on the sphere
float theta = Mathf.Asin(diff.x / radius);
float phi = Mathf.Atan2(diff.y, diff.z);
uvs[i] = new Vector2(phi / (Mathf.PI * 2.0f) + 0.5f, theta / (Mathf.PI * 2.0f) + 0.5f) * uvScale;
}
outputMesh.SetUVs(0, uvs);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 29dbcb8127ce46e40a5aedbf66f68d77
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,317 @@
/*=========================================================================
Library: iMSTK-Unity
Copyright (c) Kitware, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
using ImstkUnity;
using System;
using UnityEditor;
using UnityEngine;
namespace ImstkEditor
{
/// <summary>
/// Used to display geometry components in the editor view and inspector
/// </summary>
[CustomEditor(typeof(GeometryFilter), true)]
[InitializeOnLoad]
class GeometryFilterEditor : Editor
{
public override void OnInspectorGUI()
{
OnGeomGUI();
OnPrimitiveGeomGUI();
}
protected void OnGeomGUI()
{
GeometryFilter geomFilter = target as GeometryFilter;
EditorGUI.BeginChangeCheck();
bool showHandles = EditorGUILayout.Toggle("Show Handles", geomFilter.showHandles);
GeometryType newType = (GeometryType)EditorGUILayout.EnumPopup("Geom Type", geomFilter.type);
UnityEngine.Object abstractMesh = null;
// If unity mesh, let user slot an asset
if (newType == GeometryType.UnityMesh)
{
// Accepts either a Mesh or MeshFilter. If MeshFilter, then pulls the mesh out and uses that
// This is because users
UnityEngine.Object obj = EditorGUILayout.ObjectField("Mesh", geomFilter.inputUnityGeom, typeof(UnityEngine.Object), true);
if (obj as MeshFilter != null)
{
abstractMesh = (obj as MeshFilter).sharedMesh;
}
else if (obj as Mesh != null)
{
abstractMesh = obj as Mesh;
}
else
{
if (abstractMesh != null)
{
Debug.LogWarning("Tried to set object of type " + abstractMesh.GetType().Name + " on GeometryFilter");
}
}
}
// If an imstk mesh, let user slot an asset for it
else if (newType == GeometryType.SurfaceMesh ||
newType == GeometryType.LineMesh ||
newType == GeometryType.TetrahedralMesh ||
newType == GeometryType.HexahedralMesh ||
newType == GeometryType.PointSet)
{
abstractMesh = EditorGUILayout.ObjectField("iMSTKMesh", geomFilter.inputImstkGeom, typeof(Geometry), true);
}
if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(geomFilter, "Change of GeomFilter");
geomFilter.showHandles = showHandles;
// If the type changed unslot the geometry from the component
if (newType != geomFilter.type)
{
geomFilter.inputImstkGeom = null;
geomFilter.inputUnityGeom = null;
geomFilter.type = newType;
abstractMesh = null;
}
// If the mesh changed, call the appropriate setter for it
if (abstractMesh != null)
{
if ((abstractMesh as Mesh) != null)
geomFilter.SetGeometry(abstractMesh as Mesh);
else if ((abstractMesh as Geometry) != null)
geomFilter.SetGeometry(abstractMesh as Geometry);
}
SceneView.RepaintAll();
}
if (geomFilter.type == GeometryType.SurfaceMesh ||
geomFilter.type == GeometryType.UnityMesh)
{
if (GUILayout.Button("Write Mesh"))
{
WriteMesh(geomFilter, ".ply");
}
}
}
protected void OnPrimitiveGeomGUI()
{
GeometryFilter geomFilter = target as GeometryFilter;
if (geomFilter.type == GeometryType.Capsule)
{
if (geomFilter.inputImstkGeom == null)
{
geomFilter.SetGeometry(CreateInstance<Capsule>());
}
Capsule source = geomFilter.inputImstkGeom as Capsule;
Capsule target = CreateInstance<Capsule>();
EditorGUI.BeginChangeCheck();
target.center = EditorGUILayout.Vector3Field("Center", source.center);
target.radius = Mathf.Max(EditorGUILayout.FloatField("Radius", source.radius), float.Epsilon);
target.length = Mathf.Max(EditorGUILayout.FloatField("Length", source.length), float.Epsilon);
target.orientation = EditorGUILayout.Vector4Field("Orientation", source.orientation.ToVector4()).ToQuat();
if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(geomFilter, "Change of GeomFilter Geom");
geomFilter.inputImstkGeom = target;
SceneView.RepaintAll();
}
}
else if (geomFilter.type == GeometryType.Cylinder)
{
if (geomFilter.inputImstkGeom == null)
{
geomFilter.SetGeometry(CreateInstance<Cylinder>());
}
Cylinder source = geomFilter.inputImstkGeom as Cylinder;
Cylinder target = CreateInstance<Cylinder>();
EditorGUI.BeginChangeCheck();
target.center = EditorGUILayout.Vector3Field("Center", source.center);
target.radius = Mathf.Max(EditorGUILayout.FloatField("Radius", source.radius), float.Epsilon);
target.length = Mathf.Max(EditorGUILayout.FloatField("Length", source.length), float.Epsilon);
target.orientation = EditorGUILayout.Vector4Field("Orientation", source.orientation.ToVector4()).ToQuat();
if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(geomFilter, "Change of GeomFilter Geom");
geomFilter.inputImstkGeom = target;
SceneView.RepaintAll();
}
}
else if (geomFilter.type == GeometryType.OrientedBox)
{
if (geomFilter.inputImstkGeom == null)
{
geomFilter.SetGeometry(CreateInstance<OrientedBox>());
}
OrientedBox source = geomFilter.inputImstkGeom as OrientedBox;
OrientedBox target = CreateInstance<OrientedBox>();
EditorGUI.BeginChangeCheck();
target.center = EditorGUILayout.Vector3Field("Center", source.center);
target.extents = EditorGUILayout.Vector3Field("Extents", source.extents).cwiseMax(new Vector3(float.Epsilon, float.Epsilon, float.Epsilon)); ;
target.orientation = EditorGUILayout.Vector4Field("Orientation", source.orientation.ToVector4()).ToQuat();
if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(geomFilter, "Change of GeomFilter Geom");
geomFilter.inputImstkGeom = target;
SceneView.RepaintAll();
}
}
else if (geomFilter.type == GeometryType.Plane)
{
if (geomFilter.inputImstkGeom == null)
{
geomFilter.SetGeometry(CreateInstance<ImstkUnity.Plane>());
}
ImstkUnity.Plane source = geomFilter.inputImstkGeom as ImstkUnity.Plane;
ImstkUnity.Plane target = CreateInstance<ImstkUnity.Plane>();
EditorGUI.BeginChangeCheck();
target.center = EditorGUILayout.Vector3Field("Center", source.center);
target.normal = EditorGUILayout.Vector3Field("Normal", source.normal);
target.visualWidth = Mathf.Max(EditorGUILayout.FloatField("Visual Width", source.visualWidth), float.Epsilon);
if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(geomFilter, "Change of GeomFilter Geom");
geomFilter.inputImstkGeom = target;
SceneView.RepaintAll();
}
}
else if (geomFilter.type == GeometryType.Sphere)
{
if (geomFilter.inputImstkGeom == null)
{
geomFilter.SetGeometry(CreateInstance<Sphere>());
}
Sphere source = geomFilter.inputImstkGeom as Sphere;
Sphere target = CreateInstance<Sphere>();
EditorGUI.BeginChangeCheck();
target.center = EditorGUILayout.Vector3Field("Center", source.center);
target.radius = Mathf.Max(EditorGUILayout.FloatField("Radius", source.radius), float.Epsilon);
if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(geomFilter, "Change of GeomFilter Geom");
geomFilter.inputImstkGeom = target;
SceneView.RepaintAll();
}
}
}
[DrawGizmo(GizmoType.InSelectionHierarchy | GizmoType.NotInSelectionHierarchy)]
static void DrawHandles(GeometryFilter geomFilter, GizmoType gizmoType)
{
if (!geomFilter.showHandles) return;
if (geomFilter.inputUnityGeom == null && geomFilter.inputImstkGeom == null) return;
if (geomFilter.type == GeometryType.UnityMesh)
{
Transform transform = geomFilter.gameObject.GetComponent<Transform>();
Mesh mesh = geomFilter.inputUnityGeom;
ImstkGizmos.DrawMesh(mesh, transform.position, transform.rotation, transform.lossyScale);
}
else
{
Transform transform = geomFilter.gameObject.GetComponent<Transform>();
Geometry geom = geomFilter.inputImstkGeom;
if (geom.geomType == GeometryType.Capsule)
{
Capsule capsule = geom as Capsule;
Mesh displayMesh = capsule.GetMesh();
Gizmos.DrawWireMesh(displayMesh, 0, transform.position, transform.rotation, new Vector3(1.0f, 1.0f, 1.0f));
}
else if (geom.geomType == GeometryType.Cylinder)
{
Cylinder cylinder = geom as Cylinder;
Mesh displayMesh = cylinder.GetMesh();
Gizmos.DrawWireMesh(displayMesh, 0, transform.position, transform.rotation, new Vector3(1.0f, 1.0f, 1.0f));
}
else if (geom.geomType == GeometryType.OrientedBox)
{
OrientedBox orientedBox = geom as OrientedBox;
Mesh displayMesh = orientedBox.GetMesh();
Gizmos.DrawWireMesh(displayMesh, 0, transform.position, transform.rotation, transform.localScale);
}
else if (geom.geomType == GeometryType.Plane)
{
// Unity's planes default config for drawing is normal along z. So we rotate from z to normal
ImstkUnity.Plane plane = geom as ImstkUnity.Plane;
Handles.RectangleHandleCap(0, plane.GetTransformedCenter(transform),
Quaternion.FromToRotation(Vector3.forward, plane.GetTransformedNormal(transform)), plane.visualWidth, EventType.Repaint);
}
else if (geom.geomType == GeometryType.Sphere)
{
Sphere sphere = geom as Sphere;
Mesh displayMesh = sphere.GetMesh();
Gizmos.DrawWireMesh(displayMesh, 0, transform.position, transform.rotation, transform.lossyScale);
}
else if (geom.geomType == GeometryType.PointSet ||
geom.geomType == GeometryType.LineMesh ||
geom.geomType == GeometryType.SurfaceMesh)
{
ImstkMesh mesh = geom as ImstkMesh;
ImstkGizmos.DrawMesh(mesh.ToMesh(), transform.position, transform.rotation, transform.localScale);
}
else if (geom.geomType == GeometryType.TetrahedralMesh)
{
var tetMesh = Imstk.Utils.CastTo<Imstk.TetrahedralMesh>(geomFilter.GetOutputGeometry());
Imstk.SurfaceMesh surfMesh = tetMesh.extractSurfaceMesh();
Debug.Assert(tetMesh != null);
var toWorld = transform.localToWorldMatrix;
surfMesh.transform(toWorld.ToMat4d());
surfMesh.updatePostTransformData();
// Note probably not really performant ...
Gizmos.DrawWireMesh(surfMesh.ToMesh());
}
}
}
private void WriteMesh(GeometryFilter script, string type)
{
var components = script.GetComponents<GeometryFilter>();
int i = Array.IndexOf(components, script);
script.WriteMesh(script.gameObject.name + "_" + i.ToString() + type);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: beaa834f9e135c04e8538c213b9b5db2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,137 @@
/*=========================================================================
Library: iMSTK-Unity
Copyright (c) Kitware, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
using UnityEngine;
namespace ImstkUnity
{
/// <summary>
/// This class reads in various types of geometry utilized by Imstk
/// </summary>
[UnityEditor.AssetImporters.ScriptedImporter(1, new string[] { "vtk", "vtu", "vtp", "stl", "ply", "veg", "msh", "mhd" })]
public class GeometryImporter : UnityEditor.AssetImporters.ScriptedImporter
{
/// <summary>
/// When on, reverses winding of cells (currently only works for surface meshes)
/// </summary>
public bool reverseWinding = false;
// Default is mirror along the X-Axis
public Matrix4x4 transform = Matrix4x4.Scale(new Vector3(-1, 1, 1));
[Tooltip("If true, will center the mesh around the origin")]
public bool centerMesh = false;
public override void OnImportAsset(UnityEditor.AssetImporters.AssetImportContext ctx)
{
string assetsPath = Application.dataPath;
assetsPath = assetsPath.Replace("Assets", "");
string filePath = assetsPath + ctx.assetPath;
string fileName = System.IO.Path.GetFileNameWithoutExtension(ctx.assetPath);
// Read the geometry using imstk, warning: type not correct use conversion funcs
Imstk.PointSet pointSet = Imstk.MeshIO.read(filePath);
// Create resource to load into
// Setup a default cube, remove BoxCollider, replace mesh, add Geometry (Imstk), replace Mesh (Unity)
GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Cube);
DestroyImmediate(obj.GetComponent<BoxCollider>());
obj.name = fileName;
if (centerMesh)
{
var vertices = pointSet.getVertexPositions();
var center = new Imstk.Vec3d(0, 0, 0);
for (uint i = 0; i < vertices.size(); ++i)
{
center += vertices[i];
}
center = center / vertices.size();
pointSet.translate(center*-1.0, Imstk.Geometry.TransformType.ApplyToData);
}
if (pointSet.getTypeName() == Imstk.LineMesh.getStaticTypeName())
{
Imstk.LineMesh lineMesh = Imstk.Utils.CastTo<Imstk.LineMesh>(pointSet);
lineMesh.transform(transform.ToMat4d(), Imstk.Geometry.TransformType.ApplyToData);
lineMesh.updatePostTransformData();
Mesh mesh = lineMesh.ToMesh();
foreach (var v in mesh.vertices)
{
Debug.Log(v);
}
mesh.name = fileName + "_mesh";
obj.GetComponent<MeshFilter>().sharedMesh = mesh;
ctx.AddObjectToAsset(obj.name, obj);
ctx.AddObjectToAsset(mesh.name, mesh); // Add to the load asset
}
else if (pointSet.getTypeName() == Imstk.SurfaceMesh.getStaticTypeName())
{
Imstk.SurfaceMesh surfMesh = Imstk.Utils.CastTo<Imstk.SurfaceMesh>(pointSet);
surfMesh.transform(transform.ToMat4d(), Imstk.Geometry.TransformType.ApplyToData);
surfMesh.updatePostTransformData();
if (reverseWinding)
{
surfMesh.flipNormals();
}
Mesh mesh = surfMesh.ToMesh();
mesh.name = fileName + "_mesh";
obj.GetComponent<MeshFilter>().sharedMesh = mesh;
ctx.AddObjectToAsset(obj.name, obj);
ctx.AddObjectToAsset(mesh.name, mesh); // Add to the load asset
}
else if (pointSet.getTypeName() == Imstk.TetrahedralMesh.getStaticTypeName())
{
Imstk.TetrahedralMesh tetMesh = Imstk.Utils.CastTo<Imstk.TetrahedralMesh>(pointSet);
if (tetMesh == null)
{
return;
}
tetMesh.transform(transform.ToMat4d(), Imstk.Geometry.TransformType.ApplyToData);
tetMesh.updatePostTransformData();
Imstk.SurfaceMesh surfMesh = tetMesh.extractSurfaceMesh();
if (reverseWinding)
{
surfMesh.flipNormals();
}
Geometry tetGeom = tetMesh.ToImstkMesh();
tetGeom.name = fileName + "_mesh";
Mesh mesh = surfMesh.ToMesh();
mesh.name = fileName + "_mesh_surface";
obj.GetComponent<MeshFilter>().sharedMesh = mesh;
ctx.AddObjectToAsset(obj.name, obj);
ctx.AddObjectToAsset(mesh.name, mesh); // Add to the load asset
// \todo: Add a custom thumbnail for the tetrahedral mesh
ctx.AddObjectToAsset(tetGeom.name, tetGeom);
}
ctx.SetMainObject(obj);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e43119e965e82b041aac262bc0f72039
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,183 @@
/*=========================================================================
Library: iMSTK-Unity
Copyright (c) Kitware, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
using ImstkUnity;
using UnityEngine;
using UnityEditor;
namespace ImstkEditor
{
/// <summary>
/// For menu'd geometry operations. Could spin off into own GUI as it gets larger.
/// GUI for parameters needs to be done up as well for some
/// </summary>
class GeometryMenuItems
{
/// <summary>
/// Creates UVs per vertex on plane for GameObjects MeshFilter mesh
/// </summary>
[MenuItem("iMSTK/Geometry/ProjectUVPlane")]
private static void ProjectUVPlane()
{
Vector2 scale = new Vector2(1.0f, 1.0f);
// \todo: Plane option
GameObject inputObj = Selection.activeObject as GameObject;
if (inputObj == null)
{
Debug.LogWarning("ProjectUVPlane failed, no object selected.");
return;
}
MeshFilter meshFilter = inputObj.GetComponentOrCreate<MeshFilter>();
Mesh inputMesh = meshFilter.sharedMesh;
meshFilter.sharedMesh = new Mesh();
meshFilter.sharedMesh.name = inputMesh.name;
UVPlaneProjectEditor.Init(inputMesh, meshFilter.sharedMesh);
}
/// <summary>
/// Creates UVs per vertex on sphere for GameObjects MeshFilter mesh
/// </summary>
[MenuItem("iMSTK/Geometry/ProjectUVSphere")]
private static void ProjectUVSphere()
{
GameObject inputObj = Selection.activeObject as GameObject;
if (inputObj == null)
{
Debug.LogWarning("ProjectUVSphere failed, no object selected.");
return;
}
MeshFilter meshFilter = inputObj.GetComponentOrCreate<MeshFilter>();
Mesh inputMesh = meshFilter.sharedMesh;
meshFilter.sharedMesh = new Mesh();
meshFilter.sharedMesh.name = inputMesh.name;
UVSphereProjectEditor.Init(inputMesh, meshFilter.sharedMesh);
}
/// <summary>
/// Laplacian smoothens a mesh
/// </summary>
[MenuItem("iMSTK/Geometry/LaplaceSmoothMesh")]
private static void LaplaceSmoothMesh()
{
GameObject inputObj = Selection.activeObject as GameObject;
if (inputObj == null)
{
Debug.LogWarning("LaplaceSmoothMesh failed, no object selected.");
return;
}
MeshFilter meshFilter = inputObj.GetComponentOrCreate<MeshFilter>();
Mesh inputMesh = meshFilter.sharedMesh;
meshFilter.sharedMesh = new Mesh();
meshFilter.sharedMesh.name = inputMesh.name;
LaplaceSmoothEditor.Init(inputMesh, meshFilter.sharedMesh);
}
/// <summary>
/// Subdivides a triangle mesh
/// </summary>
[MenuItem("iMSTK/Geometry/SubdivideMesh")]
private static void SubdivideMesh()
{
GameObject inputObj = Selection.activeObject as GameObject;
if (inputObj == null)
{
Debug.LogWarning("LaplaceSmoothMesh failed, no object selected.");
return;
}
MeshFilter meshFilter = inputObj.GetComponentOrCreate<MeshFilter>();
Mesh inputMesh = meshFilter.sharedMesh;
meshFilter.sharedMesh = new Mesh();
meshFilter.sharedMesh.name = inputMesh.name;
SubdivideMeshEditor.Init(inputMesh, meshFilter.sharedMesh);
}
/// <summary>
/// Generates a tet grid on the currently selected object
/// </summary>
[MenuItem("iMSTK/Geometry/Generate TetGrid")]
private static void GenerateTetGrid()
{
GameObject inputObj = Selection.activeObject as GameObject;
if (inputObj == null)
{
Debug.LogWarning("TetGrid generation failed, no object selected.");
return;
}
MeshFilter meshFilter = inputObj.GetComponentOrCreate<MeshFilter>();
Mesh inputMesh = meshFilter.sharedMesh;
meshFilter.sharedMesh = new Mesh();
meshFilter.sharedMesh.name = inputMesh.name;
GeometryFilter tetGridFilter = inputObj.AddComponent<GeometryFilter>();
ImstkMesh tetMesh = ScriptableObject.CreateInstance<ImstkMesh>();
tetMesh.geomType = GeometryType.TetrahedralMesh;
tetGridFilter.SetGeometry(tetMesh);
// Operates on the whole object as it provides the tetrahedral mesh on a separate geometry
TetrahedralGridEditor.Init(meshFilter.sharedMesh, tetGridFilter.inputImstkGeom as ImstkMesh);
}
/// <summary>
/// Generates a plane mesh on the currently selected object
/// </summary>
[MenuItem("iMSTK/Geometry/Generate Plane")]
private static void GeneratePlane()
{
GameObject inputObj = Selection.activeObject as GameObject;
if (inputObj == null)
{
Debug.LogWarning("Plane generation failed, no object selected.");
return;
}
MeshFilter meshFilter = inputObj.GetComponentOrCreate<MeshFilter>();
PlaneMeshEditor.Init(meshFilter.sharedMesh);
}
/// <summary>
/// Generates a line mesh on the currently selected object
/// </summary>
[MenuItem("iMSTK/Geometry/Generate LineMesh")]
private static void GenerateLineMesh()
{
GameObject inputObj = Selection.activeObject as GameObject;
if (inputObj == null)
{
Debug.LogError("Select an object before opening the LineMesh Editor");
return;
}
MeshFilter meshFilter = inputObj.GetComponentOrCreate<MeshFilter>();
inputObj.GetComponentOrCreate<MeshRenderer>();
if (meshFilter.sharedMesh == null)
{
meshFilter.sharedMesh = new Mesh();
meshFilter.sharedMesh.name = inputObj.name + "_mesh";
} else
{
Debug.LogWarning("This will overwrite the current mesh.");
}
LineMeshEditor.Init(meshFilter.sharedMesh);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8934b7d83f4f03246ae61fe806001275
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,129 @@
using ImstkUnity;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace ImstkEditor
{
[CustomEditor(typeof(GraspingManager))]
public class GraspingManagerEditor : Editor
{
bool _folded = true;
Rigid _rigid;
GeometryFilter _graspingGeometry;
List<GraspingManager.GraspingData> _graspingData;
List<DynamicalModel> _allDeformables = new List<DynamicalModel>();
GUIContent _warning;
double _deformableGraspingStiffness;
double _rigidGraspingStiffness;
GraspingManagerEditor()
{
EditorApplication.hierarchyChanged += OnHierarchyChanged;
}
private void OnHierarchyChanged()
{
_allDeformables = (Resources.FindObjectsOfTypeAll(typeof(DynamicalModel)) as DynamicalModel[]).ToList<DynamicalModel>();
}
public override void OnInspectorGUI()
{
if (_allDeformables.Count == 0) OnHierarchyChanged();
var script = target as GraspingManager;
EditorGUI.BeginChangeCheck();
EditorGUILayout.BeginHorizontal();
_rigid = EditorGUILayout.ObjectField("Grasping Object",
script.rigid, typeof(ImstkUnity.Rigid), true) as ImstkUnity.Rigid;
if (script.rigid == null)
{
_warning = EditorGUIUtility.IconContent("Error", "|Grasping Object Can't be null");
EditorGUILayout.LabelField(_warning, GUILayout.Width(_warning.image.width));
}
EditorGUILayout.EndHorizontal();
_graspingGeometry = EditorGUILayout.ObjectField("Grasping Geometry (Optional)",
script.graspingGeometry, typeof(GeometryFilter), true) as GeometryFilter;
GUILayout.BeginVertical(EditorStyles.helpBox);
_deformableGraspingStiffness = EditorGUILayout.DoubleField("Deformable Grasping Stiffness", script.deformableGraspingStiffness);
_rigidGraspingStiffness = EditorGUILayout.DoubleField("Rigid Grasping Stiffness", script.rigidGraspingStiffness);
GUILayout.EndVertical();
// Maybe this is something we should do for all imstk components
// as we can't edit them during runtime anyway
if (_rigid != null && !Application.isPlaying)
{
// Takes up a lot of resources when playing, just don't execute
HandleGraspingData(script);
UpdateScript(script);
}
else
{
EditorGUI.EndChangeCheck();
}
}
private void UpdateScript(GraspingManager script)
{
if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(script, "Change of Parameters");
script.rigid = _rigid;
script.graspingGeometry = _graspingGeometry;
script.graspingData = new List<GraspingManager.GraspingData>(_graspingData);
script.deformableGraspingStiffness = _deformableGraspingStiffness;
script.rigidGraspingStiffness = _rigidGraspingStiffness;
}
}
private void HandleGraspingData(GraspingManager script)
{
// if there aren't any items to grasp, make sure ...
if (_allDeformables.Count == 0) OnHierarchyChanged();
_graspingData = new List<GraspingManager.GraspingData>(script.graspingData);
foreach (var item in _allDeformables)
{
if (item is StaticModel || item == _rigid) continue;
if (_graspingData.FindIndex(x => x.target == item) < 0)
{
GraspingManager.GraspingData graspingData = new GraspingManager.GraspingData();
graspingData.enabled = false;
graspingData.type = Grasping.GraspType.Cell;
graspingData.target = item;
_graspingData.Add(graspingData);
}
}
// Remove stale Objects
_graspingData.RemoveAll(x => !_allDeformables.Contains(x.target));
_folded = EditorGUILayout.Foldout(_folded, "Graspable Objects");
if (_folded)
{
EditorGUILayout.BeginVertical();
for (int i = 0; i < _graspingData.Count; ++i)
{
var item = _graspingData[i];
EditorGUILayout.BeginHorizontal();
item.enabled = EditorGUILayout.Toggle(item.enabled, GUILayout.Width(20));
EditorGUI.BeginDisabledGroup(!item.enabled);
EditorGUILayout.LabelField(item.target.name);
item.type = (Grasping.GraspType)EditorGUILayout.EnumPopup(item.type);
EditorGUI.EndDisabledGroup();
EditorGUILayout.EndHorizontal();
_graspingData[i] = item;
}
EditorGUILayout.EndVertical();
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 90bae2d9e1ecd124b913832a0a5a1abb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,113 @@
/*=========================================================================
Library: iMSTK-Unity
Copyright (c) Kitware, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
using ImstkUnity;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
namespace ImstkEditor
{
/// <summary>
/// Defines the gui to fill ImstkSettings
/// </summary>
class ImstkSettingsProvider : SettingsProvider
{
private ImstkSettings settings;
public ImstkSettingsProvider(string path, SettingsScope scope = SettingsScope.User) : base(path, scope) { }
public static bool IsSettingsAvailable() { return File.Exists(ImstkSettings.settingsPath); }
// Read existing settings or create settings if they don't exist when user clicks them
public override void OnActivate(string searchContext, VisualElement rootElement) { settings = ImstkSettings.Instance(); }
public override void OnGUI(string searchContext)
{
EditorGUI.BeginChangeCheck();
bool useOptimalNumberOfThreads = EditorGUILayout.Toggle("Use Optimal # Threads", settings.useOptimalNumberOfThreads);
//int numThreads = settings.numThreads;
//if (!useOptimalNumberOfThreads)
// numThreads = EditorGUILayout.IntField("# Threads", numThreads);
EditorGUILayout.HelpBox(
"When developer mode is on you will be prompted to install imstk " +
" this can only be done by restarting unity as the editor will may load dll's preventing you from installing imstk" +
" while the editor is running.", MessageType.Warning);
bool useDevMode = EditorGUILayout.Toggle("Use Developer Mode", settings.useDeveloperMode);
string installPath = settings.installSourcePath;
if (useDevMode)
{
GUILayout.BeginVertical(EditorStyles.helpBox);
GUILayout.BeginHorizontal();
GUILayout.Label("iMSTK Install Directory");
installPath = EditorGUILayout.TextField(installPath);
if (GUILayout.Button("Open Directory"))
{
installPath = EditorUtility.OpenFolderPanel("iMSTK Install Directory (Development Use)", settings.installSourcePath, "");
}
GUILayout.EndHorizontal();
EditorGUILayout.HelpBox("Force install will attempt to perform an install now. This may not work if " +
"any imstk libraries are already loaded.",
MessageType.Warning);
if (GUILayout.Button("Force Install"))
{
EditorUtils.InstallImstk(installPath);
}
GUILayout.EndVertical();
}
if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(settings, "Change of Settings");
settings.useDeveloperMode = useDevMode;
settings.useOptimalNumberOfThreads = useOptimalNumberOfThreads;
//settings.numThreads = numThreads;
settings.installSourcePath = installPath;
if (!System.IO.Directory.Exists(ImstkSettings.settingsDirectory))
{
System.IO.Directory.CreateDirectory(ImstkSettings.settingsDirectory);
}
EditorUtility.SetDirty(settings);
AssetDatabase.SaveAssets();
}
}
/// <summary>
/// Register the SettingsProvider so it can be found in Editor->Project Settings
/// </summary>
[SettingsProvider]
public static SettingsProvider CreateMyCustomSettingsProvider()
{
var provider = new ImstkSettingsProvider("Project/iMSTK Settings", SettingsScope.Project);
provider.keywords = new HashSet<string>(new string[] { "Debug", "Logger", "Threads", "iMSTK" });
return provider;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 195737e5160741b4a8d43f53837040df
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,74 @@
/*=========================================================================
Library: iMSTK-Unity
Copyright (c) Kitware, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
using ImstkUnity;
using UnityEditor;
namespace ImstkEditor
{
/// <summary>
/// This class observes the play mode state to properly pause and step
/// Imstk in the Unity editor
/// </summary>
[InitializeOnLoad]
class PlayModeStateObserver
{
static PlayModeStateObserver()
{
#if UNITY_EDITOR
// Perform imstk install if developer mode is on
ImstkSettings settings = ImstkSettings.Instance();
if (settings.useDeveloperMode &&
EditorUtility.DisplayDialog("Do you want to install imstk",
"To install imstk select yes and provide your imstk build/install directory. If you would not " +
"like to be prompted again, please turn off developer mode in imstk settings. Note: " +
"This prompt will be displayed upon installation again, select no second time.", "Yes", "No"))
{
settings.installSourcePath =
EditorUtility.OpenFolderPanel("iMSTK Install Directory (Development Use)", settings.installSourcePath, "");
EditorUtils.InstallImstk(settings.installSourcePath);
EditorUtility.SetDirty(settings);
AssetDatabase.SaveAssets();
}
#endif
//EditorApplication.playModeStateChanged += playModeStateChanged;
EditorApplication.pauseStateChanged += pauseStateChanged;
}
private static void pauseStateChanged(PauseState state)
{
if (SimulationManager.sceneManager != null)
{
bool paused = SimulationManager.sceneManager.getPaused();
if (paused)
{
SimulationManager.sceneManager.setPaused(true);
}
else
{
SimulationManager.sceneManager.setPaused(false);
}
}
}
//private static void playModeStateChanged(PlayModeStateChange state) { }
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2e6b12b0479820f43b977a10b5399b5b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,196 @@
/*=========================================================================
Library: iMSTK-Unity
Copyright (c) Kitware, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
using ImstkUnity;
using UnityEngine;
using UnityEditor;
namespace ImstkEditor
{
[CustomEditor(typeof(RigidController))]
public class RigidControllerEditor : Editor
{
Vector3 _attachmentPoint;
Vector3 _translationalOffset;
Vector3 _rotationalOffset;
Vector3 _localRotationalOffset;
double _translationScaling;
public override void OnInspectorGUI()
{
RigidController script = target as RigidController;
EditorGUI.BeginChangeCheck();
GUILayout.BeginVertical(EditorStyles.helpBox);
TrackingDevice results = script.device;
Object obj = EditorGUILayout.ObjectField("Device", results, typeof(Object), true) as Object;
if (obj is TrackingDevice)
{
results = obj as TrackingDevice;
}
else if (obj is GameObject)
{
results = (obj as GameObject).GetComponent<TrackingDevice>();
}
else
{
Debug.LogWarning("Cannot set object on field, expects TrackingDevice or game object with TrackingDevice");
}
Rigid rigid = EditorGUILayout.ObjectField("Rigid", script.rigid, typeof(Rigid), true) as Rigid;
GUILayout.EndVertical();
GUILayout.BeginVertical(EditorStyles.helpBox);
bool useCriticalDamping = EditorGUILayout.Toggle("Critical Damping", script.useCriticalDamping);
double linearKs = EditorGUILayout.DoubleField("Linear Spring Constant", script.linearKs);
double linearKd = script.linearKd;
if (!useCriticalDamping)
{
linearKd = EditorGUILayout.DoubleField("Linear Damping", script.linearKd);
}
double angularKs = EditorGUILayout.DoubleField("Angular Spring Constant", script.angularKs);
double angularKd = script.angularKd;
if (!useCriticalDamping)
{
angularKd = EditorGUILayout.DoubleField("Angular Damping", script.angularKd);
}
GUILayout.EndVertical();
script._forceFoldout = EditorGUILayout.Foldout(script._forceFoldout, "Force Settings");
double forceScaling = script.forceScale;
bool useForceSmoothing = script.useForceSmoothing;
int forceSmoothKernelSize = script.forceSmoothingKernelSize;
if (script._forceFoldout)
{
GUILayout.BeginVertical(EditorStyles.helpBox);
forceScaling = EditorGUILayout.DoubleField("Force Scaling", script.forceScale);
useForceSmoothing = EditorGUILayout.Toggle("Use Force Smoothing", script.useForceSmoothing);
forceSmoothKernelSize =
EditorGUILayout.IntField("Force Smooth Kernel Size", script.forceSmoothingKernelSize);
GUILayout.EndVertical();
}
var offsetContent = new GUIContent("Offsets", "Settings that will transform the controlled objects coordinate system in " +
"relation to the device coordinate system");
script._offsetFoldout = EditorGUILayout.Foldout(script._offsetFoldout, offsetContent);
// Initialize in case the foldout is closed
_attachmentPoint = script.attachmentPoint;
_translationScaling = script.translationScaling;
_translationalOffset = script.translationalOffset;
_rotationalOffset = script.rotationalOffset.eulerAngles;
_localRotationalOffset = script.localRotationalOffset.eulerAngles;
if (script._offsetFoldout)
{
GUILayout.BeginVertical(EditorStyles.helpBox);
_attachmentPoint = EditorGUILayout.Vector3Field("Attachment Point", script.attachmentPoint);
if (GUILayout.Button("Copy Translational Offset from Transform"))
{
_translationalOffset = script.transform.position;
} else
{
_translationalOffset =
EditorGUILayout.Vector3Field("Translational Offset", script.translationalOffset);
}
_rotationalOffset =
EditorGUILayout.Vector3Field("Rotational Offset", script.rotationalOffset.eulerAngles);
_localRotationalOffset =
EditorGUILayout.Vector3Field("Local Rotational Offset", script.localRotationalOffset.eulerAngles);
_translationScaling =
EditorGUILayout.DoubleField("Translation Scaling", script.translationScaling);
GUILayout.EndVertical();
}
script._axisMappingFoldout = EditorGUILayout.Foldout(script._axisMappingFoldout, "Coordinate Transforms");
bool invertX = script.invertX;
bool invertY = script.invertY;
bool invertZ = script.invertZ;
bool rotInvertX = script.invertRotX;
bool rotInvertY = script.invertRotY;
bool rotInvertZ = script.invertRotZ;
if (script._axisMappingFoldout)
{
GUILayout.BeginVertical(EditorStyles.helpBox);
invertX = EditorGUILayout.Toggle("Invert X", script.invertX);
invertY = EditorGUILayout.Toggle("Invert Y", script.invertY);
invertZ = EditorGUILayout.Toggle("Invert Z", script.invertZ);
rotInvertX = EditorGUILayout.Toggle("Rotation Invert X", script.invertRotX);
rotInvertY = EditorGUILayout.Toggle("Rotation Invert Y", script.invertRotY);
rotInvertZ = EditorGUILayout.Toggle("Rotation Invert Z", script.invertRotZ);
GUILayout.EndVertical();
}
bool debugController = EditorGUILayout.Toggle("Write Controller transform", script.debugController);
if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(script, "Change of Parameters");
script.device = results;
script.rigid = rigid;
script.angularKd = angularKd;
script.angularKs = angularKs;
script.linearKd = linearKd;
script.linearKs = linearKs;
script.useCriticalDamping = useCriticalDamping;
script.forceScale = forceScaling;
script.useForceSmoothing = useForceSmoothing;
script.forceSmoothingKernelSize = forceSmoothKernelSize;
script.attachmentPoint = _attachmentPoint;
script.translationalOffset = _translationalOffset;
script.rotationalOffset.eulerAngles = _rotationalOffset;
script.localRotationalOffset.eulerAngles = _localRotationalOffset;
script.translationScaling = _translationScaling;
script.invertX = invertX;
script.invertY = invertY;
script.invertZ = invertZ;
script.invertRotX = rotInvertX;
script.invertRotY = rotInvertY;
script.invertRotZ = rotInvertZ;
script.debugController = debugController;
}
}
[DrawGizmo(GizmoType.InSelectionHierarchy)]
static void DrawHandles(RigidController scr, GizmoType gizmoType)
{
var pos = scr.transform.localToWorldMatrix.MultiplyPoint(scr.attachmentPoint);
// Draw a sphere at the haptic attachment point
Gizmos.color = Color.red;
Gizmos.DrawSphere(pos, 0.02f);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b142915e0959468428258cc9dc36f4b0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
+155
View File
@@ -0,0 +1,155 @@
/*=========================================================================
Library: iMSTK-Unity
Copyright (c) Kitware, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
using ImstkUnity;
using UnityEngine;
using UnityEditor;
using Imstk;
namespace ImstkEditor
{
[CustomEditor(typeof(Rigid))]
class RigidEditor : DynamicalModelEditor
{
GeometryFilter _physicsGeometryFilter;
bool _drawPhysicsGeometry = false;
GeometryFilter _collisionGeometryFilter;
bool _drawCollisionGeometry = false;
bool _bodyDamping = false;
double _linearDampingCoeff = 0.0;
double _angularDampingCoeff = 0.0;
readonly GUIContent _debugContent = new GUIContent("","Draw debug mesh");
readonly GUILayoutOption _checkBoxWidth = GUILayout.Width(20);
public override void OnInspectorGUI()
{
Rigid script = target as Rigid;
EditorGUI.BeginChangeCheck();
EditorGUILayout.BeginHorizontal();
_physicsGeometryFilter = EditorUtils.GeomFilterField("Physics Geometry", script.physicsGeomFilter);
_drawPhysicsGeometry = EditorGUILayout.Toggle(_debugContent, script.drawPhysicsGeometry, _checkBoxWidth);
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
_collisionGeometryFilter = EditorUtils.GeomFilterField("Collision Geometry", script.collisionGeomFilter);
_drawCollisionGeometry = EditorGUILayout.Toggle(_debugContent, script.drawCollisionGeometry, _checkBoxWidth);
EditorGUILayout.EndHorizontal();
GUILayout.BeginVertical(EditorStyles.helpBox);
double mass = EditorGUILayout.DoubleField("Mass", script.mass);
if (mass < 0.0)
{
Debug.LogWarning("Mass cannot be negative!");
mass = 0.0;
}
GUILayout.EndVertical();
GUILayout.BeginVertical(EditorStyles.helpBox);
GUILayout.Label("Inertia Tensor");
Vector3 inertiaRow1 = EditorGUILayout.Vector3Field("", script.inertia[0]);
Vector3 inertiaRow2 = EditorGUILayout.Vector3Field("", script.inertia[1]);
Vector3 inertiaRow3 = EditorGUILayout.Vector3Field("", script.inertia[2]);
GUILayout.EndVertical();
var ignoreGravity = EditorGUILayout.Toggle("Ignore Gravity", script.ignoreGravity);
GUILayout.BeginVertical(EditorStyles.helpBox);
_bodyDamping = EditorGUILayout.Toggle("Use Body Damping", script.useBodyDamping);
if (_bodyDamping)
{
_linearDampingCoeff = EditorGUILayout.Slider("Linear Damping Coeff", (float)script.linearDampingCoeff, 0, 1);
_angularDampingCoeff = EditorGUILayout.Slider("Angular Damping Coeff", (float)script.angularDampingCoeff, 0, 1);
}
GUILayout.EndVertical();
// Need to update PbdBody class to better support this when accessing it through the wrapper
// GUILayout.BeginVertical(EditorStyles.helpBox);
// Vector3 initVel = EditorGUILayout.Vector3Field("Initial Linear Velocity", script.initVelocity);
// Vector3 initAngularVel = EditorGUILayout.Vector3Field("Initial Angular Velocity", script.initAngularVelocity);
// GUILayout.EndVertical();
//
// GUILayout.BeginVertical(EditorStyles.helpBox);
// Vector3 initForce = EditorGUILayout.Vector3Field("Initial Force", script.initForce);
// Vector3 initTorque = EditorGUILayout.Vector3Field("Initial Torque", script.initTorque);
// GUILayout.EndVertical();
if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(script, "Change of Parameters");
script.physicsGeomFilter = _physicsGeometryFilter;
script.drawPhysicsGeometry = _drawPhysicsGeometry;
script.collisionGeomFilter = _collisionGeometryFilter;
script.drawCollisionGeometry = _drawCollisionGeometry;
script.mass = mass;
script.inertia[0] = inertiaRow1;
script.inertia[1] = inertiaRow2;
script.inertia[2] = inertiaRow3;
script.ignoreGravity = ignoreGravity;
script.useBodyDamping = _bodyDamping;
script.linearDampingCoeff = _linearDampingCoeff;
script.angularDampingCoeff = _angularDampingCoeff;
// script.initVelocity = initVel;
// script.initAngularVelocity = initAngularVel;
// script.initForce = initForce;
// script.initTorque = initTorque;
}
base.HandleColliders(script);
}
[DrawGizmo(GizmoType.Selected | GizmoType.Active)]
public static void DrawRigidGizmo(Rigid rigid, GizmoType gizmoType)
{
var dyn = rigid.GetDynamicObject();
var pbdObj = Imstk.Utils.CastTo<PbdObject>(dyn);
if (pbdObj != null)
{
if (rigid.drawCollisionGeometry)
{
DrawGeometryGizmo(pbdObj.getCollidingGeometry());
}
if (rigid.drawPhysicsGeometry)
{
DrawGeometryGizmo(pbdObj.getPhysicsGeometry());
}
}
}
public static void DrawGeometryGizmo(Imstk.Geometry geom)
{
var pointSet = Imstk.Utils.CastTo<PointSet>(geom);
if (pointSet != null)
{
ImstkGizmos.DrawMesh(pointSet, UnityEngine.Color.red);
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 68c782406a24eda4d946cef6db6f01cc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,78 @@
/*=========================================================================
Library: iMSTK-Unity
Copyright (c) Kitware, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
using ImstkUnity;
using UnityEngine;
using UnityEditor;
namespace ImstkEditor
{
[CustomEditor(typeof(SimulationManager))]
public class SimulationManagerEditor : Editor
{
public override void OnInspectorGUI()
{
// Define a style for centering text
var centeredStyle = GUI.skin.GetStyle("Label");
centeredStyle.alignment = TextAnchor.UpperCenter;
// Begin the script modification!
SimulationManager script = target as SimulationManager;
EditorGUI.BeginChangeCheck();
GUILayout.Label("Scene Settings", centeredStyle);
GUILayout.BeginVertical(EditorStyles.helpBox);
bool writeTaskGraph = EditorGUILayout.Toggle("Write Task Graph", script.writeTaskGraph);
EditorGUILayout.HelpBox(
"This is the timestep that iMSTK will used to advance the simulation, use the stats" +
" display and testing to arrive at a reasonable value for your simulation." ,
MessageType.Warning);
float fixedTimestep = EditorGUILayout.FloatField("Fixed Timestep", script.fixedTimestep);
GUILayout.EndVertical();
GUILayout.Label("Pbd Simulation Settings", centeredStyle);
GUILayout.BeginVertical(EditorStyles.helpBox);
var c = new PbdModelConfiguration();
c.gravity = EditorGUILayout.Vector3Field("Gravity", script.pbdModelConfiguration.gravity);
c.iterations = EditorGUILayout.IntField("Max # Iterations", script.pbdModelConfiguration.iterations);
c.useRealtime = EditorGUILayout.Toggle("Use Realtime", script.pbdModelConfiguration.useRealtime);
if (!script.pbdModelConfiguration.useRealtime)
{
c.dt = EditorGUILayout.DoubleField("Delta Time", script.pbdModelConfiguration.dt);
}
c.linearDampingCoeff = EditorGUILayout.DoubleField("Linear Damping Coefficient",
script.pbdModelConfiguration.linearDampingCoeff);
c.angularDampingCoeff = EditorGUILayout.DoubleField("Angular Damping Coefficient",
script.pbdModelConfiguration.angularDampingCoeff);
c.doPartitioning = EditorGUILayout.Toggle("Partitioning", script.pbdModelConfiguration.doPartitioning);
GUILayout.EndVertical();
if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(script, "Change of Parameters");
script.writeTaskGraph = writeTaskGraph;
script.pbdModelConfiguration = c;
script.fixedTimestep = fixedTimestep;
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 22dc68fd2e5f4144295545ee2ff229bb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,43 @@
/*=========================================================================
Library: iMSTK-Unity
Copyright (c) Kitware, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
using ImstkUnity;
using UnityEditor;
namespace ImstkEditor
{
[CustomEditor(typeof(StaticModel))]
class StaticModelEditor : Editor
{
public override void OnInspectorGUI()
{
StaticModel script = target as StaticModel;
EditorGUI.BeginChangeCheck();
GeometryFilter collisionGeomFilter = EditorUtils.GeomFilterField("Collision Geometry", script.collisionGeomFilter);
if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(script, "Change of Parameters");
script.collisionGeomFilter = collisionGeomFilter;
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1f318b9a7ac342f4c94f8ad8d9b618af
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant: