📄 polyhedralboundedsolidmodelingtools.java
字号:
[MANT1988].12.3.2, and presented in program [MANT1988].12.5. This version of the rotational sweep has some limitations and characteristics: - It is the simpler form of rotational sweep, and serves as the base to develop complex/generalized versions of the algorithm. - The rotation axis is fixed to be the x-axis - The profile path must be open (a "wire" solid with just one face with one loop, which is open, with a single, connected and nonforking string of edges) - All edges must lie on the half plane [y>0,z=0], and must not touch the x axis. */ public static void rotationalSweepVersion1(PolyhedralBoundedSolid solid, int nfaces) { _PolyhedralBoundedSolidHalfEdge first, cfirst, last, scan = null; _PolyhedralBoundedSolidFace tailf; Vector3D v; Matrix4x4 M; first = solid.polygonsList.get(0).boundariesList.get(0).boundaryStartHalfEdge; while ( first.parentEdge != first.next().parentEdge ) { first = first.next(); } last = first.next(); while ( last.parentEdge != last.next().parentEdge ) { last = last.next(); } cfirst = first; M = new Matrix4x4(); M.axisRotation( (2*Math.PI) / ((double)nfaces), 1, 0, 0); int i; for ( i = 0; i < nfaces-1; i++ ) { v = M.multiply(cfirst.next().startingVertex.position); solid.lmev(cfirst.next(), cfirst.next(), solid.getMaxVertexId()+1, v); scan = cfirst.next(); while ( scan != last.next() ) { v = M.multiply(scan.previous().startingVertex.position); solid.lmev(scan.previous(), scan.previous(), solid.getMaxVertexId()+1, v); solid.lmef(scan.previous().previous(), scan.next(), solid.getMaxFaceId()+1); scan = (scan.next().next()).mirrorHalfEdge(); } last = scan; cfirst = (cfirst.next().next()).mirrorHalfEdge(); } tailf = solid.lmef(cfirst.next(), first.mirrorHalfEdge(), solid.getMaxFaceId()+1); while ( cfirst != scan ) { solid.lmef(cfirst, cfirst.next().next().next(), solid.getMaxFaceId()+1); cfirst = (cfirst.previous()).mirrorHalfEdge().previous(); } } /** Current method implements a variant of simple and restricted rotational sweep (lathe) algorithm for wires and laminas in the z=0 plane, to be rotated about the x axis, as described in section [MANT1988].12.5, and presented in programs [MANT1988].12.5 and [MANT1988].12.11. */ public static void rotationalSweepVersion2(PolyhedralBoundedSolid solid, int nfaces) { //----------------------------------------------------------------- _PolyhedralBoundedSolidHalfEdge first, cfirst, last, scan = null; _PolyhedralBoundedSolidHalfEdge h; _PolyhedralBoundedSolidFace tailf = null; _PolyhedralBoundedSolidFace headf = null; boolean closedFigure = false; Vector3D v; Matrix4x4 M; //----------------------------------------------------------------- if ( solid.polygonsList.size() > 1 ) { // Assume it's a lamina closedFigure = true; h = solid.polygonsList.get(0).boundariesList.get(0).boundaryStartHalfEdge; solid.lmev(h, (h.mirrorHalfEdge()).next(), solid.getMaxVertexId()+1, h.startingVertex.position); solid.lkef(h.previous(), (h.previous()).mirrorHalfEdge()); headf = solid.polygonsList.get(0); } //----------------------------------------------------------------- first = solid.polygonsList.get(0).boundariesList.get(0).boundaryStartHalfEdge; while ( first.parentEdge != first.next().parentEdge ) { first = first.next(); } last = first.next(); while ( last.parentEdge != last.next().parentEdge ) { last = last.next(); } cfirst = first; M = new Matrix4x4(); M.axisRotation( (2*Math.PI) / ((double)nfaces), 1, 0, 0); int i; for ( i = 0; i < nfaces-1; i++ ) { v = M.multiply(cfirst.next().startingVertex.position); solid.lmev(cfirst.next(), cfirst.next(), solid.getMaxVertexId()+1, v); scan = cfirst.next(); while ( scan != last.next() ) { v = M.multiply(scan.previous().startingVertex.position); solid.lmev(scan.previous(), scan.previous(), solid.getMaxVertexId()+1, v); solid.lmef(scan.previous().previous(), scan.next(), solid.getMaxFaceId()+1); scan = (scan.next().next()).mirrorHalfEdge(); } last = scan; cfirst = (cfirst.next().next()).mirrorHalfEdge(); } tailf = solid.lmef(cfirst.next(), first.mirrorHalfEdge(), solid.getMaxFaceId()+1); while ( cfirst != scan ) { solid.lmef(cfirst, cfirst.next().next().next(), solid.getMaxFaceId()+1); cfirst = (cfirst.previous()).mirrorHalfEdge().previous(); } //----------------------------------------------------------------- if ( closedFigure ) { solid.lkfmrh(headf, tailf); solid.loopGlue(headf.id); } //----------------------------------------------------------------- } /** This method builds a test solid for evaluating the second version of the rotational sweep algorithm in a controlled way, as proposed on the example from section [MANT1988].12.5. The created solid is is similar to the solid shown on figure [MANT1988].12.5. (in particular when seting 4 sides); */ public static PolyhedralBoundedSolid createTestTorus() { PolyhedralBoundedSolid solid; Vector3D center = new Vector3D(0.5, 0.5, 0); int nsides = 4; solid = GeometricModeler.createCircularLamina(center.x, center.y, 0.2, 0.0, nsides); // For seting 4 sided case to be equal to figure [MANT1988].12.5. // an aditional rotation must be applied to the lamina prior to the // rotational sweep. Matrix4x4 T1 = new Matrix4x4(); Matrix4x4 T2 = new Matrix4x4(); Matrix4x4 R = new Matrix4x4(); Matrix4x4 M; T1.translation(center.multiply(-1)); T2.translation(center); R.axisRotation(Math.PI/((double)nsides), 0, 0, 1); M = T2.multiply(R.multiply(T1)); solid.applyTransformation(M); rotationalSweepVersion2(solid, 16); return solid; } public static PolyhedralBoundedSolid rotationalSweepTest() { PolyhedralBoundedSolid solid; //-----------------------------------------------------------------/* solid = new PolyhedralBoundedSolid(); solid.mvfs(new Vector3D(0.75, 0.25, 0), 1, 1); GeometricModeler.addArc(solid, 1, 1, 0.5, 0.25, 0.25, 0.0, 0.0, 90.0, 10); rotationalSweepVersion1(solid, 20);*/ solid = createTestTorus(); //----------------------------------------------------------------- solid.validateModel(); return solid; } /** This method builds a test solid for evaluating the splitting algorithm in a controlled way. The generated object is similar to that shown on figures [MANT1986].4., [MANT1986].5., [MANT1986].8., [MANT1986].10., [MANT1988].14.2., [MANT1988].14.3., and [MANT1988].14.6. Generated solid is interesting when intersecting with the plane Z=0.35 becase stress the splitting algorithm to consider multiple vertex classification cases. */ private static PolyhedralBoundedSolid buildSplitTest1() { Matrix4x4 R = new Matrix4x4(); PolyhedralBoundedSolid solid; R.translation(0.55, 0.55, 0.55); solid = new PolyhedralBoundedSolid(); solid.mvfs(new Vector3D(0.00+0.05, 0.40+0.05, 0.00+0.05), 1, 1); solid.smev(1, 1, 2, new Vector3D(0.94+0.05, 0.40+0.05, 0.00+0.05)); solid.smev(1, 2, 3, new Vector3D(0.94+0.05, 0.40+0.05, 0.46+0.05)); solid.smev(1, 3, 4, new Vector3D(0.60+0.05, 0.40+0.05, 0.30+0.05)); solid.smev(1, 4, 5, new Vector3D(0.37+0.05, 0.40+0.05, 0.30+0.05)); solid.smev(1, 5, 6, new Vector3D(0.18+0.05, 0.40+0.05, 0.46+0.05)); solid.smev(1, 6, 7, new Vector3D(0.00+0.05, 0.40+0.05, 0.30+0.05)); solid.mef(1, 1, 7, 6, 1, 2, 2); Matrix4x4 T = new Matrix4x4(); T.translation(0, -0.4, 0); GeometricModeler.translationalSweepExtrudeFacePlanar( solid, solid.findFace(1), T); return solid; } public static PolyhedralBoundedSolid splitTest(int part) { //- Basic lamina -------------------------------------------------- //PolyhedralBoundedSolid solid = createHoledBox(); //PolyhedralBoundedSolid solid = createBox(new Vector3D(0.9, 0.9, 0.9)); PolyhedralBoundedSolid solid = buildSplitTest1();/* Matrix4x4 R = new Matrix4x4(); PolyhedralBoundedSolid solid; R.translation(0.55, 0.55, 0.55); solid = new PolyhedralBoundedSolid(); solid.mvfs(new Vector3D(0.00+0.05, 0.00+0.05, 0), 1, 1); solid.smev(1, 1, 2, new Vector3D(0.94+0.05, 0.00+0.05, 0)); solid.smev(1, 2, 3, new Vector3D(0.94+0.05, 0.46+0.05, 0)); solid.smev(1, 3, 4, new Vector3D(0.00+0.05, 0.30+0.05, 0)); solid.mef(1, 1, 4, 3, 1, 2, 2); Matrix4x4 T = new Matrix4x4(); T.translation(0, 0, 0.4); GeometricModeler.translationalSweepExtrudeFacePlanar( solid, solid.findFace(1), T);*/ //----------------------------------------------------------------- InfinitePlane sp; ArrayList <PolyhedralBoundedSolid> solidsAbove; ArrayList <PolyhedralBoundedSolid> solidsBelow; solidsAbove = new ArrayList <PolyhedralBoundedSolid>(); solidsBelow = new ArrayList <PolyhedralBoundedSolid>(); sp = new InfinitePlane(new Vector3D(0, 0, 1) /*n*/, new Vector3D(0, 0, 0.30+0.05) /*p*/);// sp = new InfinitePlane(new Vector3D(0, 0, 1) /*n*/,// new Vector3D(0, 0, 0.5) /*p*/); //----------------------------------------------------------------- solid.validateModel(); if ( part == 1 ) { return solid; } GeometricModeler.split(solid, sp, solidsAbove, solidsBelow); //----------------------------------------------------------------- if ( part == 3 ) { solid = solidsBelow.get(0); } else { solid = solidsAbove.get(0); } solid.maximizeFaces(); solid.validateModel(); return solid; } /** This method builds a test sample pair of solids for evaluating the set operations algorithm in a controlled way. The generated objects are similar to that shown on figures [MANT1986].11. and [MANT1988].15.4. This set correspond to the simpler of all cases for CSG operations test, and its processing in set operations are characterized by the following consecuences: - Only the vertex-face classifier is called (can be processed without using a verte-vertex classifier). - On the vertex-face classifier, the second stage (reclassification on sectors) is not used, due to non coplanar cases on neigborhoods. */ private static PolyhedralBoundedSolid[] buildCsgTest1() { PolyhedralBoundedSolid operands[]; PolyhedralBoundedSolid a, b; operands = new PolyhedralBoundedSolid[2]; //----------------------------------------------------------------- Matrix4x4 R = new Matrix4x4(); R.translation(0.5, 0.25, 0.3); Box box = new Box(new Vector3D(1, 0.5, 0.6)); a = box.exportToPolyhedralBoundedSolid(); a.applyTransformation(R); a.validateModel(); //----------------------------------------------------------------- R = new Matrix4x4(); R.translation(0.5+0.24, 0.25-0.18, 0.3+0.42); box = new Box(new Vector3D(1, 0.5, 0.6)); b = box.exportToPolyhedralBoundedSolid(); b.applyTransformation(R); b.validateModel(); //----------------------------------------------------------------- operands[0] = a; operands[1] = b; return operands; } /** This method builds a test sample pair of solids for evaluating the set operations algorithm in a controlled way. This set correspond to a simple cases for CSG operations test: two blocks without intersecting vertex pairs (only edge/face intersections are present). The resulting gluing face can be a variation of the method `buildCsgTest1`, if blocks are translated so their parallel faces don't touch; or can be one simple test case for the complex sector intersection. */ private static PolyhedralBoundedSolid[] buildCsgTest2() { PolyhedralBoundedSolid operands[]; PolyhedralBoundedSolid a, b; operands = new PolyhedralBoundedSolid[2]; //----------------------------------------------------------------- Matrix4x4 R = new Matrix4x4(); R.translation(0.5, 0.5, 0.15); Box box = new Box(new Vector3D(1, 0.5, 0.3)); a = box.exportToPolyhedralBoundedSolid(); a.applyTransformation(R); a.validateModel(); //----------------------------------------------------------------- R = new Matrix4x4(); R.translation(0.5, 0.5, 0.15+0.3); box = new Box(new Vector3D(0.5, 1, 0.3)); b = box.exportToPolyhedralBoundedSolid(); b.applyTransformation(R); b.validateModel(); //----------------------------------------------------------------- operands[0] = a; operands[1] = b; return operands; } /** This method builds a test sample pair of solids for evaluating the set operations algorithm in a controlled way. The generated objects are similar to that shown on figures [MANT1986].12. and [MANT1988].15.5. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -