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); }
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(); } }
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)); }
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); }
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); }
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(); } }
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); }
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); }
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); } } }
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()); }
// [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); }
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); } }
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); }