public void BeginStroke(Frame3f vFrameS, int nHitElementID, MeshEditorOpType.ElementType elemType) { if (in_stroke) { throw new Exception("MeshEditorTool.BeginBrushStroke: already in brush stroke!"); } Frame3f vFrameL = SceneTransforms.SceneToObject(Target, vFrameS); begin_stroke(vFrameL, nHitElementID, elemType); in_stroke = true; lastBrushPosS = vFrameS; }
protected override BaseDMeshSourceOp edit_op_factory(TargetObject o) { TransformSequence xform = SceneTransforms.ObjectToObjectXForm(o.SO, ReprojectTargetSO); return(new ReprojectOp() { MeshSource = o.MeshSourceOp, TargetMaxDistance = 1.0, RemeshRounds = 10, ProjectionRounds = 20, TargetSource = ReprojectTargetMeshOp, TransformToTarget = xform, ReprojectMode = ReprojectOp.ReprojectModes.SmoothSurfaceFlow }); }
void update() { MeshIsoCurves iso = new MeshIsoCurves(SO.Mesh, (v) => { return((v - frameL.Origin).Dot(frameL.Z)); }); iso.Compute(); graph = iso.Graph; localCurves = DGraph3Util.ExtractCurves(graph); // ugh need xform seq for to/from world... if (OutputSpace == CoordSpace.WorldCoords) { foreach (DCurve3 c in localCurves.Loops) { for (int i = 0; i < c.VertexCount; ++i) { c[i] = SceneTransforms.TransformTo((Vector3f)c[i], SO, CoordSpace.ObjectCoords, OutputSpace); } } foreach (DCurve3 c in localCurves.Paths) { for (int i = 0; i < c.VertexCount; ++i) { c[i] = SceneTransforms.TransformTo((Vector3f)c[i], SO, CoordSpace.ObjectCoords, OutputSpace); } } } else if (OutputSpace == CoordSpace.SceneCoords) { TransformSequence xform = SceneTransforms.ObjectToSceneXForm(SO); foreach (DCurve3 c in localCurves.Loops) { for (int i = 0; i < c.VertexCount; ++i) { c[i] = xform.TransformP(c[i]); } } foreach (DCurve3 c in localCurves.Paths) { for (int i = 0; i < c.VertexCount; ++i) { c[i] = xform.TransformP(c[i]); } } } }
public virtual void Setup() { // push history stream, so that we can do undo/redo internal to tool, // that will not end up in external history push_history_stream(); if (OnApplyF == null) { OnApplyF = this.add_to_scene; } combineMesh = new DMesh3(); MeshEditor editor = new MeshEditor(combineMesh); foreach (var so in InputSOs) { DMesh3 inputMesh = so.Mesh; int[] mapV; if (editor.AppendMesh(so.Mesh, out mapV)) { MeshTransforms.PerVertexTransform(combineMesh, inputMesh, mapV, (v, old_id, new_id) => { return(SceneTransforms.ObjectToSceneP(so, v)); }); } } ; MeshSourceOp = new ConstantMeshSourceOp(combineMesh, true, true); SeparateOp = new SeparateSolidsOp() { MeshSource = MeshSourceOp }; ComputeOp = new ThreadedResultComputeOp <List <DMesh3> >() { ResultSource = SeparateOp }; if (HiddenPreviewMaterial == null) { HiddenPreviewMaterial = SOMaterial.CreateTransparent("remove_hidden_generated", new Colorf(Colorf.DimGrey, 0.5f)); } if (KeepPreviewMaterial == null) { KeepPreviewMaterial = SOMaterial.CreateFlatShaded("remove_keep_generated", Colorf.DimGrey); } }
protected override void on_curve_validated() { if (previewGO != null) { RemoveGO((fGameObject)previewGO); previewGO.Destroy(); } if (EnableRegionOverlay) { if (TargetModelSO == null) { throw new InvalidOperationException("EnclosedPatchSO.on_curve_validated: curve is not connected to a Target"); } if (TransformMode != OutputCurveTransform.ToTargetSO) { throw new InvalidOperationException("EnclosedPatchSO.on_curve_validated: curve is not transformed to TargetSO"); } DCurve3 target_curve = RequestCurveCopyFromMainThread(); MeshFacesFromLoop loop = new MeshFacesFromLoop(TargetModel.SourceMesh, target_curve, TargetModel.SourceSpatial); MeshFaceSelection face_selection = loop.ToSelection(); DSubmesh3 submesh = new DSubmesh3(TargetModel.SourceMesh, face_selection, face_selection.Count); MeshNormals normals = new MeshNormals(submesh.SubMesh); normals.Compute(); foreach (int vid in submesh.SubMesh.VertexIndices()) { Vector3d n = normals.Normals[vid]; Vector3d v = submesh.SubMesh.GetVertex(vid); v += 0.1 * n; v = SceneTransforms.TransformTo(v, TargetModelSO, this); submesh.SubMesh.SetVertex(vid, v); } previewGO = GameObjectFactory.CreateMeshGO("patch", new fMesh(submesh.SubMesh), false, true); previewGO.SetMaterial(previewMaterial, true); previewGO.SetLayer(FPlatform.WidgetOverlayLayer); previewGO.SetIgnoreMaterialChanges(); AppendNewGO(previewGO, root, false); } }
public bool FindHitVertex(Ray3f sceneRay, MeshEditorOpType.BoundaryType boundaryMode, ref Frame3f hitFrameS, ref int hitVID) { Ray3f objRay = SceneTransforms.SceneToObject(Target, sceneRay); int hit_tri = PreviewSpatial.FindNearestHitTriangle(objRay); if (hit_tri == DMesh3.InvalidID) { return(false); } if (allow_backface_hits == false && is_back_facing(hit_tri)) { return(false); } Index3i vt = PreviewMesh.GetTriangle(hit_tri); hitVID = -1; double near_sqr = double.MaxValue; for (int j = 0; j < 3; ++j) { Vector3f v = (Vector3f)PreviewMesh.GetVertex(vt[j]); if (objRay.DistanceSquared(v) < near_sqr) { near_sqr = objRay.DistanceSquared(v); hitVID = vt[j]; } } if (boundaryMode != MeshEditorOpType.BoundaryType.Any) { bool is_boundary = PreviewMesh.IsBoundaryVertex(hitVID); if ((is_boundary && boundaryMode == MeshEditorOpType.BoundaryType.OnlyInternal) || (is_boundary == false && boundaryMode == MeshEditorOpType.BoundaryType.OnlyBoundary)) { return(false); } } Frame3f hitFrameL = new Frame3f(PreviewMesh.GetVertex(hitVID), PreviewMesh.GetTriNormal(hit_tri)); hitFrameS = SceneTransforms.ObjectToScene(previewSO, hitFrameL); return(true); }
public static PlaneIntersectionCurveSO CreateFromPlane(DMeshSO TargetSO, Frame3f PlaneS, SOMaterial material, FScene scene, double fNormalOffset = 0.0f) { Frame3f PlaneO = SceneTransforms.SceneToObject(TargetSO, PlaneS); PlaneIntersectionCurves curves = new PlaneIntersectionCurves(TargetSO.Mesh, PlaneO, 1) { NormalOffset = fNormalOffset }; curves.Compute(); if (curves.Loops.Length != 1) { throw new Exception("PlaneIntersectionSO.CreateFromPlane: got more than one cut loop?"); } DCurve3 loop = curves.Loops[0]; // map loop back into plane frame for (int i = 0; i < loop.VertexCount; ++i) { loop[i] = PlaneO.ToFrameP(loop[i]); } PlaneIntersectionCurveSO curveSO = new PlaneIntersectionCurveSO() { Curve = loop }; curveSO.Create(material); Frame3f curveFrame = SceneTransforms.ObjectToScene(TargetSO, PlaneO); curveSO.SetLocalFrame(curveFrame, CoordSpace.ObjectCoords); scene.History.PushChange( new AddSOChange() { scene = scene, so = curveSO, bKeepWorldPosition = false }); scene.History.PushInteractionCheckpoint(); return(curveSO); }
/// <summary> /// called on click-down /// </summary> override public void Begin(SceneObject so, Vector2d downPos, Ray3f downRayWorld) { SORayHit hit; if (TargetSO.FindRayIntersection(downRayWorld, out hit) == false) { return; } Vector3d scenePos = SceneTransforms.WorldToSceneP(this.Scene, hit.hitPos); if (have_source == false) { CurrentSourceHitPosS = new Frame3f(scenePos); sourceIndicator = new SphereIndicator() { SceneFrameF = () => { return(CurrentSourceHitPosS); }, Radius = fDimension.Scene(SourceIndicatorSizeScene * 0.5), ColorF = () => { return(Colorf.Orange); } }; indicators.AddIndicator(sourceIndicator); have_source = true; source_modified = true; } else if (have_extent == false) { CurrentExtentHitPosS = new Frame3f(scenePos); extentIndicator = new SphereIndicator() { SceneFrameF = () => { return(CurrentExtentHitPosS); }, Radius = fDimension.Scene(ExtentIndicatorSizeScene * 0.5), ColorF = () => { return(Colorf.CornflowerBlue); } }; indicators.AddIndicator(extentIndicator); have_extent = true; extent_modified = true; } }
override public void Apply() { float VerticalSpaceFudge = 10.0f; DMeshSO TargetMeshSO = TargetSO as DMeshSO; Frame3f curFrameS = TargetSO.GetLocalFrame(CoordSpace.SceneCoords); TransformSOChange change = new TransformSOChange(TargetSO, curFrameS, lastPreviewFrameS, CoordSpace.SceneCoords); Scene.History.PushChange(change, false); Frame3f newFrameS = new Frame3f(SceneTransforms.ObjectToSceneP(TargetSO, meshBounds.Center)); RepositionPivotChangeOp pivot1 = new RepositionPivotChangeOp(newFrameS, TargetMeshSO); Scene.History.PushChange(pivot1, false); newFrameS = TargetSO.GetLocalFrame(CoordSpace.SceneCoords); AxisAlignedBox3d bounds = TargetMeshSO.Mesh.CachedBounds; float h = (float)bounds.Height; Vector3f o = newFrameS.Origin; Vector3f translate = new Vector3f(-o.x, h * 0.5f - o.y + VerticalSpaceFudge, -o.z); Frame3f centeredFrameS = newFrameS.Translated(translate); TransformSOChange centerChange = new TransformSOChange(TargetSO, newFrameS, centeredFrameS, CoordSpace.SceneCoords); Scene.History.PushChange(centerChange, false); newFrameS = TargetSO.GetLocalFrame(CoordSpace.SceneCoords); o = newFrameS.Origin; o.y = 0; newFrameS.Origin = o; RepositionPivotChangeOp pivot2 = new RepositionPivotChangeOp(newFrameS, TargetMeshSO); Scene.History.PushChange(pivot2, false); Scene.History.PushInteractionCheckpoint(); }
/// <summary> /// initialize points w/ known base point and up direction /// </summary> public void Initialize_KnownBasePoint(Vector3d basePointL, Vector3f upAxis) { DMeshSO TargetMeshSO = TargetSO as DMeshSO; // initialize w/ auto-fit box DMesh3 mesh = TargetMeshSO.Mesh; DMeshAABBTree3 spatial = TargetMeshSO.Spatial; meshBounds = mesh.CachedBounds; create_preview_so(); /*Frame3f frameO = TargetSO.GetLocalFrame(CoordSpace.ObjectCoords);*/ // reproject base point onto surface in case somehow it is wrong Vector3f basePointUpdatedL = MeshQueries.NearestPointFrame(mesh, spatial, basePointL).Origin; Vector3f BasePointS = SceneTransforms.ObjectToSceneP(TargetSO, basePointUpdatedL); Vector3f upAxisL = Vector3f.AxisY; Vector3f topPointL = basePointUpdatedL + upAxisL * (float)meshBounds.Height; topPointL = MeshQueries.NearestPointFrame(mesh, spatial, topPointL).Origin; Vector3f TopPointS = SceneTransforms.ObjectToSceneP(TargetSO, topPointL); // shoot ray forward in scene, to find front point Vector3f forwardL = SceneTransforms.SceneToObjectN(TargetSO, -Vector3f.AxisZ); Frame3f fwHitFrameL; bool bHit = MeshQueries.RayHitPointFrame(mesh, spatial, new Ray3d(meshBounds.Center, forwardL), out fwHitFrameL); if (!bHit) { throw new Exception("SocketAlignmentTool.Initialize_KnownBasePoint: ray missed!"); } Vector3f FrontPointS = SceneTransforms.ObjectToSceneP(TargetSO, fwHitFrameL.Origin); SetPointPosition(BasePointID, new Frame3f(BasePointS), CoordSpace.SceneCoords); SetPointPosition(FrontPointID, new Frame3f(FrontPointS), CoordSpace.SceneCoords); SetPointPosition(TopPointID, new Frame3f(TopPointS), CoordSpace.SceneCoords); }
public static void MoveToPrintBed(FScene scene, DMeshSO so, bool bInteractive) { TransformSequence seq = SceneTransforms.ObjectToSceneXForm(so); AxisAlignedBox3d bounds = BoundsUtil.Bounds(so.Mesh.Vertices(), seq); Frame3f curFrameS = so.GetLocalFrame(CoordSpace.SceneCoords); float dy = (float)(bounds.Center.y - bounds.Extents.y); if (Math.Abs(dy) > MathUtil.ZeroTolerancef) { Frame3f newFrameS = curFrameS; newFrameS.Origin = curFrameS.Origin - dy * Vector3f.AxisY; TransformSOChange change = new TransformSOChange(so, curFrameS, newFrameS, CoordSpace.SceneCoords); change.Tags.Add("MoveToPrintBed"); scene.History.PushChange(change, false); if (bInteractive) { scene.History.PushInteractionCheckpoint(); } } }
override public void SetLocalFrame(Frame3f newFrame, CoordSpace eSpace) { if (Parent != GetScene()) { throw new Exception("SlicePlaneHeightSO.SetLocalFrame: unsupported"); } Frame3f newSceneFrame = newFrame; if (eSpace == CoordSpace.WorldCoords) { newSceneFrame = SceneTransforms.WorldToScene(GetScene(), newFrame); } Line3d axis = new Line3d(ConstraintFrameS.Origin, Vector3d.AxisY); Segment3d seg = new Segment3d(axis.ClosestPoint(MinPosS), axis.ClosestPoint(MaxPosS)); Vector3d cp = seg.NearestPoint(newSceneFrame.Origin); newSceneFrame.Origin = (Vector3f)cp; base.SetLocalFrame(newSceneFrame, CoordSpace.SceneCoords); }
public void PreRender(Vector3f cameraPosition) { // since we are supporting case where so is moving (ie bimanual grab), we need to // update position here. And SetGameObjectFrame() does not support SceneCoords. // So map scene to world Frame3f FrameW = SceneTransforms.TransformTo(FrameS, so, CoordSpace.SceneCoords, CoordSpace.WorldCoords); UnityUtil.SetGameObjectFrame(primGO, FrameW, CoordSpace.WorldCoords); float fScaling = VRUtil.GetVRRadiusForVisualAngle( primGO.transform.position, cameraPosition, SceneGraphConfig.DefaultPivotVisualDegrees * 0.98f); // [RMS] not sure this makes sense...eg what if we have multiple parents? they could // have different scalings, no? ParentScale seems to be inherited from scene scaling, // somehow, but it is unclear... float fParentScale = primGO.transform.parent.localScale[0]; float fSceneScale = so.GetScene().GetSceneScale(); fScaling = fScaling / fParentScale / fSceneScale; primGO.transform.localScale = new Vector3f(fScaling, fScaling, fScaling); }
public IVectorDisplacementSourceOp AppendLengthenOp(PivotSO Source) { Frame3f deformF = Frame3f.Identity; deformF = SceneTransforms.TransformTo(deformF, Source, leg); LengthenOp deformOp = new LengthenOp() { BasePoint = deformF.Origin, Direction = -Vector3d.AxisY, BandDistance = 50.0f, LengthenDistance = 2.0f, MeshSource = SOMeshSource }; Combiner.Append(deformOp); SO_Op.Add(Source, deformOp); OnDeformationAdded?.Invoke(Source, deformOp); return(deformOp); }
public IVectorDisplacementSourceOp AppendRegionOffset(EnclosedPatchSO Source) { Frame3f deformF = Frame3f.Identity; deformF = SceneTransforms.TransformTo(deformF, Source, leg); PolyCurveSOSourceOp curveOp = new PolyCurveSOSourceOp(Source); EnclosedRegionOffsetOp deformOp = new EnclosedRegionOffsetOp() { Normal = deformF.Y, PushPullDistance = 2.0f, MeshSource = SOMeshSource, CurveSource = curveOp }; Combiner.Append(deformOp); SO_Op.Add(Source, deformOp); OnDeformationAdded?.Invoke(Source, deformOp); return(deformOp); }
public IVectorDisplacementSourceOp AppendPlaneBandExpansion(PlaneIntersectionCurveSO Source) { Frame3f deformF = Frame3f.Identity; deformF = SceneTransforms.TransformTo(deformF, Source, leg); PlaneBandExpansionOp deformOp = new PlaneBandExpansionOp() { Origin = deformF.Origin, Normal = deformF.Y, BandDistance = 15.0f, PushPullDistance = -1.0f, MeshSource = SOMeshSource }; Combiner.Append(deformOp); SO_Op.Add(Source, deformOp); OnDeformationAdded?.Invoke(Source, deformOp); return(deformOp); }
public Frame3f GetPointPosition(int id, CoordSpace space = CoordSpace.SceneCoords) { ControlPoint pt; if (GizmoPoints.TryGetValue(id, out pt) == false) { throw new Exception("MultiSurfacePointTool.SetPointPosition: point with id " + id + " does not exist!"); } if (space == CoordSpace.WorldCoords) { return(SceneTransforms.SceneToWorld(this.Scene, pt.currentFrameS)); } else if (space == CoordSpace.ObjectCoords) { return(SceneTransforms.SceneToObject(TargetSO, pt.currentFrameS)); } else { return(pt.currentFrameS); } }
/// <summary> /// adds an expand/contract-type plane/leg intersection thing at the given frame /// </summary> public static void AddLengthenOp() { if (OG.IsInState(OGWorkflow.RectifyState) == false) { return; } LengthenPivotSO pivotSO = new LengthenPivotSO(); pivotSO.Create(OG.Scene.PivotSOMaterial, null); OG.Scene.AddSceneObject(pivotSO, false); pivotSO.Name = "LengthenPivot"; // we put the lengthen pivot at min vertex of leg DMesh3 mesh = OG.Leg.SO.Mesh; Vector3d minYPt = Vector3d.Zero; foreach (Vector3d v in mesh.Vertices()) { if (v.y < minYPt.y) { minYPt = v; } } Vector3d basePtS = SceneTransforms.ObjectToSceneP(OG.Leg.SO, minYPt); Frame3f pivotF = new Frame3f(basePtS); pivotSO.SetLocalFrame(pivotF, CoordSpace.SceneCoords); pivotSO.InitialLegPtL = pivotF.Origin; AddNewLengthenOp(pivotSO); // select pivot next frame OG.Context.RegisterNextFrameAction(() => { OG.Scene.Select(pivotSO, true); }); }
/// <summary> /// called on click-down /// </summary> override public void Begin(SceneObject so, Vector2d downPos, Ray3f downRay) { SORayHit hit; if (TargetSO.FindRayIntersection(downRay, out hit) == false) { return; } Vector3d scenePos = SceneTransforms.WorldToSceneP(this.Scene, hit.hitPos); CurrentHitPosS = new Frame3f(scenePos); float fObjectT = (CurrentHitPosS.Origin - ObjectFrameS.Origin).Dot(ObjectFrameS.Y); CurrentPlaneFrameS = ObjectFrameS.Translated(fObjectT, 1); if (have_set_plane == false) { sphereIndicator = IndicatorBuilder.MakeSphereIndicator(0, "hit_point", fDimension.Scene(sphere_indicator_size * 0.5), () => { return(CurrentHitPosS); }, () => { return(Colorf.Orange); }, () => { return(true); }); Indicators.AddIndicator(sphereIndicator); sphereIndicator.RootGameObject.SetName("hit_point"); planeIndicator = IndicatorBuilder.MakeSectionPlaneIndicator(1, "section_plane", fDimension.Scene(plane_indicator_width), () => { return(CurrentPlaneFrameS); }, () => { return(new Colorf(Colorf.LightGreen, 0.5f)); }, () => { return(true); }); Indicators.AddIndicator(planeIndicator); planeIndicator.RootGameObject.SetName("section_plane"); have_set_plane = true; } }
void update_current_hole_type() { if (HoleType == HoleTypes.CutHole) { if (CutOp != null) { CutOp.StartPoint = LastUpdateRay.Origin; CutOp.EndPoint = LastUpdateRay.PointAt(LastThroughDepth); } } if (HoleType == HoleTypes.CavityObject || AlwaysShowPreview) { Frame3f holeFrame = new Frame3f(LastUpdateRay.Origin, LastUpdateRay.Direction); holeFrame.Translate((float)(-CurEndOffset) * holeFrame.Z); Frame3f holeFrameS = SceneTransforms.ObjectToScene(InputMeshSO, holeFrame); CavityPreviewSO.SetLocalFrame(holeFrameS, CoordSpace.SceneCoords); CavityPreviewSO.SetLocalScale(new Vector3f(hole_size, hole_size, (float)CurHoleDepth)); } active_hole_type = HoleType; }
public List <Polygon2d> GetPolygons() { Frame3f f = frameL; if (OutputSpace != CoordSpace.ObjectCoords) { f = SceneTransforms.TransformTo(f, SO, CoordSpace.ObjectCoords, OutputSpace); } List <Polygon2d> polygons = new List <Polygon2d>(); foreach (DCurve3 c in localCurves.Loops) { Polygon2d poly = new Polygon2d(); for (int i = 0; i < c.VertexCount; ++i) { Vector2f uv = f.ToPlaneUV((Vector3f)c[i], 2); poly.AppendVertex(uv); } polygons.Add(poly); } return(polygons); }
public static void DuplicateSelectedObjects(bool bInteractive) { List <SceneObject> duplicate = new List <SceneObject>(CC.ActiveScene.Selected); foreach (var existingSO in duplicate) { if (existingSO is PrintMeshSO == false) { throw new NotSupportedException("CCActions.DuplicateSelectedObjects: currently can only delete print meshes?"); } PrintMeshSO dupeSO = (existingSO as PrintMeshSO).DuplicateSubtype <PrintMeshSO>(); dupeSO.Name = UniqueNames.GetNext(existingSO.Name); AddNewPrintMesh(dupeSO); // If we have multi-select, then we duplicated relative to a transient group that will // go away. So, update position using scene coords if (existingSO.Parent is FScene == false) { var sceneF = existingSO.GetLocalFrame(CoordSpace.SceneCoords); dupeSO.SetLocalFrame(sceneF, CoordSpace.SceneCoords); Vector3f scaleL = existingSO.GetLocalScale(); Vector3f scaleS = SceneTransforms.ObjectToSceneV(existingSO, scaleL); float scale = scaleS.Length / scaleL.Length; dupeSO.SetLocalScale(scale * Vector3f.One); } if (dupeSO.CanAutoUpdateFromSource() && dupeSO.AutoUpdateOnSourceFileChange == true) { CC.FileMonitor.AddMesh(dupeSO); } } if (bInteractive) { CC.ActiveScene.History.PushInteractionCheckpoint(); } }
void update_selection() { if (have_source && have_extent) { if (source_modified) { Frame3f objFrame = SceneTransforms.SceneToObject(TargetSO, CurrentSourceHitPosS); int tid = TargetSO.Spatial.FindNearestTriangle(objFrame.Origin); selectionCache.InitializeGeodesicDistance(objFrame.Origin, tid); source_modified = false; selection_valid = false; } if (extent_modified) { Frame3f objFrame = SceneTransforms.SceneToObject(TargetSO, CurrentExtentHitPosS); int tid = TargetSO.Spatial.FindNearestTriangle(objFrame.Origin); float scalar = selectionCache.GetTriScalar(objFrame.Origin, tid); selectionCache.UpdateFromOrderedScalars(scalar); extent_modified = false; selection_valid = false; } } }
public virtual void Setup() { // push history stream, so that we can do undo/redo internal to tool, // that will not end up in external history push_history_stream(); if (OnApplyF == null) { OnApplyF = this.add_so_to_scene; } if (PreviewMaterial == null) { PreviewMaterial = SOMaterial.CreateMesh("tool_generated", Colorf.DimGrey); } if (ErrorMaterial == null) { ErrorMaterial = SOMaterial.CreateMesh("tool_generated_error", Colorf.VideoRed); } // clear selection here so that multi-select GroupSO goes away, otherwise // when we copy frmaes below, they are relative to that GroupSO, and things move inputSelection = new List <SceneObject>(Scene.Selected); set_allow_selection_changes(true); Scene.ClearSelection(); set_allow_selection_changes(false); if (InputSOs.Count == 1 && ForceSceneSpaceComputation == false) { combineMesh = new DMesh3(InputSOs[0].Mesh); sceneToObjUnitScale = SceneTransforms.SceneToObject(InputSOs[0], 1.0f); } else { combineMesh = new DMesh3(); MeshEditor editor = new MeshEditor(combineMesh); foreach (var so in InputSOs) { TransformSequence xform = SceneTransforms.ObjectToSceneXForm(so); DMesh3 inputMesh = so.Mesh; int[] mapV; if (editor.AppendMesh(so.Mesh, out mapV)) { MeshTransforms.PerVertexTransform(combineMesh, inputMesh, mapV, (v, old_id, new_id) => { return(xform.TransformP(v)); }); } } ; sceneToObjUnitScale = 1.0; } MeshSourceOp = new ConstantMeshSourceOp(combineMesh, true, true); EditOp = edit_op_factory(MeshSourceOp); ComputeOp = new ThreadedMeshComputeOp() { MeshSource = EditOp }; PreviewSO = new DMeshSO() { EnableSpatial = EnablePreviewSpatial }; PreviewSO.Create(new DMesh3(), PreviewMaterial); if (InputSOs.Count == 1 && ForceSceneSpaceComputation == false) { PreviewSO.SetLocalFrame(InputSOs[0].GetLocalFrame(CoordSpace.ObjectCoords), CoordSpace.ObjectCoords); PreviewSO.SetLocalScale(InputSOs[0].GetLocalScale()); } Scene.AddSceneObject(PreviewSO); postprocess_target_objects(); base_initialize_parameters(); }
public virtual void Setup() { // push history stream, so that we can do undo/redo internal to tool, // that will not end up in external history push_history_stream(); if (OnApplyF == null) { OnApplyF = this.add_so_to_scene; } if (PreviewMaterial == null) { PreviewMaterial = SOMaterial.CreateMesh("tool_generated", Colorf.DimGrey); } if (ErrorMaterial == null) { ErrorMaterial = SOMaterial.CreateMesh("tool_generated_error", Colorf.VideoRed); } // clear selection here so that multi-select GroupSO goes away, otherwise // when we copy frmaes below, they are relative to that GroupSO, and things move inputSelection = new List <SceneObject>(Scene.Selected); set_allow_selection_changes(true); Scene.ClearSelection(); set_allow_selection_changes(false); objects = new List <TargetObject>(); foreach (var so in InputSOs) { TargetObject o = new TargetObject(); o.SO = so; o.sceneFrame = so.GetLocalFrame(CoordSpace.SceneCoords); o.sceneToObjUnitScale = SceneTransforms.SceneToObject(o.SO, 1.0f); o.MeshSourceOp = new WrapDMeshSourceOp() { MeshSourceF = () => { return(so.Mesh); }, SpatialSourceF = () => { return(so.Spatial); } }; o.EditOp = edit_op_factory(o); o.Compute = new ThreadedMeshComputeOp() { MeshSource = o.EditOp }; o.Preview = new DMeshSO() { EnableSpatial = EnablePreviewSpatial }; o.Preview.Create(new DMesh3(), PreviewMaterial); o.Preview.SetLocalFrame(so.GetLocalFrame(CoordSpace.ObjectCoords), CoordSpace.ObjectCoords); o.Preview.SetLocalScale(so.GetLocalScale()); Scene.AddSceneObject(o.Preview); objects.Add(o); } postprocess_target_objects(); base_initialize_parameters(); }
/// <summary> /// This is the action we give to the trim-scan tool, to run on accept /// </summary> public static void CropScanFromSelection(DMeshSO so, MeshFaceSelection selection, object tool) { DMesh3 beforeMesh = new DMesh3(so.Mesh); DMesh3 mesh = so.Mesh; // [RMS] if we are using the two-point tool, then we can use the user input points to // try to figure out an up axis, by assuming the first point is on the base of the scan. Steps are: // 1) guess a midpoint. Currently centroid of upper-half of geodesic selection. // 2) construct up axis as (midpoint-basepoint). this axis to Y-up. Vector3f upAxisS = Vector3f.AxisY; TwoPointFaceSelectionTool ptool = tool as TwoPointFaceSelectionTool; if (ptool != null) { var cache = ptool.SelectionCache; Interval1d range = new Interval1d(cache.CurrentScalarThreshold / 2, cache.CurrentScalarThreshold); List <int> triangles = new List <int>(selection.Count); cache.FindTrianglesInScalarInterval(range, triangles); Vector3d c = MeshMeasurements.Centroid(triangles, mesh.GetTriCentroid); Vector3d cS = SceneTransforms.ObjectToSceneP(so, c); Vector3d basePosS = ptool.SourcePositionS.Origin; upAxisS = (Vector3f)(cS - basePosS).Normalized; } // crop scan and fill top hole List <int> borderTris = selection.FindBorderTris(); MeshEditor editor = new MeshEditor(mesh); editor.RemoveTriangles((tid) => { return(selection.IsSelected(tid) == false); }, true); if (OGActions.FillHoleInScan) { SmoothedHoleFill fill = new SmoothedHoleFill(mesh) { TargetEdgeLength = 2.5f, SmoothAlpha = 0.5f, BorderHintTris = borderTris, OffsetDirection = SceneTransforms.SceneToObjectN(so, upAxisS), OffsetDistance = (ptool != null) ? 25.0 : 0.0 }; fill.Apply(); } so.NotifyMeshEdited(); DMesh3 afterMesh = new DMesh3(so.Mesh); so.GetScene().History.PushChange(new ReplaceEntireMeshChange(so, beforeMesh, afterMesh), true); mesh = so.Mesh; // Now we auto-align the scan so it points upwards, and then // recenter pivot and shift to above ground plane if (ptool != null) { Vector3d basePosS = ptool.SourcePositionS.Origin; Quaternionf alignUp = Quaternionf.FromTo(upAxisS, Vector3f.AxisY); // rotate part so that axis points up Frame3f curF = so.GetLocalFrame(CoordSpace.SceneCoords); Frame3f newF = curF.Rotated(alignUp); TransformSOChange alignUpChange = new TransformSOChange(so, curF, newF, CoordSpace.SceneCoords); basePosS = newF.FromFrameP(curF.ToFrameP(basePosS)); // map to new frame so.GetScene().History.PushChange(alignUpChange, false); // recenter pivot at bbox center // [RMS] previously was using vertex centroid, but this is then affected by mesh density // (maybe tri centroid? but bbox makes more sense...and below we assume box center) Vector3d centerL = mesh.CachedBounds.Center; Vector3d centerO = newF.FromFrameP(centerL); Frame3f newPivotO = new Frame3f(centerO); so.GetScene().History.PushChange(new RepositionPivotChangeOp(newPivotO, so), false); // position above ground plane AxisAlignedBox3d bounds = so.Mesh.CachedBounds; float h = (float)bounds.Height; Vector3f o = newPivotO.Origin; Vector3f translateO = new Vector3f(-o.x, h * 0.5f - o.y + BaseHeightAboveGroundPlaneMM, -o.z); //Vector3f translateO = new Vector3f(0, h * 0.5f - o.y + BaseHeightAboveGroundPlaneMM, 0); newPivotO.Translate(translateO); so.GetScene().History.PushChange(new TransformSOChange(so, newPivotO, CoordSpace.ObjectCoords), false); // save base point in frame of scan basePosS += translateO; Vector3d basePosL = SceneTransforms.SceneToObjectP(so, basePosS); OG.Scan.UserBasePoint = basePosL; } so.GetScene().History.PushInteractionCheckpoint(); }