void SoXipOverlayExtractContour::appendContour( SoXipManipulableShape* shape, SoMFVec3f& accumulatePoint, SoMFInt32& accumulateCoordIndex ) { if( !shape->isClosed() ) { SoDebugError::post( __FILE__, "Contour extraction does not operate on shapes with opened contours" ); return ; } int oldNumPoints = accumulatePoint.getNum(); int oldNumIndices = accumulateCoordIndex.getNum(); SoMFVec3f linePoints; SoMFInt32 lineIndices; SbBool closed; shape->extractGeometries( linePoints, lineIndices, closed ); accumulatePoint.setValues( oldNumPoints, linePoints.getNum(), linePoints.getValues(0) ); accumulateCoordIndex.setValues( oldNumIndices, lineIndices.getNum(), lineIndices.getValues(0) ); int* indPtr = accumulateCoordIndex.startEditing() + oldNumIndices; for( int i = 0; i < lineIndices.getNum(); ++ i, ++ indPtr ) { if( *indPtr != -1 ) *indPtr += oldNumPoints; } accumulateCoordIndex.finishEditing(); }
void XipPrimitiveDraw::lines( SoGLRenderAction* action, const SoMFVec3f& coord, const SbColor& color, const float alpha, const float lineWidth, const unsigned short linePattern ) { action->getState()->push(); { GLboolean depthTest; glGetBooleanv( GL_DEPTH_TEST, &depthTest ); if( depthTest ) glDisable( GL_DEPTH_TEST ); SoLinePatternElement::set( action->getState(), linePattern ); SoLineWidthElement::set( action->getState(), lineWidth ); m_Material->diffuseColor.setValue( color ); m_Material->transparency.setValue( alpha ); action->traverse( m_Material ); m_Coords->point.copyFrom( coord ); action->traverse( m_Coords ); m_LineSet->numVertices.setValue( coord.getNum() ); action->traverse( m_LineSet ); if( depthTest ) glEnable( GL_DEPTH_TEST ); } action->getState()->pop(); }
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; }
bool isInsideClosedContour( const SbVec3f& pt, const SoMFVec3f& point ) { bool oddNodes = false; int numPoints = point.getNum(); if( numPoints ) { // Shift the vertices so that 'pt' is the origin SoMFVec3f tmpPoint; tmpPoint.setValues( 0, numPoints, point.getValues(0) ); SbVec3f* ptr = tmpPoint.startEditing(); for( int k = 0; k < numPoints; ++ k ) { ptr[k] -= pt; if( isZero( ptr[k][0] ) && isZero( ptr[k][1] ) ) return true; } for( int i = 0, j = numPoints - 1; i < numPoints; j = i ++ ) { if( ptr[i][1] < 0 && ptr[j][1] >= 0 || ptr[j][1] < 0 && ptr[i][1] >= 0 ) { if( ptr[i][0] < ptr[i][1] / (ptr[j][1] - ptr[i][1]) * (ptr[j][0] - ptr[i][0]) ) oddNodes = !oddNodes; } } tmpPoint.finishEditing(); } return oddNodes; }
SbBool selfIntersect( const SoMFVec3f& point, SbBool isClosed ) { SbVec3f pt; int numPoints = point.getNum(); for( int i = 0; i < numPoints - 1; ++ i ) for( int j = i + 2; j < numPoints - 1; ++ j ) { if( intersect( point[i], point[i+1], point[j], point[j+1], pt ) ) return TRUE; } if( isClosed ) { for( int j = 1; j < numPoints - 2; ++ j ) { if( intersect( point[numPoints - 1], point[0], point[j], point[j+1], pt ) ) return TRUE; } } return FALSE; }
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 ++; } } } }
int closestPoint( const SoMFVec3f& point, const SbVec3f& ref ) { if( point.getNum() ) { int i_min = 0; double dist_min = (point[0] - ref).length(); int numPoints = point.getNum(); for( int i = 1; i < numPoints; ++ i ) { float dist = (point[i] - ref).length(); if( dist < dist_min ) { i_min = i; dist_min = dist; } } return i_min; } return -1; }
double areaPolygon3D( const SoMFVec3f& point, const SbVec3f& normal ) { int numPoints = point.getNum(); if( numPoints < 3 ) return 0; // select largest abs coordinate to ignore for projection double ax = (normal[0] > 0 ? normal[0] : -normal[0]); // abs x-coord double ay = (normal[1] > 0 ? normal[1] : -normal[1]); // abs y-coord double az = (normal[2] > 0 ? normal[2] : -normal[2]); // abs z-coord // scale to get area before projection double an = sqrt( ax * ax + ay * ay + az * az); // length of normal vector double area = 0; if( ax > ay ) { if( ax > az ) { // [ignore x-coord] for( int i = numPoints - 1, j = 0, k = numPoints - 2; j < numPoints; k = i, i = j ++ ) area += point[i][1] * (point[j][2] - point[k][2]); return fabs( area * 0.5 * an / ax ); } } else if( ay > az ) { // [ignore y-coord] for( int i = numPoints - 1, j = 0, k = numPoints - 2; j < numPoints; k = i, i = j ++ ) area += point[i][0] * (point[j][2] - point[k][2]); return fabs( area * 0.5 * an / ay ); } // [ignore z-coord] for( int i = numPoints - 1, j = 0, k = numPoints - 2; j < numPoints; k = i, i = j ++ ) area += point[i][0] * (point[j][1] - point[k][1]); return fabs( area * 0.5 * an / az ); }
void removeClosePoints( SoMFVec3f& point, float minDist ) { int numPoints = point.getNum(); if( numPoints >= 2 ) { for( int ni = numPoints - 1, i = 0; i < numPoints; ) { if( (point[ni] - point[i]).length() <= minDist ) { point.deleteValues( i, 1 ); -- numPoints; } else // move forward { ni = i ++; } } } }
DT_ShapeHandle Shape::create(const SoMFVec3f& point) { DT_ShapeHandle shape = DT_NewPolytope(NULL); DT_Vector3 vertex; for (int i = 0; i < point.getNum(); ++i) { vertex[0] = point[i][0]; vertex[1] = point[i][1]; vertex[2] = point[i][2]; DT_Vertex(vertex); } DT_EndPolytope(); return shape; }
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(); }