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);
        }
示例#2
0
        public static void SetBasePoint(FScene scene, DMeshSO so, Frame3f baseFrameS, bool bInteractive)
        {
            Frame3f curFrameS = so.GetLocalFrame(CoordSpace.SceneCoords);
            Frame3f relFrameS = baseFrameS.ToFrame(curFrameS);

            baseFrameS.AlignAxis(2, -Vector3f.AxisY);
            baseFrameS.Translate(-baseFrameS.Origin);

            Frame3f           newFrameS = baseFrameS.FromFrame(relFrameS);
            TransformSOChange change    = new TransformSOChange(so, curFrameS, newFrameS, CoordSpace.SceneCoords);

            change.Tags.Add("SetBasePoint");
            scene.History.PushChange(change, false);

            Frame3f pivotS = Frame3f.Identity;
            // WHAT why is it the scene pivot ?!
            //Frame3f pivotL = SceneTransforms.SceneToObject(so, pivotS);
            RepositionPivotChangeOp pivotChange = new RepositionPivotChangeOp(pivotS, so);

            scene.History.PushChange(pivotChange, false);

            if (bInteractive)
            {
                scene.History.PushInteractionCheckpoint();
            }
        }
示例#3
0
        public virtual void Setup()
        {
            // turn on xform gizmo
            Scene.Context.TransformManager.PushOverrideGizmoType(BendPlanePivotGizmo.DefaultTypeName);


            Vector3d ctrPt    = TargetSO.Mesh.CachedBounds.Center;
            Frame3f  nearestF = MeshQueries.NearestPointFrame(TargetSO.Mesh, TargetSO.Spatial, ctrPt, true);

            BendPlaneOriginS = SceneTransforms.ObjectToSceneP(TargetSO, nearestF.Origin);
            BendPlaneNormalS = Vector3d.AxisY;

            bendPlaneGizmoSO = new BendPlanePivotSO();
            bendPlaneGizmoSO.Create(Scene.PivotSOMaterial, Scene.FrameSOMaterial);
            bendPlaneGizmoSO.OnTransformModified += OnBendPlaneTransformModified;
            Scene.AddSceneObject(bendPlaneGizmoSO);

            Frame3f cutFrameS = new Frame3f(BendPlaneOriginS); cutFrameS.AlignAxis(1, (Vector3f)BendPlaneNormalS);

            bendPlaneGizmoSO.SetLocalFrame(cutFrameS, CoordSpace.SceneCoords);

            allow_selection_changes = true;
            Scene.Select(bendPlaneGizmoSO, true);
            allow_selection_changes = false;


            StandardIndicatorFactory factory   = new StandardIndicatorFactory();
            SectionPlaneIndicator    bendPlane = factory.MakeSectionPlaneIndicator(
                100, "bendPlane",
                fDimension.Scene(100),
                () => { return(new Frame3f(BendPlaneOriginS, BendPlaneNormalS)); },
                () => { return(new Colorf(Colorf.LightGreen, 0.5f)); },
                () => { return(true); }
                );

            Indicators.AddIndicator(bendPlane);

            // save initial vtx positions
            VertexPositions = new Vector3d[TargetSO.Mesh.MaxVertexID];
            foreach (int vid in TargetSO.Mesh.VertexIndices())
            {
                VertexPositions[vid] = TargetSO.Mesh.GetVertex(vid);
            }

            PreviewSO = TargetSO.Duplicate() as DMeshSO;
            Scene.AddSceneObject(PreviewSO);
            //PreviewSO.AssignSOMaterial(Scene.TransparentNewSOMaterial);

            fMaterial transMat = MaterialUtil.CreateTransparentMaterial(Colorf.BlueMetal.SetAlpha(0.1f));

            TargetSO.PushOverrideMaterial(transMat);
            TargetSO.SetLayer(FPlatform.WidgetOverlayLayer);
        }
        private static void CreateFrames(Segment3d segmentBefore, Segment3d segmentAfter, out Frame3f frameMiter, out Frame3f frameSegBefore, out Frame3f frameSegAfter)
        {
            var averageDirection = (segmentBefore.Direction + segmentAfter.Direction).Normalized;

            frameMiter = new Frame3f(segmentBefore.P1);
            frameMiter.AlignAxis(1, ToVector3f(averageDirection));

            frameSegBefore = new Frame3f(segmentBefore.P1);
            frameSegBefore.AlignAxis(1, ToVector3f(segmentBefore.Direction));

            frameSegAfter = new Frame3f(segmentBefore.P1);
            frameSegAfter.AlignAxis(1, ToVector3f(segmentAfter.Direction));
        }
示例#5
0
        DMesh3 compute_partial_hole(Vector3d start, Vector3d end, double tol)
        {
            DMesh3         origMesh    = MeshSource.GetDMeshUnsafe();
            DMeshAABBTree3 origSpatial = MeshSource.GetSpatial() as DMeshAABBTree3;

            DMesh3 cutMesh = new DMesh3(origMesh);

            Polygon2d polygon = Polygon2d.MakeCircle(hole_size / 2, hole_subdivisions);

            Vector3f axis = (Vector3f)(start - end).Normalized;

            int     start_tid   = origSpatial.FindNearestTriangle(start);
            Frame3f start_frame = origMesh.GetTriFrame(start_tid);

            start_frame.Origin = (Vector3f)start;
            start_frame.AlignAxis(2, axis);

            int end_tid = origSpatial.FindNearestTriangle(end);
            //Frame3f end_frame = origMesh.GetTriFrame(end_tid); end_frame.Origin = (Vector3f)end;
            Frame3f end_frame = start_frame; end_frame.Origin = (Vector3f)end;

            // [TODO] we don't need to Simplify here...is more robust?

            MeshInsertProjectedPolygon start_insert = new MeshInsertProjectedPolygon(cutMesh, polygon, start_frame, start_tid);
            bool start_ok = start_insert.Insert();

            if (start_ok == false)
            {
                throw new Exception("CutPolygonHoleOp.compute_partial_hole: start or end insertion failed!");
            }

            EdgeLoop outLoop = start_insert.InsertedLoop;

            MeshExtrudeLoop extrude = new MeshExtrudeLoop(cutMesh, outLoop);

            extrude.PositionF = (v, n, vid) => {
                cutMesh.GetVertex(vid);
                return(end_frame.ProjectToPlane((Vector3f)v, 2));
            };
            extrude.Extrude();

            SimpleHoleFiller filler = new SimpleHoleFiller(cutMesh, extrude.NewLoop);

            filler.Fill();

            return(cutMesh);
        }
示例#6
0
        public fGraph(DCurve3 curve, bool bInitializeFrames, IList <Colorf> colors = null, IList <float> sizes = null)
        {
            graph = new Mesh();

            int NV = curve.VertexCount;

            Vector3[] verts   = new Vector3[NV];
            int[]     indices = new int[NV * 2];
            for (int i = 0; i < curve.VertexCount; ++i)
            {
                indices[2 * i]     = i;
                indices[2 * i + 1] = (i + 1) % NV;
                verts[i]           = (Vector3)curve[i];
            }
            graph.vertices = verts;

            if (bInitializeFrames)
            {
                Vector3[] normals  = new Vector3[NV];
                Vector4[] tangents = new Vector4[NV];

                Frame3f vf = new Frame3f(curve[0], curve.Tangent(0));
                for (int i = 0; i < curve.VertexCount; ++i)
                {
                    Vector3d tan = curve.Tangent(i);
                    vf.AlignAxis(2, (Vector3f)tan);
                    normals[i] = vf.X;
                    float s = (sizes == null) ? 1.0f : sizes[i];
                    tangents[i] = new Vector4(vf.Y.x, vf.Y.y, vf.Y.z, s);
                }

                graph.normals  = normals;
                graph.tangents = tangents;
            }

            if (colors != null)
            {
                Color[] ucolors = new Color[NV];
                for (int i = 0; i < curve.VertexCount; ++i)
                {
                    ucolors[i] = colors[i];
                }
                graph.colors = ucolors;
            }

            graph.SetIndices(indices, MeshTopology.Lines, 0);
        }
示例#7
0
        public void SetPlaneFromSingleClick(Frame3f worldF, bool bShiftDown)
        {
            Frame3f sceneF = Scene.ToSceneFrame(worldF);

            if (bShiftDown == false)
            {
                sceneF.AlignAxis(2, Vector3f.AxisY);
            }
            TransformSOChange change = new TransformSOChange(gizmoSO, sceneF, CoordSpace.SceneCoords);

            Scene.History.PushChange(change, false);
            Scene.History.PushInteractionCheckpoint();
            if (end_on_set)
            {
                EndSetPlaneFromSingleClick();
            }
        }
示例#8
0
        void update_position(AnyRayHit hit)
        {
            int nNormalAxis = 1;
            int nUpAxis     = 2;

            // as we drag object we will align Y with hit surface normal, but
            // we also want to constrain rotation so it is stable. Hence, we are
            // going to use world or local frame of target object to stabilize
            // rotation around normal.
            Frame3f hitF       = TargetScene.SceneFrame;
            Vector3 targetAxis = hitF.GetAxis(1);

            if (hit.hitSO is SceneObject)
            {
                hitF = (hit.hitSO as SceneObject).GetLocalFrame(CoordSpace.WorldCoords);
            }
            bool bUseLocal =
                (TargetScene.Context.TransformManager.ActiveFrameType == FrameType.LocalFrame);

            if (bUseLocal && hit.hitSO is SceneObject)
            {
                hitF       = (hit.hitSO as SceneObject).GetLocalFrame(CoordSpace.WorldCoords);
                targetAxis = hitF.GetAxis(1);
            }
            // if normal is parallel to target, this would become unstable, so use another axis
            if (Vector3.Dot(targetAxis, hit.hitNormal) > 0.99f)
            {
                targetAxis = hitF.GetAxis(0);
            }

            if (lastHitObject == null || hit.hitSO != lastHitObject)
            {
                lastHitF = new Frame3f(hit.hitPos, hit.hitNormal, nNormalAxis);
                lastHitF.ConstrainedAlignAxis(nUpAxis, targetAxis, lastHitF.GetAxis(nNormalAxis));
            }
            else
            {
                lastHitF.Origin = hit.hitPos;
                lastHitF.AlignAxis(nNormalAxis, hit.hitNormal);
                lastHitF.ConstrainedAlignAxis(nUpAxis, targetAxis, lastHitF.GetAxis(nNormalAxis));
            }
            lastHitObject = hit.hitSO;
        }
        public override bool UpdateCapture(ITransformable target, Ray3f worldRay)
        {
            Func <SceneObject, bool> FilterF = (so) => {
                return(this.ConstraintSurfaces.Contains(so));
            };

            SORayHit hit;

            if (Scene.FindSORayIntersection(worldRay, out hit, FilterF))
            {
                CurrentConstraintSO = hit.hitSO;
                Frame3f f = SourceSO.GetLocalFrame(CoordSpace.WorldCoords);
                f.Origin = hit.hitPos;
                f.AlignAxis(2, hit.hitNormal);
                SourceSO.SetLocalFrame(f, CoordSpace.WorldCoords);
            }

            return(true);
        }
示例#10
0
        DMesh3 compute_through_hole(Vector3d start, Vector3d end, double tol)
        {
            DMesh3         origMesh    = MeshSource.GetDMeshUnsafe();
            DMeshAABBTree3 origSpatial = MeshSource.GetSpatial() as DMeshAABBTree3;

            DMesh3 cutMesh = new DMesh3(origMesh);

            Polygon2d polygon = Polygon2d.MakeCircle(hole_size / 2, hole_subdivisions);

            Vector3f axis = (Vector3f)(start - end).Normalized;

            int     start_tid   = origSpatial.FindNearestTriangle(start);
            Frame3f start_frame = origMesh.GetTriFrame(start_tid);

            start_frame.Origin = (Vector3f)start;
            start_frame.AlignAxis(2, axis);

            int end_tid = origSpatial.FindNearestTriangle(end);
            //Frame3f end_frame = origMesh.GetTriFrame(end_tid); end_frame.Origin = (Vector3f)end;
            Frame3f end_frame = start_frame; end_frame.Origin = (Vector3f)end;

            MeshInsertProjectedPolygon start_insert = new MeshInsertProjectedPolygon(cutMesh, polygon, start_frame, start_tid);
            bool start_ok = start_insert.Insert();

            MeshInsertProjectedPolygon end_insert = new MeshInsertProjectedPolygon(cutMesh, polygon, end_frame, end_tid);
            bool end_ok = end_insert.Insert();

            if (start_ok == false || end_ok == false)
            {
                throw new Exception("CutPolygonHoleOp.compute_through_hole: start or end insertion failed!");
            }

            MeshEditor editor = new MeshEditor(cutMesh);
            EdgeLoop   l0     = start_insert.InsertedLoop;
            EdgeLoop   l1     = end_insert.InsertedLoop;

            l1.Reverse();
            editor.StitchLoop(l0.Vertices, l1.Vertices);

            return(cutMesh);
        }
        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);
        }
示例#12
0
        public override void Generate()
        {
            double tCurveLen            = CurveUtils.ArcLength(Curve);
            SampledArcLengthParam pAxis = new SampledArcLengthParam(Axis, Axis.Length);
            double tAxisLen             = pAxis.ArcLength;
            double tScale = tAxisLen / tCurveLen;

            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);

            double      tCur = 0;
            CurveSample s    = pAxis.Sample(tCur);
            Frame3f     f0   = new Frame3f((Vector3F)s.position, (Vector3F)s.tangent, 1);
            Frame3f     fCur = f0;

            // generate tube
            for (int ri = 0; ri < nRings; ++ri)
            {
                if (ri > 0)
                {
                    tCur       += (Curve[ri] - Curve[ri - 1]).Length;
                    s           = pAxis.Sample(tCur * tScale);
                    fCur.Origin = (Vector3F)s.position;
                    fCur.AlignAxis(1, (Vector3F)s.tangent);
                }

                Vector3D v_along  = Curve[ri];
                Vector3F v_frame  = fCur.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 = fCur.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 - 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)
            {
                // 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 = f0;
                fStart.Origin = (Vector3F)vAvgStart;
                Frame3f fEnd = fCur;
                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);
                }
            }
        }
示例#13
0
        public DMesh3 CreateMesh(List <Vector3d> path,
                                 List <Polygon2d> polys,
                                 VectorArray3d seam)
        {
            // Ignore first and last path/polys for mesh generation.
            // We just need the extra path positions to calculate a
            // continuous tangent at the seams.
            List <Vector3d> pathXZ = new List <Vector3d>();

            for (int i = 0; i < path.Count; i++)
            {
                pathXZ.Add(new Vector3d(path[i].x, 0, path[i].z));
            }

            int nVerts = path.Count - 2;
            int nPolys = polys.Count - 2;
            // Same VertexCount for all Polygons.
            int nSlices   = polys[0].VertexCount;
            int nPolySize = nSlices + 1;
            int nVecs     = nVerts * nPolySize;

            vertices = new VectorArray3d(nVecs);
            normals  = new VectorArray3f(nVecs);
            uv       = new VectorArray2f(nVecs);

            int quad_strips = nVerts - 1;
            int nSpanTris   = quad_strips * (2 * nSlices);

            triangles = new IndexArray3i(nSpanTris);

            Frame3f fCur         = new Frame3f(frame);
            double  pathLength   = CurveUtils.ArcLength(path.GetRange(1, nVerts));
            double  accum_path_u = 0;

            for (int ri = 0; ri < nPolys; ++ri)
            {
                int      si      = ri + 1; // actual path/polys index for mesh
                Vector3d tangent = CurveUtils.GetTangent(pathXZ, si);
                fCur.Origin = (Vector3f)path[si];
                fCur.AlignAxis(2, (Vector3f)tangent);

                int    nStartR      = ri * nPolySize;
                double accum_ring_v = 0;
                bool   copy         = ri == nPolys - 1;
                bool   paste        = ri == 0;

                for (int j = 0; j < nPolySize; ++j)
                {
                    int      k      = nStartR + j;
                    Vector2d pv     = polys[si].Vertices[j % nSlices];
                    Vector2d pvNext = polys[si].Vertices[(j + 1) % nSlices];
                    Vector3d v      = fCur.FromPlaneUV((Vector2f)pv, 2);
                    vertices[k] = v;
                    Vector3f n = (Vector3f)(v - fCur.Origin).Normalized;
                    normals[k]    = n;
                    uv[k]         = new Vector2f(accum_path_u, accum_ring_v);
                    accum_ring_v += (pv.Distance(pvNext) / polys[si].ArcLength);
                    if (copy)
                    {
                        Seam[j] = vertices[k];
                    }
                    else if (paste)
                    {
                        vertices[k] = seam[j];
                    }
                }
                double d = path[si].Distance(path[si + 1]);
                accum_path_u += d / pathLength;
            }

            int nStop = nVerts - 1;
            int ti    = 0;

            for (int ri = 0; ri < nStop; ++ri)
            {
                int r0 = ri * nPolySize;
                int r1 = r0 + nPolySize;
                for (int k = 0; k < nPolySize - 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);
                }
            }
            return(MakeDMesh());
        }
示例#14
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);
        }
示例#15
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);
                }
            }
        }
    // Use this for initialization
    public override void Awake()
    {
        // if we need to auto-configure Rift vs Vive vs (?) VR, we need
        // to do this before any other F3 setup, because MainCamera will change
        // and we are caching that in a lot of places...
        if (AutoConfigVR)
        {
            VRCameraRig = gs.VRPlatform.AutoConfigureVR();
        }

        // restore any settings
        SceneGraphConfig.RestorePreferences();

        // set up some defaults
        // this will move the ground plane down, but the bunnies will be floating...
        //SceneGraphConfig.InitialSceneTranslate = -4.0f * Vector3f.AxisY;
        SceneGraphConfig.DefaultSceneCurveVisualDegrees = 0.5f;
        SceneGraphConfig.DefaultPivotVisualDegrees      = 1.5f;
        SceneGraphConfig.DefaultAxisGizmoVisualDegrees  = 10.0f;
        SceneGraphConfig.InitialSceneTranslate          = -4 * Vector3f.AxisY;


        SceneOptions options = new SceneOptions();

        options.UseSystemMouseCursor = false;
        options.Use2DCockpit         = false;
        options.EnableTransforms     = true;
        options.EnableCockpit        = true;
        options.CockpitInitializer   = new PhotoToolCockpit();

        options.MouseCameraControls = new MayaCameraHotkeys();
        options.SpatialCameraRig    = VRCameraRig;

        // very verbose
        options.LogLevel = 2;

        context = new FContext();
        context.Start(options);

        // if you had other gizmos, you would register them here
        //context.TransformManager.RegisterGizmoType("snap_drag", new SnapDragGizmoBuilder());
        //controller.TransformManager.SetActiveGizmoType("snap_drag");

        // if you had other tools, you would register them here.
        context.ToolManager.RegisterToolType(DrawPrimitivesTool.Identifier, new DrawPrimitivesToolBuilder());
        context.ToolManager.RegisterToolType(DrawSurfaceCurveTool.Identifier, new DrawSurfaceCurveToolBuilder()
        {
            AttachCurveToSurface = true,
            DefaultSamplingRateS = 0.0025f, DefaultSurfaceOffsetS = 0.0025f,
            CurveMaterialF       = () => { var mat = context.Scene.DefaultCurveSOMaterial.Clone(); mat.RGBColor = Colorf.VideoRed; return(mat); }
        });
        context.ToolManager.SetActiveToolType(DrawSurfaceCurveTool.Identifier, ToolSide.Right);

        // Set up standard scene lighting if requested
        if (options.EnableDefaultLighting)
        {
            GameObject lighting = GameObject.Find("SceneLighting");
            if (lighting == null)
            {
                lighting = new GameObject("SceneLighting");
            }
            SceneLightingSetup setup = lighting.AddComponent <SceneLightingSetup>();
            setup.Context       = context;
            setup.LightDistance = 30.0f; // related to total scene scale...
        }


        Context.Scene.DisableSelectionMaterial = true;


        /*
         * Import elements of Unity scene that already exist into the FScene
         */

        // set up ground plane geometry (optional)
        GameObject groundPlane = GameObject.Find("GroundPlane");

        if (groundPlane != null && groundPlane.IsVisible())
        {
            context.Scene.AddWorldBoundsObject(groundPlane);
        }


        float    fSquareSize = 1.0f;
        Vector3f eyePos      = context.ActiveCamera.GetPosition();

        System.Random rand = new System.Random(31337);

        // [RMS] this path only works in Editor, is relative to top-level project directory
        string sPhotoFolder = "Data\\PhotoSets\\kitchen";

        string[] photos = Directory.GetFiles(sPhotoFolder);
        foreach (string filename in photos)
        {
            Texture2D tex = load_texture(filename);
            if (tex == null)
            {
                continue;
            }

            float fScale = fSquareSize / (float)tex.width;
            if (tex.height > tex.width)
            {
                fScale = fSquareSize / (float)tex.height;
            }

            float w = fScale * (float)tex.width;
            float h = fScale * (float)tex.height;

            TrivialRectGenerator rectgen = new TrivialRectGenerator()
            {
                Width = w, Height = h
            };
            rectgen.Generate();
            DMesh3 mesh = new DMesh3(MeshComponents.VertexUVs);
            rectgen.MakeMesh(mesh);

            SOMaterial material = new SOMaterial()
            {
                Name     = "photomaterial",
                Type     = SOMaterial.MaterialType.TextureMap,
                RGBColor = Colorf.White
            };
            material.MainTexture = tex;

            DMeshSO so = new DMeshSO();
            so.Create(mesh, material);
            context.Scene.AddSceneObject(so);

            float horz = rand.Next(-50, 50);
            float vert = rand.Next(-20, 25);
            int   mult = 1000;
            float dist = (float)(rand.Next(2 * mult, 3 * mult)) / (float)mult;

            Ray3f r = VRUtil.MakeRayFromSphereCenter(horz, vert);
            r.Origin += eyePos;
            float fRayT = 0.0f;
            RayIntersection.Sphere(r.Origin, r.Direction, eyePos, dist, out fRayT);
            Vector3f v = r.Origin + fRayT * r.Direction;
            Frame3f  f = new Frame3f(v, v.Normalized);

            Vector3f toEye = context.ActiveCamera.GetPosition() - f.Origin;
            toEye.Normalize();
            f.AlignAxis(1, toEye);
            f.ConstrainedAlignAxis(2, Vector3f.AxisY, f.Y);

            so.SetLocalFrame(f, CoordSpace.WorldCoords);
        }
    }
示例#17
0
        public override bool UpdateCapture(ITransformable target, Ray3f worldRay)
        {
            // find hit
            SnapResult snap = Targets.FindHitSnapPoint(worldRay);

            snapState.UpdateState(snap);

            if (snapState.IsSnapped)
            {
                SnapResult useSnap   = snapState.ActiveSnapTarget;
                Frame3f    hitFrameS = Frame3f.Identity;
                if (useSnap != null)
                {
                    hitFrameS = new Frame3f(useSnap.FrameS);
                }

                Frame3f targetF = originalTargetS; // target.GetLocalFrame(CoordSpace.WorldCoords);
                Frame3f pivotF  = hitFrameS;
                targetF.Origin = pivotF.Origin;

                if (parent.CurrentFrameMode == FrameType.WorldFrame)
                {
                    targetF.Rotation = Quaternion.identity;
                }
                else
                {
                    targetF.Rotation = pivotF.Rotation;
                }

                Vector3f deltaInT = targetF.FromFrameV(SourceFrameL.Origin);
                targetF.Origin -= deltaInT;   // why is this minus?

                target.SetLocalFrame(targetF, CoordSpace.SceneCoords);
            }
            else
            {
                Func <SceneObject, bool> filter = null;
                if (TargetObjects != null && TargetObjects.Count > 0)
                {
                    filter = (x) => { return(TargetObjects.Contains(x) == false); }
                }
                ;

                AnyRayHit hit;
                if (scene.FindSceneRayIntersection(worldRay, out hit, true, filter))
                {
                    Vector3f hitPosS  = scene.ToSceneP(hit.hitPos);
                    Vector3f hitNormS = scene.ToSceneN(hit.hitNormal);

                    Frame3f targetF = originalTargetS;
                    targetF.Origin = hitPosS;
                    targetF.AlignAxis(1, hitNormS);

                    if (parent.CurrentFrameMode == FrameType.WorldFrame)
                    {
                        targetF.Rotation = Quaternion.identity;
                    }

                    Vector3f deltaInT = targetF.FromFrameV(SourceFrameL.Origin);
                    targetF.Origin -= deltaInT;   // why is this minus?
                    target.SetLocalFrame(targetF, CoordSpace.SceneCoords);
                }
                else
                {
                    target.SetLocalFrame(originalTargetS, CoordSpace.SceneCoords);
                }
            }

            return(true);
        }