Initial Commit
This commit is contained in:
@@ -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:
|
||||
@@ -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:
|
||||
@@ -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:
|
||||
Reference in New Issue
Block a user