double areaPolygon3D( const SoMFVec3f& point, const SoMFInt32& indices, const SbVec3f& normal ) { int numIndices = indices.getNum(); if( numIndices < 3 ) return 0; double area = 0; SoMFVec3f tmpPoint; const int* iPtr = indices.getValues(0); for( int i = 0; i < numIndices; ++ i, ++ iPtr ) { if( *iPtr == -1 ) { area += areaPolygon3D( tmpPoint, normal ); tmpPoint.setNum(0); } else { tmpPoint.set1Value( tmpPoint.getNum(), point[*iPtr] ); } } return area; }
void removeClosePoints( const SoMFVec3f& point, SoMFVec3f& cleanPoints, float minDist ) { cleanPoints.setNum( point.getNum() ); cleanPoints.setValues( 0, point.getNum(), point.getValues(0) ); int numPoints = cleanPoints.getNum(); if( cleanPoints.getNum() >= 2 ) { for( int ni = numPoints - 1, i = 0; i < numPoints; ) { if( (cleanPoints[ni] - cleanPoints[i]).length() <= minDist ) { cleanPoints.deleteValues( i, 1 ); -- numPoints; } else // move forward { ni = i ++; } } } }
void doClipping(SbVec3f trans, SbRotation rot) { SbMatrix mat; SbVec3f normal; mat.setTransform(trans, rot, SbVec3f(1,1,1)); mat.multDirMatrix(SbVec3f(0, -1, 0), normal); SbPlane plane(normal, trans); const float coords[][3] = { {-5,-5,-5}, {5,-5,-5}, {5,5,-5}, {-5,5,-5}, {-5,-5,5}, {5,-5,5}, {5,5,5}, {-5,5,5} }; const int indices[] = { 0,3,2,1,-1, 0,1,5,4,-1, 2,6,5,1,-1, 3,7,6,2,-1, 3,0,4,7,-1, 7,4,5,6,-1 }; // Clip box against plane SbClip clip; SoMFVec3f * globalVerts = (SoMFVec3f *)SoDB::getGlobalField(SbName("globalVerts")); SoMFVec3f * globalTVerts = (SoMFVec3f *)SoDB::getGlobalField(SbName("globalTVerts")); SoMFInt32 * globalnv = (SoMFInt32 *)SoDB::getGlobalField(SbName("globalnv")); globalVerts->startEditing(); globalVerts->setNum(0); globalTVerts->startEditing(); globalTVerts->setNum(0); globalnv->startEditing(); globalnv->setNum(0); int i; for (i = 0;i<6*5;i++) { if (indices[i] == -1) { clip.clip(plane); int numVerts = clip.getNumVertices(); if (numVerts > 0) { for (int j = 0;j<numVerts;j++) { SbVec3f v; clip.getVertex(j, v); globalVerts->set1Value(globalVerts->getNum(), v); v += SbVec3f(5, 5, 5); v /= 10.0; globalTVerts->set1Value(globalTVerts->getNum(), v); } globalnv->set1Value(globalnv->getNum(), numVerts); } clip.reset(); } else clip.addVertex(coords[indices[i]]); } globalVerts->finishEditing(); globalTVerts->finishEditing(); globalnv->finishEditing(); // Close hole in clipped box by clipping against all 6 planes const SbVec3f planecoords[] = { SbVec3f(-10,0,-10), SbVec3f(10,0,-10), SbVec3f(10,0,10), SbVec3f(-10,0,10) }; clip.reset(); for (i = 0;i<4;i++) { SbVec3f v; mat.multVecMatrix(planecoords[i], v); clip.addVertex(v); } for (i = 0;i<6*5;i+=5) { SbPlane p(coords[indices[i+2]], coords[indices[i+1]], coords[indices[i]]); clip.clip(p); } int numVerts = clip.getNumVertices(); SoMFVec3f * planeVerts = (SoMFVec3f *)SoDB::getGlobalField(SbName("planeVerts")); SoMFVec3f * planeTVerts = (SoMFVec3f *)SoDB::getGlobalField(SbName("planeTVerts")); planeVerts->startEditing(); planeVerts->setNum(0); planeTVerts->startEditing(); planeTVerts->setNum(0); for (i = 0;i<numVerts;i++) { SbVec3f v; clip.getVertex(i, v); planeVerts->set1Value(planeVerts->getNum(), v); v += SbVec3f(5, 5, 5); v /= 10.0; planeTVerts->set1Value(planeTVerts->getNum(), v); } planeVerts->finishEditing(); planeTVerts->finishEditing(); }