protected virtual ToolpathPreviewJoint GenerateMiterJoint(Segment3d segmentBefore, Segment3d segmentAfter, TPrintVertex printVertex, ToolpathPreviewMesh mesh)
        {
            var averageDirection = (segmentBefore.Direction + segmentAfter.Direction).Normalized;
            var scaleFactor      = 1 / segmentBefore.Direction.Dot(averageDirection);

            var frame = new Frame3f(printVertex.Position);

            frame.AlignAxis(1, ToVector3f(averageDirection));

            var joint = new ToolpathPreviewJoint();

            joint.InTop = joint.OutTop = mesh.AddVertex(vertexFactory(printVertex,
                                                                      frame.FromFrameP(DiamondCrossSection.Top(printVertex.Dimensions)), brightnessMax));

            joint.InRight = joint.OutRight = mesh.AddVertex(vertexFactory(printVertex,
                                                                          frame.FromFrameP(DiamondCrossSection.Right(printVertex.Dimensions)), brightnessMin));

            joint.InBottom = joint.OutBottom = mesh.AddVertex(vertexFactory(printVertex,
                                                                            frame.FromFrameP(DiamondCrossSection.Bottom(printVertex.Dimensions)), brightnessMax));

            joint.InLeft = joint.OutLeft = mesh.AddVertex(vertexFactory(printVertex,
                                                                        frame.FromFrameP(DiamondCrossSection.Left(printVertex.Dimensions)), brightnessMin));

            return(joint);
        }
Esempio n. 2
0
        void update_measurement()
        {
            Frame3f  localFrame = meshTarget.GetLocalFrame(CoordSpace.ObjectCoords);
            Vector3f localP     = localFrame.ToFrameP(scene.ToSceneP(measureHitPos));

            AxisAlignedBox3f bounds = meshTarget.GetLocalBoundingBox();
            Vector3f         dv     = localP - bounds.Center;

            dv.y = 0;

            Line3f   line    = new Line3f(Vector3f.Zero, Vector3f.AxisY);
            Vector3f linePos = line.ClosestPoint(localP);

            Frame3f mFrame = new Frame3f(linePos, Vector3f.AxisY);

            MeshSO.SectionInfo info = meshTarget.MeasureSection(mFrame);
            curDimension = info.maxDiameter;
            Vector3f center = 0.5f * (info.maxDiamPos1 + info.maxDiamPos2);

            //measureAxisPos = scene.ToWorldP(localFrame.FromFrameP(linePos));

            displayPosS   = localFrame.FromFrameP(linePos);
            circleCenterS = localFrame.FromFrameP(center);

            maxStart = localFrame.FromFrameP(info.maxDiamPos1);
            maxEnd   = localFrame.FromFrameP(info.maxDiamPos2);
        }
Esempio n. 3
0
        public void UpdateDraw_Spatial(Ray3f ray, Frame3f handFrame)
        {
            float    fScale    = scene.GetSceneScale();
            Vector3f newHitPos = handFrame.FromFrameP(handHitVec);

            smooth_append(preview, scene.SceneFrame.ToFrameP(newHitPos) / fScale, dist_thresh(Width, fScale));
        }
Esempio n. 4
0
        // figuring out a decent line width is tricky. Want to be responsive to camera
        //  pos, so line doesn't get super-thick when zoomed in. So we want to measure
        //  screen-space radius. But off-screen vertices are a problem. So, only consider
        //  vertices within a level, pointing-forward view cone (can't be actual view cone
        //  because then line thickness changes as you turn head!).
        //
        //  Also sub-sample verts for efficiency. Probably we don't need to do this
        //  every frame...but how to distribute?
        //
        //  ***returns 0*** if we couldn't find any points in view cone
        public static float EstimateStableCurveWidth(FScene scene,
                                                     Frame3f curveFrameS, DCurve3 curve, float fVisualAngleDeg)
        {
            // do computations in Scene coords..."safest"?

            Vector3f camPos     = scene.ActiveCamera.GetPosition();
            Vector3f camForward = scene.ActiveCamera.Forward();

            // use level-forward
            camForward[1] = 0; camForward.Normalize();

            camPos     = scene.ToSceneP(camPos);
            camForward = scene.ToSceneN(camForward);

            const float ViewConeDotThresh = 0.707106f;   // 45 degrees
            int         nSubSampleInc     = Math.Max(2, curve.VertexCount / 10);

            float rSum = 0; int iSum = 0;

            for (int k = 0; k < curve.VertexCount; k += nSubSampleInc)
            {
                Vector3f vS = (Vector3f)curve.GetVertex(k);
                vS = curveFrameS.FromFrameP(vS);
                Vector3f dv = (vS - camPos).Normalized;
                if (dv.Dot(camForward) < ViewConeDotThresh)
                {
                    continue;
                }

                float r = VRUtil.GetVRRadiusForVisualAngle(vS, camPos, fVisualAngleDeg);
                rSum += r; iSum++;
            }
            return((rSum == 0) ? 0 :  scene.ToWorldDimension(rSum / (float)iSum));
        }
Esempio n. 5
0
        /// <summary>
        /// input ray is in Object (local) coords of so, apply all intermediate
        /// transforms to get it to Scene coords
        /// </summary>
        public static Ray3f ObjectToScene(SceneObject so, Ray3f objectRay)
        {
            Ray3f       sceneRay = objectRay;
            SceneObject curSO    = so;

            while (curSO != null)
            {
                Frame3f  curF  = curSO.GetLocalFrame(CoordSpace.ObjectCoords);
                Vector3f scale = curSO.GetLocalScale();
                Vector3f new_o = curF.FromFrameP(sceneRay.Origin * scale);
                Vector3f new_d = curF.FromFrameV(sceneRay.Direction * scale);
                sceneRay = new Ray3f(new_o, new_d.Normalized);
                SOParent parent = curSO.Parent;
                if (parent is FScene)
                {
                    return(sceneRay);
                }
                curSO = (parent as SceneObject);
            }
            if (curSO == null)
            {
                DebugUtil.Error("SceneTransforms.ObjectToScene: found null parent SO!");
            }
            return(sceneRay);
        }
Esempio n. 6
0
        protected override void update_vertices(FScene s)
        {
            if (Target.Timestamp == target_timestamp)
            {
                return;
            }

            target_timestamp = Target.Timestamp;

            DMesh3 Mesh = Target.Mesh;

            for (int i = 0; i < VertexCount; ++i)
            {
                SurfaceVertexRef r    = SurfacePoints[i];
                Vector3d         vSum = Vector3d.Zero;
                Frame3f          f    = Mesh.GetTriFrame(r.tid);
                Index3i          tv   = Mesh.GetTriangle(r.tid);
                for (int j = 0; j < 3; ++j)
                {
                    f.Origin = (Vector3f)Mesh.GetVertex(tv[j]);
                    Vector3d v = f.FromFrameP(r.offsets[j]);
                    vSum += v;
                }
                vSum   /= 3;
                this[i] = SceneTransforms.ObjectToSceneP(Target, vSum);
            }
        }
Esempio n. 7
0
        public void UpdateDraw_Ray(Ray3f ray, int nStep)
        {
            // scene xform may have changed during steps (eg view rotation), so we
            // need to reconstruct our local frame
            Frame3f primCurW = scene.ToWorldFrame(primStartS);

            // step 1: find radius in plane
            // step 2: find height from plane
            float fY = MinDimension;

            if (nStep == 0)
            {
                Vector3f forwardDir = ray.Direction;
                Vector3f plane_hit  = VRUtil.SafeRayPlaneIntersection(ray, forwardDir, primCurW.Origin, primCurW.Y);
                plane_hit_local = primCurW.ToFrameP(plane_hit);
            }
            else if (nStep == 1)
            {
                Vector3f plane_hit = primCurW.FromFrameP(plane_hit_local);
                Line3d   l         = new Line3d(plane_hit, primCurW.Y);
                fY = (float)DistLine3Ray3.MinDistanceLineParam(ray, l);
            }

            // figure out possible dimensions, clamp to ranges
            float planeX   = MathUtil.SignedClamp(plane_hit_local[0], MinDimension, MaxDimension);
            float planeZ   = MathUtil.SignedClamp(plane_hit_local[2], MinDimension, MaxDimension);
            float fR_plane = MathUtil.Clamp(plane_hit_local.Length, MinDimension / 2, MaxDimension / 2);

            fY = MathUtil.SignedClamp(fY, MinDimension, MaxDimension);

            // update frame
            primitive.Frame = primCurW;

            // update dimensions
            bool  bIsCorner = (primitive.Center == CenterModes.Corner);
            float fScale    = 1.0f;     // object is not in scene coordinates!

            if (primitive.Type == MeshPrimitivePreview.PrimType.Cylinder)
            {
                primitive.Width  = (bIsCorner) ? fR_plane * fScale : 2 * fR_plane * fScale;
                primitive.Depth  = primitive.Width;
                primitive.Height = fY * fScale;
            }
            else if (primitive.Type == MeshPrimitivePreview.PrimType.Box)
            {
                primitive.Width  = (bIsCorner) ? planeX * fScale : 2 * planeX * fScale;
                primitive.Depth  = (bIsCorner) ? planeZ * fScale : 2 * planeZ * fScale;
                primitive.Height = fY * fScale;
            }
            else if (primitive.Type == MeshPrimitivePreview.PrimType.Sphere)
            {
                primitive.Width  = (bIsCorner) ? fR_plane * fScale : 2 * fR_plane * fScale;
                primitive.Depth  = primitive.Width;
                primitive.Height = Mathf.Sign(fY) * primitive.Width;
            }
            else
            {
                throw new NotImplementedException("DrawPrimitivesTool.UpdateDraw_Ray - type not supported");
            }
        }
Esempio n. 8
0
        override public bool FindRayIntersection(Ray3f ray, out SORayHit hit)
        {
            hit = null;

            Ray     sceneRay = GetScene().ToSceneRay(ray);
            Frame3f frameL   = GetLocalFrame(CoordSpace.ObjectCoords);
            Ray     localRay = frameL.ToFrame(sceneRay);

            float sceneWidth = GetScene().ToSceneDimension(visibleWidth);

            AxisAlignedBox3d hitBox = localBounds;

            hitBox.Expand(sceneWidth * 0.5f);
            Bounds hitBounds = new Bounds((Vector3)hitBox.Center, (Vector3)hitBox.Diagonal);

            if (hitBounds.IntersectRay(localRay) == false)
            {
                return(false);
            }

            double rayHitT;

            if (CurveUtils.FindClosestRayIntersection(curve, sceneWidth * 0.5f, localRay, out rayHitT))
            {
                hit           = new SORayHit();
                hit.fHitDist  = (float)rayHitT;
                hit.hitPos    = localRay.GetPoint(hit.fHitDist);
                hit.hitPos    = GetScene().ToWorldP(frameL.FromFrameP(hit.hitPos));
                hit.hitNormal = Vector3.zero;
                hit.hitGO     = root;
                hit.hitSO     = this;
                return(true);
            }
            return(false);
        }
        private void AddRightMiter(TPrintVertex printVertex, ToolpathPreviewMesh mesh, ref Frame3f frameMiter, ref Frame3f frameSegBefore, ToolpathPreviewJoint joint)
        {
            double miterScaleFactor = GetMiterScaleFactor(ref frameMiter, ref frameSegBefore);

            joint.InRight = joint.OutRight = mesh.AddVertex(vertexFactory(printVertex,
                                                                          frameMiter.FromFrameP(DiamondCrossSection.Right(printVertex.Dimensions, miterScaleFactor)), brightnessMin));
        }
Esempio n. 10
0
        /// <summary>
        /// Set the position of the object frame for this SO without moving the mesh in the scene.
        /// The input frame is the new object frame. So, this is a frame "in scene coordinates" unless
        /// this object has a parent SceneObject (ie is not a child of Scene directly). In that case
        /// the frame needs to be specified relative to that SO. An easy way to do this is to via
        ///   obj_pivot = GetLocalFrame(Object).FromFrame( SceneTransforms.SceneToObject(pivot_in_scene) )
        /// TODO: specify frame coordpace as input argument?
        /// </summary>
        public void RepositionPivot(Frame3f objFrame)
        {
            //if (Parent is FScene == false)
            //    throw new NotSupportedException("DMeshSO.RepositionMeshFrame: have not tested this!");

            Frame3f curFrame = this.GetLocalFrame(CoordSpace.ObjectCoords);
            bool    bNormals = mesh.HasVertexNormals;

            // map vertices to new frame
            foreach (int vid in mesh.VertexIndices())
            {
                Vector3f v = (Vector3f)mesh.GetVertex(vid);
                v = curFrame.FromFrameP(ref v);
                v = objFrame.ToFrameP(ref v);
                mesh.SetVertex(vid, v);

                if (bNormals)
                {
                    Vector3f n = mesh.GetVertexNormal(vid);
                    n = curFrame.FromFrameV(ref n);
                    n = objFrame.ToFrameV(ref n);
                    mesh.SetVertexNormal(vid, n);
                }
            }

            // set new object frame
            SetLocalFrame(objFrame, CoordSpace.ObjectCoords);

            fast_mesh_update(bNormals, false);
            post_mesh_modified();
        }
        private void AddRightSquare(TPrintVertex printVertex, ToolpathPreviewMesh mesh, ref Frame3f frameSegBefore, ref Frame3f frameSegAfter, ToolpathPreviewJoint joint)
        {
            joint.InRight = mesh.AddVertex(vertexFactory(printVertex,
                                                         frameSegBefore.FromFrameP(DiamondCrossSection.Left(printVertex.Dimensions)), brightnessMin));

            joint.OutRight = mesh.AddVertex(vertexFactory(printVertex,
                                                          frameSegAfter.FromFrameP(DiamondCrossSection.Right(printVertex.Dimensions)), brightnessMin));
        }
        protected override void OnPointUpdated(ControlPoint pt, Frame3f prevFrameS, bool isFirst)
        {
            Vector3f basePt  = GetPointPosition(BasePointID, CoordSpace.SceneCoords).Origin;
            Vector3f frontPt = GetPointPosition(FrontPointID, CoordSpace.SceneCoords).Origin;
            Vector3f topPt   = GetPointPosition(TopPointID, CoordSpace.SceneCoords).Origin;

            lastTargetFrameS = TargetSO.GetLocalFrame(CoordSpace.SceneCoords);

            Frame3f previewFrameS = lastTargetFrameS;

            // position next to original object
            previewFrameS = previewFrameS.Translated(1.1f * (float)meshBounds.Width * Vector3f.AxisX);

            Vector3f upAxis = (topPt - basePt).Normalized;

            // construct a frame perp to upAxis at midpoint, and project original and current fw points
            Frame3f  upFrame = new Frame3f((topPt + basePt) * 0.5f, upAxis);
            Vector3f origFW  = upFrame.ProjectToPlane(initialFrontPt, 2);

            origFW = (origFW - upFrame.Origin).Normalized;
            Vector3f curFW = upFrame.ProjectToPlane(frontPt, 2);

            curFW = (curFW - upFrame.Origin).Normalized;
            //float angle = MathUtil.PlaneAngleSignedD(origFW, curFW, upAxis);

            start_forward_pt_S   = upFrame.FromFrameP(origFW);
            current_forward_pt_S = upFrame.FromFrameP(curFW);

            // construct rotation that aligns up axis with y-up
            Quaternionf upRotate = Quaternionf.FromTo(upAxis, Vector3f.AxisY);

            previewFrameS.Rotate(upRotate);

            // now rotate so that forward dir points along -Z
            //Quaternionf fwRotate = Quaternionf.AxisAngleD(Vector3f.AxisY, angle);
            //curFW = upRotate * curFW;
            Quaternionf fwRotate = Quaternionf.FromToConstrained(curFW, -Vector3f.AxisZ, Vector3f.AxisY);

            previewFrameS.Rotate(fwRotate);

            previewSO.SetLocalFrame(previewFrameS, CoordSpace.SceneCoords);
            lastPreviewFrameS = previewFrameS;
        }
Esempio n. 13
0
        private void update_axis_vertices(PolyCurveSO curveSO)
        {
            Vector3d[] verticesS   = axisCurveSO.Curve.Vertices.ToArray();
            Frame3f    curveFrameS = axisCurveSO.GetLocalFrame(CoordSpace.SceneCoords);

            for (int k = 0; k < verticesS.Length; ++k)
            {
                verticesS[k] = curveFrameS.FromFrameP((Vector3f)verticesS[k]);
            }
            axisCurve.SetVertices(verticesS);
        }
        private void AddCapBeforeJoint(Vector3d segmentDirection, TPrintVertex printVertex, ToolpathPreviewJoint joint, ToolpathPreviewMesh mesh)
        {
            var frame = new Frame3f(printVertex.Position);

            frame.AlignAxis(1, ToVector3f(segmentDirection));

            joint.InTop = mesh.AddVertex(vertexFactory(printVertex,
                                                       frame.FromFrameP(DiamondCrossSection.Top(printVertex.Dimensions)), brightnessMax));

            joint.InRight = mesh.AddVertex(vertexFactory(printVertex,
                                                         frame.FromFrameP(DiamondCrossSection.Right(printVertex.Dimensions)), brightnessMin));

            joint.InBottom = mesh.AddVertex(vertexFactory(printVertex,
                                                          frame.FromFrameP(DiamondCrossSection.Bottom(printVertex.Dimensions)), brightnessMax));

            joint.InLeft = mesh.AddVertex(vertexFactory(printVertex,
                                                        frame.FromFrameP(DiamondCrossSection.Left(printVertex.Dimensions)), brightnessMin));

            mesh.AddTriangle(joint.InBottom, joint.InLeft, joint.InTop);
            mesh.AddTriangle(joint.InBottom, joint.InTop, joint.InRight);
        }
Esempio n. 15
0
        public static void ScaleMesh(NGonsCore.geometry3Sharp.mesh.DMesh3 mesh, Frame3f f, Vector3F vScale)
        {
            foreach (int vid in mesh.VertexIndices())
            {
                Vector3D v          = mesh.GetVertex(vid);
                Vector3F vScaledInF = f.ToFrameP((Vector3F)v) * vScale;
                Vector3D vNew       = f.FromFrameP(vScaledInF);
                mesh.SetVertex(vid, vNew);

                // TODO: normals
            }
        }
Esempio n. 16
0
        public static void AppendMeshSO(DMeshSO appendTo, DMeshSO append)
        {
            FScene scene = appendTo.GetScene();

            if (scene.IsSelected(appendTo))
            {
                scene.Deselect(appendTo);
            }
            if (scene.IsSelected(append))
            {
                scene.Deselect(append);
            }

            Frame3f  f1     = appendTo.GetLocalFrame(CoordSpace.ObjectCoords);
            Vector3f scale1 = appendTo.GetLocalScale();
            Frame3f  f2     = append.GetLocalFrame(CoordSpace.ObjectCoords);
            Vector3f scale2 = append.GetLocalScale();

            DMesh3 mesh1 = appendTo.Mesh;

            DMesh3 mesh2 = append.Mesh;

            foreach (int vid in mesh2.VertexIndices())
            {
                // convert point in mesh2 to scene coords
                Vector3f v2 = (Vector3f)mesh2.GetVertex(vid);
                v2 *= scale2;
                Vector3f v2s = f2.FromFrameP(v2);

                // transfer that scene coord into local coords of mesh1
                Vector3f v2in1 = f1.ToFrameP(v2s);
                v2in1 /= scale1;
                mesh2.SetVertex(vid, v2in1);

                if (mesh1.HasVertexNormals && mesh2.HasVertexNormals)
                {
                    Vector3f n   = mesh2.GetVertexNormal(vid);
                    Vector3f ns  = f2.FromFrameV(n);
                    Vector3f ns2 = f1.ToFrameV(ns);
                    mesh2.SetVertexNormal(vid, ns2);
                }
            }

            MeshEditor editor = new MeshEditor(mesh1);

            editor.AppendMesh(mesh2);

            appendTo.NotifyMeshEdited();

            // [TODO] change record!

            scene.RemoveSceneObject(append, false);
        }
Esempio n. 17
0
        public static void FromFrame(IDeformableMesh mesh, Frame3f f)
        {
            int  NV          = mesh.MaxVertexID;
            bool bHasNormals = mesh.HasVertexNormals;

            for (int vid = 0; vid < NV; ++vid)
            {
                if (mesh.IsVertex(vid))
                {
                    Vector3D vf = mesh.GetVertex(vid);
                    Vector3D v  = f.FromFrameP((Vector3F)vf);
                    mesh.SetVertex(vid, v);
                    if (bHasNormals)
                    {
                        Vector3F n  = mesh.GetVertexNormal(vid);
                        Vector3F nf = f.FromFrameV(n);
                        mesh.SetVertexNormal(vid, nf);
                    }
                }
            }
        }
Esempio n. 18
0
        public DMeshSO BuildSO(FScene scene, SOMaterial material)
        {
            DMesh3 revolveMesh = UnityUtil.UnityMeshToDMesh(meshObject.GetSharedMesh(), false);

            // move axis frame to center of bbox of mesh, measured in axis frame
            Frame3f          useF          = OutputFrame;
            AxisAlignedBox3f boundsInFrame = (AxisAlignedBox3f)BoundsUtil.BoundsInFrame(revolveMesh.Vertices(), useF);

            useF.Origin = useF.FromFrameP(boundsInFrame.Center);

            // transform mesh into this frame
            MeshTransforms.ToFrame(revolveMesh, useF);

            // create new so
            DMeshSO meshSO = new DMeshSO();

            meshSO.Create(revolveMesh, material);
            meshSO.SetLocalFrame(useF, CoordSpace.ObjectCoords);

            return(meshSO);
        }
Esempio n. 19
0
        /// <summary>
        /// input objectF is in Object (local) coords of so, apply all intermediate
        /// transforms to get it to Scene coords
        /// </summary>
        public static Vector3f ObjectToSceneP(SceneObject so, Vector3f objectPt)
        {
            SceneObject curSO = so;

            while (curSO != null)
            {
                Frame3f  curF  = curSO.GetLocalFrame(CoordSpace.ObjectCoords);
                Vector3f scale = curSO.GetLocalScale();
                objectPt = curF.FromFrameP(objectPt * scale);
                SOParent parent = curSO.Parent;
                if (parent is FScene)
                {
                    return(objectPt);
                }
                curSO = (parent as SceneObject);
            }
            if (curSO == null)
            {
                DebugUtil.Error("SceneTransforms.ObjectToSceneP: found null parent SO!");
            }
            return(objectPt);
        }
Esempio n. 20
0
        // returns max edge length of moved vertices, after deformation
        public override DeformInfo Apply(Frame3f vNextPos)
        {
            // if we did not move brush far enough, don't do anything
            Vector3D vDelta = (vNextPos.Origin - vPreviousPos.Origin);

            if (vDelta.Length < 0.0001f)
            {
                return new DeformInfo()
                       {
                           maxEdgeLenSqr = 0, minEdgeLenSqr = double.MaxValue
                       }
            }
            ;

            // otherwise apply base deformation
            DeformF = (idx, t) => {
                Vector3D v = vPreviousPos.ToFrameP(Curve[idx]);

                Vector3D vNew = vNextPos.FromFrameP(v);
                return(Vector3D.Lerp(Curve[idx], vNew, t));
            };
            return(base.Apply(vNextPos));
        }
    }
Esempio n. 21
0
        /// <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();
        }
Esempio n. 22
0
        public Vector3D FromGrid(Vector3i gridpoint)
        {
            Vector3F pointf = CellSize * (Vector3F)gridpoint;

            return((Vector3D)GridFrame.FromFrameP(pointf));
        }
Esempio n. 23
0
        public override void Generate()
        {
            int nRings       = Curve.Length;
            int nRingSize    = (NoSharedVertices) ? Slices + 1 : Slices;
            int nCapVertices = (NoSharedVertices) ? Slices + 1 : 1;

            if (Capped == false)
            {
                nCapVertices = 0;
            }

            vertices = new VectorArray3d(nRingSize * nRings + 2 * nCapVertices);
            uv       = new VectorArray2f(vertices.Count);
            normals  = new VectorArray3f(vertices.Count);

            int nSpanTris = (nRings - 1) * (2 * Slices);
            int nCapTris  = (Capped) ? 2 * Slices : 0;

            triangles = new IndexArray3i(nSpanTris + nCapTris);

            float fDelta = (float)((Math.PI * 2.0) / Slices);

            Frame3f f = Axis;

            // generate tube
            for (int ri = 0; ri < nRings; ++ri)
            {
                Vector3D v_along  = Curve[ri];
                Vector3F v_frame  = f.ToFrameP((Vector3F)v_along);
                float    uv_along = (float)ri / (float)(nRings - 1);

                // generate vertices
                int nStartR = ri * nRingSize;
                for (int j = 0; j < nRingSize; ++j)
                {
                    float angle = (float)j * fDelta;

                    // [TODO] this is not efficient...use Matrix3f?
                    Vector3F v_rot = Quaternionf.AxisAngleR(Vector3F.AxisY, angle) * v_frame;
                    Vector3D v_new = f.FromFrameP(v_rot);
                    int      k     = nStartR + j;
                    vertices[k] = v_new;

                    float uv_around = (float)j / (float)(nRingSize);
                    uv[k] = new Vector2F(uv_along, uv_around);

                    // [TODO] proper normal
                    Vector3F n = (Vector3F)(v_new - f.Origin).Normalized;
                    normals[k] = n;
                }
            }


            // generate triangles
            int ti = 0;

            for (int ri = 0; ri < nRings - 1; ++ri)
            {
                int r0 = ri * nRingSize;
                int r1 = r0 + nRingSize;
                for (int k = 0; k < nRingSize - 1; ++k)
                {
                    triangles.Set(ti++, r0 + k, r0 + k + 1, r1 + k + 1, Clockwise);
                    triangles.Set(ti++, r0 + k, r1 + k + 1, r1 + k, Clockwise);
                }
                if (NoSharedVertices == false)        // close disc if we went all the way
                {
                    triangles.Set(ti++, r1 - 1, r0, r1, Clockwise);
                    triangles.Set(ti++, r1 - 1, r1, r1 + nRingSize - 1, Clockwise);
                }
            }



            if (Capped)
            {
                // find avg start loop size
                Vector3D vAvgStart = Vector3D.Zero, vAvgEnd = Vector3D.Zero;
                for (int k = 0; k < Slices; ++k)
                {
                    vAvgStart += vertices[k];
                    vAvgEnd   += vertices[(nRings - 1) * nRingSize + k];
                }
                vAvgStart /= (double)Slices;
                vAvgEnd   /= (double)Slices;

                Frame3f fStart = f;
                fStart.Origin = (Vector3F)vAvgStart;
                Frame3f fEnd = f;
                fEnd.Origin = (Vector3F)vAvgEnd;



                // add endcap verts
                int nBottomC = nRings * nRingSize;
                vertices[nBottomC]  = fStart.Origin;
                uv[nBottomC]        = new Vector2F(0.5f, 0.5f);
                normals[nBottomC]   = -fStart.Z;
                startCapCenterIndex = nBottomC;

                int nTopC = nBottomC + 1;
                vertices[nTopC]   = fEnd.Origin;
                uv[nTopC]         = new Vector2F(0.5f, 0.5f);
                normals[nTopC]    = fEnd.Z;
                endCapCenterIndex = nTopC;

                if (NoSharedVertices)
                {
                    // duplicate first loop and make a fan w/ bottom-center
                    int nExistingB = 0;
                    int nStartB    = nTopC + 1;
                    for (int k = 0; k < Slices; ++k)
                    {
                        vertices[nStartB + k] = vertices[nExistingB + k];
                        //uv[nStartB + k] = (Vector2f)Polygon.Vertices[k].Normalized;

                        float  angle = (float)k * fDelta;
                        double cosa = Math.Cos(angle), sina = Math.Sin(angle);
                        uv[nStartB + k] = new Vector2F(0.5f * (1.0f + cosa), 0.5f * (1 + sina));

                        normals[nStartB + k] = normals[nBottomC];
                    }
                    append_disc(Slices, nBottomC, nStartB, true, Clockwise, ref ti);

                    // duplicate second loop and make fan
                    int nExistingT = nRingSize * (nRings - 1);
                    int nStartT    = nStartB + Slices;
                    for (int k = 0; k < Slices; ++k)
                    {
                        vertices[nStartT + k] = vertices[nExistingT + k];
                        //uv[nStartT + k] = (Vector2f)Polygon.Vertices[k].Normalized;

                        float  angle = (float)k * fDelta;
                        double cosa = Math.Cos(angle), sina = Math.Sin(angle);
                        uv[nStartT + k] = new Vector2F(0.5f * (1.0f + cosa), 0.5f * (1 + sina));


                        normals[nStartT + k] = normals[nTopC];
                    }
                    append_disc(Slices, nTopC, nStartT, true, !Clockwise, ref ti);
                }
                else
                {
                    append_disc(Slices, nBottomC, 0, true, Clockwise, ref ti);
                    append_disc(Slices, nTopC, nRingSize * (nRings - 1), true, !Clockwise, ref ti);
                }
            }
        }
Esempio n. 24
0
        // [TODO] projection pass
        //   - only project vertices modified by smooth pass?
        //   - and/or verts in set of modified edges?
        protected virtual void TrackedFaceProjectionPass()
        {
            IOrientedProjectionTarget normalTarget = ProjectionTarget as IOrientedProjectionTarget;

            if (normalTarget == null)
            {
                throw new Exception("RemesherPro.TrackedFaceProjectionPass: projection target does not have normals!");
            }

            InitializeBuffersForFacePass();

            SpinLock buffer_lock = new SpinLock();

            // this function computes rotated position of triangle, such that it
            // aligns with face normal on target surface. We accumulate weighted-average
            // of vertex positions, which we will then use further down where possible.
            Action <int> process_triangle = (tid) => {
                Vector3d normal; double area; Vector3d centroid;
                mesh.GetTriInfo(tid, out normal, out area, out centroid);

                Vector3d projNormal;
                Vector3d projPos = normalTarget.Project(centroid, out projNormal);

                Index3i  tv = mesh.GetTriangle(tid);
                Vector3d v0 = mesh.GetVertex(tv.a), v1 = mesh.GetVertex(tv.b), v2 = mesh.GetVertex(tv.c);

                // ugh could probably do this more efficiently...
                Frame3f triF = new Frame3f(centroid, normal);
                v0 = triF.ToFrameP(ref v0); v1 = triF.ToFrameP(ref v1); v2 = triF.ToFrameP(ref v2);
                triF.AlignAxis(2, (Vector3f)projNormal);
                triF.Origin = (Vector3f)projPos;
                v0          = triF.FromFrameP(ref v0); v1 = triF.FromFrameP(ref v1); v2 = triF.FromFrameP(ref v2);

                double dot = normal.Dot(projNormal);
                dot = MathUtil.Clamp(dot, 0, 1.0);
                double w = area * (dot * dot * dot);

                bool taken = false;
                buffer_lock.Enter(ref taken);
                vBufferV[tv.a] += w * v0; vBufferVWeights[tv.a] += w;
                vBufferV[tv.b] += w * v1; vBufferVWeights[tv.b] += w;
                vBufferV[tv.c] += w * v2; vBufferVWeights[tv.c] += w;
                buffer_lock.Exit();
            };

            // compute face-aligned vertex positions
            gParallel.ForEach(mesh.TriangleIndices(), process_triangle);


            // ok now we filter out all the positions we can't change, as well as vertices that
            // did not actually move. We also queue any edges that moved far enough to fall
            // under min/max edge length thresholds
            gParallel.ForEach(mesh.VertexIndices(), (vID) => {
                vModifiedV[vID] = false;
                if (vBufferVWeights[vID] < MathUtil.ZeroTolerance)
                {
                    return;
                }
                if (vertex_is_constrained(vID))
                {
                    return;
                }
                if (VertexControlF != null && (VertexControlF(vID) & VertexControl.NoProject) != 0)
                {
                    return;
                }

                Vector3d curpos  = mesh.GetVertex(vID);
                Vector3d projPos = vBufferV[vID] / vBufferVWeights[vID];
                if (curpos.EpsilonEqual(projPos, MathUtil.ZeroTolerancef))
                {
                    return;
                }

                vModifiedV[vID] = true;
                vBufferV[vID]   = projPos;

                foreach (int eid in mesh.VtxEdgesItr(vID))
                {
                    Index2i ev      = Mesh.GetEdgeV(eid);
                    int othervid    = (ev.a == vID) ? ev.b : ev.a;
                    Vector3d otherv = mesh.GetVertex(othervid);
                    double old_len  = curpos.Distance(otherv);
                    double new_len  = projPos.Distance(otherv);
                    if (new_len < MinEdgeLength || new_len > MaxEdgeLength)
                    {
                        queue_edge_safe(eid);
                    }
                }
            });


            // update vertices
            ApplyVertexBuffer(true);
        }
Esempio n. 25
0
        override public void Generate()
        {
            if (Polygon == null)
            {
                Polygon = Polygon2d.MakeCircle(1.0f, 8);
            }

            int Slices       = Polygon.VertexCount;
            int nRings       = Vertices.Count;
            int nRingSize    = (NoSharedVertices) ? Slices + 1 : Slices;
            int nCapVertices = (NoSharedVertices) ? Slices + 1 : 1;

            if (Capped == false)
            {
                nCapVertices = 0;
            }

            vertices = new VectorArray3d(nRings * nRingSize + 2 * nCapVertices);
            uv       = new VectorArray2f(vertices.Count);
            normals  = new VectorArray3f(vertices.Count);

            int nSpanTris = (Vertices.Count - 1) * (2 * Slices);
            int nCapTris  = (Capped) ? 2 * Slices : 0;

            triangles = new IndexArray3i(nSpanTris + nCapTris);

            Frame3f  fCur = new Frame3f(Frame);
            Vector3D dv   = CurveUtils.GetTangent(Vertices, 0);;

            fCur.Origin = (Vector3F)Vertices[0];
            fCur.AlignAxis(2, (Vector3F)dv);
            Frame3f fStart = new Frame3f(fCur);

            // generate tube
            for (int ri = 0; ri < nRings; ++ri)
            {
                // propagate frame
                if (ri != 0)
                {
                    Vector3D tan = CurveUtils.GetTangent(Vertices, ri);
                    fCur.Origin = (Vector3F)Vertices[ri];
                    if (ri == 11)
                    {
                        dv = tan;
                    }
                    fCur.AlignAxis(2, (Vector3F)tan);
                }

                float uv_along = (float)ri / (float)(nRings - 1);

                // generate vertices
                int nStartR = ri * nRingSize;
                for (int j = 0; j < nRingSize; ++j)
                {
                    float uv_around = (float)j / (float)(nRings);

                    int      k  = nStartR + j;
                    Vector2D pv = Polygon.Vertices[j % Slices];
                    Vector3D v  = fCur.FromFrameP((Vector2F)pv, 2);
                    vertices[k] = v;
                    uv[k]       = new Vector2F(uv_along, uv_around);
                    Vector3F n = (Vector3F)(v - fCur.Origin).Normalized;
                    normals[k] = n;
                }
            }


            // generate triangles
            int ti = 0;

            for (int ri = 0; ri < nRings - 1; ++ri)
            {
                int r0 = ri * nRingSize;
                int r1 = r0 + nRingSize;
                for (int k = 0; k < nRingSize - 1; ++k)
                {
                    triangles.Set(ti++, r0 + k, r0 + k + 1, r1 + k + 1, Clockwise);
                    triangles.Set(ti++, r0 + k, r1 + k + 1, r1 + k, Clockwise);
                }
                if (NoSharedVertices == false)        // close disc if we went all the way
                {
                    triangles.Set(ti++, r1 - 1, r0, r1, Clockwise);
                    triangles.Set(ti++, r1 - 1, r1, r1 + nRingSize - 1, Clockwise);
                }
            }

            if (Capped)
            {
                // add endcap verts
                int nBottomC = nRings * nRingSize;
                vertices[nBottomC]  = fStart.Origin;
                uv[nBottomC]        = new Vector2F(0.5f, 0.5f);
                normals[nBottomC]   = -fStart.Z;
                startCapCenterIndex = nBottomC;

                int nTopC = nBottomC + 1;
                vertices[nTopC]   = fCur.Origin;
                uv[nTopC]         = new Vector2F(0.5f, 0.5f);
                normals[nTopC]    = fCur.Z;
                endCapCenterIndex = nTopC;

                if (NoSharedVertices)
                {
                    // duplicate first loop and make a fan w/ bottom-center
                    int nExistingB = 0;
                    int nStartB    = nTopC + 1;
                    for (int k = 0; k < Slices; ++k)
                    {
                        vertices[nStartB + k] = vertices[nExistingB + k];
                        uv[nStartB + k]       = (Vector2F)Polygon.Vertices[k].Normalized;
                        normals[nStartB + k]  = normals[nBottomC];
                    }
                    append_disc(Slices, nBottomC, nStartB, true, Clockwise, ref ti);

                    // duplicate second loop and make fan
                    int nExistingT = nRingSize * (nRings - 1);
                    int nStartT    = nStartB + Slices;
                    for (int k = 0; k < Slices; ++k)
                    {
                        vertices[nStartT + k] = vertices[nExistingT + k];
                        uv[nStartT + k]       = (Vector2F)Polygon.Vertices[k].Normalized;
                        normals[nStartT + k]  = normals[nTopC];
                    }
                    append_disc(Slices, nTopC, nStartT, true, !Clockwise, ref ti);
                }
                else
                {
                    append_disc(Slices, nBottomC, 0, true, Clockwise, ref ti);
                    append_disc(Slices, nTopC, nRingSize * (nRings - 1), true, !Clockwise, ref ti);
                }
            }
        }
Esempio n. 26
0
        public void UpdateDraw_Spatial(Ray3f ray, Frame3f handFrame, int nStep)
        {
            // scene xform may have changed during steps (eg view rotation), so we
            // need to reconstruct our local frame
            Frame3f primCurW = scene.ToWorldFrame(primStartS);

            // try snap points
            SnapResult snap      = Snaps.FindHitSnapPoint(ray);
            bool       bHaveSnap = (snap != null);
            Frame3f    snapF     = (bHaveSnap) ? scene.ToWorldFrame(snap.FrameS) : Frame3f.Identity;

            // step 1: find radius in plane
            if (nStep == 0)
            {
                if (bHaveSnap)
                {
                    plane_hit_local = primCurW.ToFrameP(
                        primCurW.ProjectToPlane(snapF.Origin, 1));
                }
                else
                {
                    Vector3f forwardDir = ray.Direction;
                    Vector3f plane_hit  = VRUtil.SafeRayPlaneIntersection(ray, forwardDir, primCurW.Origin, primCurW.Y);
                    plane_hit_local = primCurW.ToFrameP(plane_hit);
                }
            }
            float fX       = MathUtil.SignedClamp(plane_hit_local[0], MinDimension, MaxDimension);
            float fY       = MinDimension;
            float fZ       = MathUtil.SignedClamp(plane_hit_local[2], MinDimension, MaxDimension);
            float fR_plane = MathUtil.Clamp(plane_hit_local.Length, MinDimension / 2, MaxDimension / 2);

            // step 2: find height from plane
            if (nStep == 1)
            {
                Vector3f plane_hit = primCurW.FromFrameP(plane_hit_local);
                Line3d   l         = new Line3d(plane_hit, primCurW.Y);
                if (bHaveSnap)
                {
                    fY = (float)l.Project(snapF.Origin);
                }
                else
                {
                    Vector3f handTip   = handFrame.Origin + SceneGraphConfig.HandTipOffset * handFrame.Z;
                    float    fHandDist = (float)l.DistanceSquared(handTip);
                    if (fHandDist < fR_plane * 1.5f)
                    {
                        fY = (float)l.Project(handTip);
                    }
                    else
                    {
                        fY = (float)DistLine3Ray3.MinDistanceLineParam(ray, l);
                    }
                }
            }

            // figure out possible dimensions, clamp to ranges
            fY = MathUtil.SignedClamp(fY, MinDimension, MaxDimension);

            // update frame
            primitive.Frame = primCurW;

            // update dimensions
            bool  bIsCorner = (primitive.Center == CenterModes.Corner);
            float fScale    = 1.0f;     // object is not in scene coordinates!

            if (primitive.Type == MeshPrimitivePreview.PrimType.Cylinder)
            {
                primitive.Width = (bIsCorner) ? fR_plane * fScale : 2 * fR_plane * fScale;
                primitive.Depth = primitive.Width;
                //primitive.Depth = Mathf.Sign(fZ) * primitive.Width;
                //primitive.Width = Mathf.Sign(fX) * primitive.Width;
                primitive.Height = fY * fScale;
            }
            else if (primitive.Type == MeshPrimitivePreview.PrimType.Box)
            {
                primitive.Width  = (bIsCorner) ? fX : 2 * fX * fScale;
                primitive.Depth  = (bIsCorner) ? fZ : 2 * fZ * fScale;
                primitive.Height = fY * fScale;
            }
            else if (primitive.Type == MeshPrimitivePreview.PrimType.Sphere)
            {
                primitive.Width = (bIsCorner) ? fR_plane * fScale : 2 * fR_plane * fScale;
                primitive.Depth = primitive.Height = primitive.Width;
                //primitive.Depth = Mathf.Sign(fZ) * primitive.Width;
                //primitive.Width = Mathf.Sign(fX) * primitive.Width;
                //primitive.Height = Mathf.Sign(fY) * primitive.Width;
            }
            else
            {
                throw new NotImplementedException("SnapDrawPrimitivesTool.UpdateDraw_Ray - type not supported");
            }
        }