00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "PreCompiled.h"
00025
00026 #ifndef _PreComp_
00027 # ifdef FC_OS_WIN32
00028 # include <windows.h>
00029 # endif
00030 # ifdef FC_OS_MACOSX
00031 # include <OpenGL/gl.h>
00032 # else
00033 # include <GL/gl.h>
00034 # endif
00035 # include <Inventor/SbBox.h>
00036 # include <Inventor/SoOutput.h>
00037 # include <Inventor/SoPrimitiveVertex.h>
00038 # include <Inventor/actions/SoGLRenderAction.h>
00039 # include <Inventor/actions/SoGetPrimitiveCountAction.h>
00040 # include <Inventor/actions/SoWriteAction.h>
00041 # include <Inventor/bundles/SoMaterialBundle.h>
00042 # include <Inventor/bundles/SoTextureCoordinateBundle.h>
00043 # include <Inventor/details/SoFaceDetail.h>
00044 # include <Inventor/details/SoPointDetail.h>
00045 # include <Inventor/elements/SoGLCacheContextElement.h>
00046 # include <Inventor/elements/SoLazyElement.h>
00047 # include <Inventor/elements/SoLightModelElement.h>
00048 # include <Inventor/misc/SoState.h>
00049 #endif
00050
00051 #include <Gui/SoFCInteractiveElement.h>
00052 #include <Mod/Mesh/App/Core/Elements.h>
00053 #include <Mod/Mesh/App/Core/Grid.h>
00054 #include <Mod/Mesh/App/Core/Algorithm.h>
00055 #include <Mod/Mesh/App/Core/MeshIO.h>
00056 #include <Mod/Mesh/App/Mesh.h>
00057 #include "SoFCMeshNode.h"
00058
00059 using namespace MeshGui;
00060
00078
00079 inline void glVertex(const MeshCore::MeshPoint& _v)
00080 {
00081 float v[3];
00082 v[0]=_v.x; v[1]=_v.y;v[2]=_v.z;
00083 glVertex3fv(v);
00084 }
00085
00086
00087 inline void glNormal(const Base::Vector3f& _n)
00088 {
00089 float n[3];
00090 n[0]=_n.x; n[1]=_n.y;n[2]=_n.z;
00091 glNormal3fv(n);
00092 }
00093
00094
00095 inline void glNormal(float* n)
00096 {
00097 glNormal3fv(n);
00098 }
00099
00100
00101 inline SbVec3f sbvec3f(const Base::Vector3f& _v) {
00102 return SbVec3f(_v.x, _v.y, _v.z);
00103 }
00104
00105 SO_NODE_SOURCE(SoFCMeshNode);
00106
00107 void SoFCMeshNode::initClass()
00108 {
00109 SO_NODE_INIT_CLASS(SoFCMeshNode, SoShape, "Shape");
00110 }
00111
00112 SoFCMeshNode::SoFCMeshNode() : MaximumTriangles(500000), _mesh(0), _ctPrimitives(0)
00113 {
00114 SO_NODE_CONSTRUCTOR(SoFCMeshNode);
00115 SO_NODE_ADD_FIELD(point, (0.0f, 0.0f, 0.0f));
00116 SO_NODE_ADD_FIELD(coordIndex,(0));
00117 }
00118
00119 void SoFCMeshNode::notify(SoNotList * node)
00120 {
00121 SoShape::notify(node);
00122 }
00123
00127 void SoFCMeshNode::setMesh(const Mesh::MeshObject* mesh)
00128 {
00129 _mesh = mesh;
00130 }
00131
00144 void SoFCMeshNode::createRoughModel(bool simplest)
00145 {
00146 const Base::BoundBox3f& cBox = _mesh->getKernel().GetBoundBox();
00147
00148 if ( simplest ) {
00149 int triangles[36] = {
00150 0,1,2,0,2,3,
00151 0,1,5,0,5,4,
00152 0,4,7,0,7,3,
00153 6,7,4,6,4,5,
00154 6,2,3,6,3,7,
00155 6,1,2,6,5,1
00156 };
00157 SbVec3f points[8] = {
00158 SbVec3f(cBox.MinX,cBox.MinY,cBox.MinZ),
00159 SbVec3f(cBox.MaxX,cBox.MinY,cBox.MinZ),
00160 SbVec3f(cBox.MaxX,cBox.MaxY,cBox.MinZ),
00161 SbVec3f(cBox.MinX,cBox.MaxY,cBox.MinZ),
00162 SbVec3f(cBox.MinX,cBox.MinY,cBox.MaxZ),
00163 SbVec3f(cBox.MaxX,cBox.MinY,cBox.MaxZ),
00164 SbVec3f(cBox.MaxX,cBox.MaxY,cBox.MaxZ),
00165 SbVec3f(cBox.MinX,cBox.MaxY,cBox.MaxZ)
00166 };
00167
00168 coordIndex.setValues(0,36,triangles);
00169 point.setValues (0,8,points);
00170 } else {
00171
00172 float fAvgLen = 5.0f * MeshCore::MeshAlgorithm(_mesh->getKernel()).GetAverageEdgeLength();
00173
00174
00175 fAvgLen = std::max<float>(fAvgLen, (cBox.MaxX-cBox.MinX)/50.0f);
00176 fAvgLen = std::max<float>(fAvgLen, (cBox.MaxY-cBox.MinY)/50.0f);
00177 fAvgLen = std::max<float>(fAvgLen, (cBox.MaxZ-cBox.MinZ)/50.0f);
00178
00179 MeshCore::MeshGeomFacet face;
00180 std::vector<MeshCore::MeshGeomFacet> facets;
00181
00182 MeshCore::MeshPointGrid cGrid(_mesh->getKernel(), fAvgLen);
00183 unsigned long ulMaxX, ulMaxY, ulMaxZ;
00184 cGrid.GetCtGrids(ulMaxX, ulMaxY, ulMaxZ);
00185 MeshCore::MeshGridIterator cIter(cGrid);
00186
00187 for ( cIter.Init(); cIter.More(); cIter.Next() ) {
00188 if ( cIter.GetCtElements() > 0 ) {
00189 unsigned long ulX, ulY, ulZ;
00190 cIter.GetGridPos(ulX, ulY, ulZ);
00191 Base::BoundBox3f cBox = cIter.GetBoundBox();
00192
00193 if ( ulX == 0 || (ulX-1 >= 0 && cGrid.GetCtElements(ulX-1,ulY, ulZ) == 0) ) {
00194 face._aclPoints[0].Set(cBox.MinX,cBox.MinY,cBox.MinZ);
00195 face._aclPoints[1].Set(cBox.MinX,cBox.MinY,cBox.MaxZ);
00196 face._aclPoints[2].Set(cBox.MinX,cBox.MaxY,cBox.MinZ);
00197 facets.push_back(face);
00198 face._aclPoints[0].Set(cBox.MinX,cBox.MaxY,cBox.MaxZ);
00199 face._aclPoints[1].Set(cBox.MinX,cBox.MaxY,cBox.MinZ);
00200 face._aclPoints[2].Set(cBox.MinX,cBox.MinY,cBox.MaxZ);
00201 facets.push_back(face);
00202 }
00203 if ( ulX+1 == ulMaxX || (ulX+1 < ulMaxX && cGrid.GetCtElements(ulX+1,ulY, ulZ) == 0) ) {
00204 face._aclPoints[0].Set(cBox.MaxX,cBox.MinY,cBox.MinZ);
00205 face._aclPoints[1].Set(cBox.MaxX,cBox.MaxY,cBox.MinZ);
00206 face._aclPoints[2].Set(cBox.MaxX,cBox.MinY,cBox.MaxZ);
00207 facets.push_back(face);
00208 face._aclPoints[0].Set(cBox.MaxX,cBox.MaxY,cBox.MaxZ);
00209 face._aclPoints[1].Set(cBox.MaxX,cBox.MinY,cBox.MaxZ);
00210 face._aclPoints[2].Set(cBox.MaxX,cBox.MaxY,cBox.MinZ);
00211 facets.push_back(face);
00212 }
00213 if ( ulY == 0 || (ulY-1 >= 0 && cGrid.GetCtElements(ulX,ulY-1, ulZ) == 0) ) {
00214 face._aclPoints[0].Set(cBox.MinX,cBox.MinY,cBox.MaxZ);
00215 face._aclPoints[1].Set(cBox.MinX,cBox.MinY,cBox.MinZ);
00216 face._aclPoints[2].Set(cBox.MaxX,cBox.MinY,cBox.MaxZ);
00217 facets.push_back(face);
00218 face._aclPoints[0].Set(cBox.MaxX,cBox.MinY,cBox.MinZ);
00219 face._aclPoints[1].Set(cBox.MaxX,cBox.MinY,cBox.MaxZ);
00220 face._aclPoints[2].Set(cBox.MinX,cBox.MinY,cBox.MinZ);
00221 facets.push_back(face);
00222 }
00223 if ( ulY+1 == ulMaxY || (ulY+1 < ulMaxY && cGrid.GetCtElements(ulX,ulY+1, ulZ) == 0) ) {
00224 face._aclPoints[0].Set(cBox.MaxX,cBox.MaxY,cBox.MinZ);
00225 face._aclPoints[1].Set(cBox.MinX,cBox.MaxY,cBox.MinZ);
00226 face._aclPoints[2].Set(cBox.MaxX,cBox.MaxY,cBox.MaxZ);
00227 facets.push_back(face);
00228 face._aclPoints[0].Set(cBox.MinX,cBox.MaxY,cBox.MaxZ);
00229 face._aclPoints[1].Set(cBox.MaxX,cBox.MaxY,cBox.MaxZ);
00230 face._aclPoints[2].Set(cBox.MinX,cBox.MaxY,cBox.MinZ);
00231 facets.push_back(face);
00232 }
00233 if ( ulZ == 0 || (ulZ-1 >= 0 && cGrid.GetCtElements(ulX,ulY, ulZ-1) == 0) ) {
00234 face._aclPoints[0].Set(cBox.MaxX,cBox.MinY,cBox.MinZ);
00235 face._aclPoints[1].Set(cBox.MinX,cBox.MinY,cBox.MinZ);
00236 face._aclPoints[2].Set(cBox.MaxX,cBox.MaxY,cBox.MinZ);
00237 facets.push_back(face);
00238 face._aclPoints[0].Set(cBox.MinX,cBox.MaxY,cBox.MinZ);
00239 face._aclPoints[1].Set(cBox.MaxX,cBox.MaxY,cBox.MinZ);
00240 face._aclPoints[2].Set(cBox.MinX,cBox.MinY,cBox.MinZ);
00241 facets.push_back(face);
00242 }
00243 if ( ulZ+1 == ulMaxZ || (ulZ+1 < ulMaxZ && cGrid.GetCtElements(ulX,ulY, ulZ+1) == 0) ) {
00244 face._aclPoints[0].Set(cBox.MaxX,cBox.MinY,cBox.MaxZ);
00245 face._aclPoints[1].Set(cBox.MaxX,cBox.MaxY,cBox.MaxZ);
00246 face._aclPoints[2].Set(cBox.MinX,cBox.MinY,cBox.MaxZ);
00247 facets.push_back(face);
00248 face._aclPoints[0].Set(cBox.MinX,cBox.MaxY,cBox.MaxZ);
00249 face._aclPoints[1].Set(cBox.MinX,cBox.MinY,cBox.MaxZ);
00250 face._aclPoints[2].Set(cBox.MaxX,cBox.MaxY,cBox.MaxZ);
00251 facets.push_back(face);
00252 }
00253 }
00254 }
00255
00256 MeshCore::MeshKernel kernel; kernel = facets;
00257 const MeshCore::MeshPointArray& rPoints = kernel.GetPoints();
00258 const MeshCore::MeshFacetArray& rFacets = kernel.GetFacets();
00259
00260 point.enableNotify(false);
00261 point.setNum(rPoints.size());
00262 unsigned int pos=0;
00263 for (MeshCore::MeshPointArray::_TConstIterator cP=rPoints.begin(); cP!=rPoints.end(); ++cP)
00264 point.set1Value(pos++,cP->x,cP->y,cP->z);
00265 point.enableNotify(true);
00266
00267 coordIndex.enableNotify(false);
00268 coordIndex.setNum(3*rFacets.size());
00269 pos=0;
00270 for (MeshCore::MeshFacetArray::_TConstIterator cF=rFacets.begin(); cF!=rFacets.end(); ++cF){
00271 coordIndex.set1Value(pos++,cF->_aulPoints[0]);
00272 coordIndex.set1Value(pos++,cF->_aulPoints[1]);
00273 coordIndex.set1Value(pos++,cF->_aulPoints[2]);
00274 }
00275 coordIndex.enableNotify(true);
00276
00277 point.touch();
00278 coordIndex.touch();
00279
00280 #ifdef FC_DEBUG
00281 std::ofstream str( "bbox.stl", std::ios::out | std::ios::binary );
00282 MeshCore::MeshOutput aWriter(kernel);
00283 aWriter.SaveBinarySTL( str );
00284 #endif
00285 }
00286 }
00287
00291 void SoFCMeshNode::GLRender(SoGLRenderAction *action)
00292 {
00293 if (_mesh && shouldGLRender(action))
00294 {
00295 SoState* state = action->getState();
00296
00297 SbBool mode = Gui::SoFCInteractiveElement::get(state);
00298
00299
00300
00301 SoMaterialBundle mb(action);
00302
00303
00304 SbBool needNormals = !mb.isColorOnly();
00305 mb.sendFirst();
00306
00307
00308
00309
00310
00311 if ( mode == false || countTriangles() <= this->MaximumTriangles )
00312 drawFaces(needNormals);
00313 else
00314 drawPoints(needNormals);
00315
00316
00317 SoGLCacheContextElement::shouldAutoCache(state, SoGLCacheContextElement::DONT_AUTO_CACHE);
00318 }
00319 }
00320
00324 void SoFCMeshNode::drawFaces(SbBool needNormals) const
00325 {
00326
00327
00328 const MeshCore::MeshPointArray& rPoints = _mesh->getKernel().GetPoints();
00329 const MeshCore::MeshFacetArray& rFacets = _mesh->getKernel().GetFacets();
00330
00331 if (needNormals)
00332 {
00333 glBegin(GL_TRIANGLES);
00334 for ( MeshCore::MeshFacetArray::_TConstIterator it = rFacets.begin(); it != rFacets.end(); ++it )
00335 {
00336 const MeshCore::MeshPoint& v0 = rPoints[it->_aulPoints[0]];
00337 const MeshCore::MeshPoint& v1 = rPoints[it->_aulPoints[1]];
00338 const MeshCore::MeshPoint& v2 = rPoints[it->_aulPoints[2]];
00339
00340
00341 float n[3];
00342 n[0] = (v1.y-v0.y)*(v2.z-v0.z)-(v1.z-v0.z)*(v2.y-v0.y);
00343 n[1] = (v1.z-v0.z)*(v2.x-v0.x)-(v1.x-v0.x)*(v2.z-v0.z);
00344 n[2] = (v1.x-v0.x)*(v2.y-v0.y)-(v1.y-v0.y)*(v2.x-v0.x);
00345
00346 glNormal(n);
00347 glVertex(v0);
00348 glVertex(v1);
00349 glVertex(v2);
00350 }
00351 glEnd();
00352 }
00353 else
00354 {
00355 glBegin(GL_TRIANGLES);
00356 for ( MeshCore::MeshFacetArray::_TConstIterator it = rFacets.begin(); it != rFacets.end(); ++it )
00357 {
00358 glVertex(rPoints[it->_aulPoints[0]]);
00359 glVertex(rPoints[it->_aulPoints[1]]);
00360 glVertex(rPoints[it->_aulPoints[2]]);
00361 }
00362 glEnd();
00363 }
00364 }
00365
00369 void SoFCMeshNode::drawPoints(SbBool needNormals) const
00370 {
00371
00372
00373 const MeshCore::MeshPointArray& rPoints = _mesh->getKernel().GetPoints();
00374 const MeshCore::MeshFacetArray& rFacets = _mesh->getKernel().GetFacets();
00375 int mod = rFacets.size()/MaximumTriangles+1;
00376
00377 float size = std::min<float>((float)mod,3.0f);
00378 glPointSize(size);
00379
00380 if (needNormals)
00381 {
00382 glBegin(GL_POINTS);
00383 int ct=0;
00384 for ( MeshCore::MeshFacetArray::_TConstIterator it = rFacets.begin(); it != rFacets.end(); ++it, ct++ )
00385 {
00386 if ( ct%mod==0 ) {
00387 const MeshCore::MeshPoint& v0 = rPoints[it->_aulPoints[0]];
00388 const MeshCore::MeshPoint& v1 = rPoints[it->_aulPoints[1]];
00389 const MeshCore::MeshPoint& v2 = rPoints[it->_aulPoints[2]];
00390
00391
00392 float n[3];
00393 n[0] = (v1.y-v0.y)*(v2.z-v0.z)-(v1.z-v0.z)*(v2.y-v0.y);
00394 n[1] = (v1.z-v0.z)*(v2.x-v0.x)-(v1.x-v0.x)*(v2.z-v0.z);
00395 n[2] = (v1.x-v0.x)*(v2.y-v0.y)-(v1.y-v0.y)*(v2.x-v0.x);
00396
00397
00398 float p[3];
00399 p[0] = (v0.x+v1.x+v2.x)/3.0f;
00400 p[1] = (v0.y+v1.y+v2.y)/3.0f;
00401 p[2] = (v0.z+v1.z+v2.z)/3.0f;
00402 glNormal3fv(n);
00403 glVertex3fv(p);
00404 }
00405 }
00406 glEnd();
00407 }
00408 else
00409 {
00410 glBegin(GL_POINTS);
00411 int ct=0;
00412 for ( MeshCore::MeshFacetArray::_TConstIterator it = rFacets.begin(); it != rFacets.end(); ++it, ct++ )
00413 {
00414 if (ct%mod==0) {
00415 const MeshCore::MeshPoint& v0 = rPoints[it->_aulPoints[0]];
00416 const MeshCore::MeshPoint& v1 = rPoints[it->_aulPoints[1]];
00417 const MeshCore::MeshPoint& v2 = rPoints[it->_aulPoints[2]];
00418
00419 float p[3];
00420 p[0] = (v0.x+v1.x+v2.x)/3.0f;
00421 p[1] = (v0.y+v1.y+v2.y)/3.0f;
00422 p[2] = (v0.z+v1.z+v2.z)/3.0f;
00423 glVertex3fv(p);
00424 }
00425 }
00426 glEnd();
00427 }
00428 }
00429
00435 void SoFCMeshNode::generatePrimitives(SoAction* action)
00436 {
00437 if (_mesh)
00438 {
00439
00440
00441 const MeshCore::MeshPointArray& rPoints = _mesh->getKernel().GetPoints();
00442 const MeshCore::MeshFacetArray& rFacets = _mesh->getKernel().GetFacets();
00443
00444
00445 if ( this->MaximumTriangles < rFacets.size() ) {
00446
00447
00448 if ( rFacets.size() != _ctPrimitives ) {
00449 _ctPrimitives = rFacets.size();
00450 createRoughModel(false);
00451 }
00452 SoPrimitiveVertex vertex;
00453 beginShape(action, TRIANGLES, 0);
00454 int i=0;
00455 while ( i<coordIndex.getNum() )
00456 {
00457 const SbVec3f& v0 = point[coordIndex[i++]];
00458 const SbVec3f& v1 = point[coordIndex[i++]];
00459 const SbVec3f& v2 = point[coordIndex[i++]];
00460
00461
00462 SbVec3f n;
00463 n[0] = (v1[1]-v0[1])*(v2[2]-v0[2])-(v1[2]-v0[2])*(v2[1]-v0[1]);
00464 n[1] = (v1[2]-v0[2])*(v2[0]-v0[0])-(v1[0]-v0[0])*(v2[2]-v0[2]);
00465 n[2] = (v1[0]-v0[0])*(v2[1]-v0[1])-(v1[1]-v0[1])*(v2[0]-v0[0]);
00466
00467
00468 vertex.setNormal(n);
00469
00470 vertex.setPoint( v0 );
00471 shapeVertex(&vertex);
00472 vertex.setPoint( v1 );
00473 shapeVertex(&vertex);
00474 vertex.setPoint( v2 );
00475 shapeVertex(&vertex);
00476 }
00477 endShape();
00478 } else {
00479
00480 SoPrimitiveVertex vertex;
00481 SoPointDetail pointDetail;
00482 SoFaceDetail faceDetail;
00483
00484 vertex.setDetail(&pointDetail);
00485
00486 beginShape(action, TRIANGLES, &faceDetail);
00487 for ( MeshCore::MeshFacetArray::_TConstIterator it = rFacets.begin(); it != rFacets.end(); ++it )
00488 {
00489 const MeshCore::MeshPoint& v0 = rPoints[it->_aulPoints[0]];
00490 const MeshCore::MeshPoint& v1 = rPoints[it->_aulPoints[1]];
00491 const MeshCore::MeshPoint& v2 = rPoints[it->_aulPoints[2]];
00492
00493
00494 SbVec3f n;
00495 n[0] = (v1.y-v0.y)*(v2.z-v0.z)-(v1.z-v0.z)*(v2.y-v0.y);
00496 n[1] = (v1.z-v0.z)*(v2.x-v0.x)-(v1.x-v0.x)*(v2.z-v0.z);
00497 n[2] = (v1.x-v0.x)*(v2.y-v0.y)-(v1.y-v0.y)*(v2.x-v0.x);
00498
00499
00500 vertex.setNormal(n);
00501
00502
00503 pointDetail.setCoordinateIndex(it->_aulPoints[0]);
00504 vertex.setPoint(sbvec3f(v0));
00505 shapeVertex(&vertex);
00506
00507
00508 pointDetail.setCoordinateIndex(it->_aulPoints[1]);
00509 vertex.setPoint(sbvec3f(v1));
00510 shapeVertex(&vertex);
00511
00512
00513 pointDetail.setCoordinateIndex(it->_aulPoints[2]);
00514 vertex.setPoint(sbvec3f(v2));
00515 shapeVertex(&vertex);
00516
00517
00518 faceDetail.incFaceIndex();
00519 }
00520
00521 endShape();
00522 }
00523 }
00524 }
00525
00531 SoDetail * SoFCMeshNode::createTriangleDetail(SoRayPickAction * action,
00532 const SoPrimitiveVertex * v1,
00533 const SoPrimitiveVertex * v2,
00534 const SoPrimitiveVertex * v3,
00535 SoPickedPoint * pp)
00536 {
00537 if ( this->MaximumTriangles < countTriangles() ) {
00538 return 0;
00539 } else {
00540 SoDetail* detail = inherited::createTriangleDetail(action, v1, v2, v3, pp);
00541 return detail;
00542 }
00543 }
00544
00548 void SoFCMeshNode::computeBBox(SoAction *action, SbBox3f &box, SbVec3f ¢er)
00549 {
00550
00551 if (countTriangles() > 0) {
00552 const Base::BoundBox3f& cBox = _mesh->getKernel().GetBoundBox();
00553 box.setBounds(SbVec3f(cBox.MinX,cBox.MinY,cBox.MinZ),
00554 SbVec3f(cBox.MaxX,cBox.MaxY,cBox.MaxZ));
00555 Base::Vector3f mid = cBox.CalcCenter();
00556 center.setValue(mid.x,mid.y,mid.z);
00557 }
00558 else {
00559 box.setBounds(SbVec3f(0,0,0), SbVec3f(0,0,0));
00560 center.setValue(0.0f,0.0f,0.0f);
00561 }
00562 }
00563
00567 void SoFCMeshNode::getPrimitiveCount(SoGetPrimitiveCountAction * action)
00568 {
00569 if (!this->shouldPrimitiveCount(action)) return;
00570 action->addNumTriangles(countTriangles());
00571 }
00572
00576 unsigned int SoFCMeshNode::countTriangles() const
00577 {
00578 return (_mesh ? _mesh->countFacets() : 0);
00579 }
00580
00584 void SoFCMeshNode::write( SoWriteAction* action )
00585 {
00586 SoOutput * out = action->getOutput();
00587
00588 if (out->getStage() == SoOutput::COUNT_REFS) {
00589 this->addWriteReference(out, FALSE);
00590 }
00591 else if (out->getStage() == SoOutput::WRITE) {
00592 const MeshCore::MeshPointArray& rPoints = _mesh->getKernel().GetPoints();
00593 const MeshCore::MeshFacetArray& rFacets = _mesh->getKernel().GetFacets();
00594 if (this->writeHeader(out, FALSE, FALSE)) return;
00595 point.setNum(rPoints.size());
00596 unsigned int pos=0;
00597 for (MeshCore::MeshPointArray::_TConstIterator cP=rPoints.begin(); cP!=rPoints.end(); ++cP)
00598 point.set1Value(pos++,cP->x,cP->y,cP->z);
00599 coordIndex.setNum(3*rFacets.size());
00600 pos=0;
00601 for (MeshCore::MeshFacetArray::_TConstIterator cF=rFacets.begin(); cF!=rFacets.end(); ++cF){
00602 coordIndex.set1Value(pos++,cF->_aulPoints[0]);
00603 coordIndex.set1Value(pos++,cF->_aulPoints[1]);
00604 coordIndex.set1Value(pos++,cF->_aulPoints[2]);
00605 }
00606 this->getFieldData()->write(out, this);
00607 this->writeFooter(out);
00608 point.deleteValues(0);
00609 coordIndex.deleteValues(0);
00610 }
00611 }
00612
00616 SbBool SoFCMeshNode::readInstance( SoInput* in, unsigned short flags )
00617 {
00618 SbBool ret = inherited::readInstance(in, flags);
00619
00620 MeshCore::MeshPointArray cPoints;
00621 cPoints.resize(point.getNum());
00622 for (int i=0; i<point.getNum(); ++i) {
00623 const SbVec3f& pt = point[i];
00624 cPoints[i].Set(pt[0],pt[1],pt[2]);
00625 }
00626
00627 MeshCore::MeshFacetArray cFacets;
00628 cFacets.resize(coordIndex.getNum()/3);
00629 unsigned long k=0;
00630 for (int j=0; j<coordIndex.getNum(); ++k) {
00631 cFacets[k]._aulPoints[0] = coordIndex[j++];
00632 cFacets[k]._aulPoints[1] = coordIndex[j++];
00633 cFacets[k]._aulPoints[2] = coordIndex[j++];
00634 }
00635
00636 point.deleteValues(0);
00637 coordIndex.deleteValues(0);
00638
00639 MeshCore::MeshKernel kernel;
00640 kernel.Adopt(cPoints, cFacets, true);
00641 _mesh = new Mesh::MeshObject(kernel);
00642
00643 return ret;
00644 }
00645
00646
00647
00648 SO_NODE_SOURCE(SoFCMeshOpenEdge);
00649
00650 void SoFCMeshOpenEdge::initClass()
00651 {
00652 SO_NODE_INIT_CLASS(SoFCMeshOpenEdge, SoShape, "Shape");
00653 }
00654
00655 SoFCMeshOpenEdge::SoFCMeshOpenEdge() : _mesh(0)
00656 {
00657 SO_NODE_CONSTRUCTOR(SoFCMeshOpenEdge);
00658 }
00659
00663 void SoFCMeshOpenEdge::setMesh(const Mesh::MeshObject* mesh)
00664 {
00665 _mesh = mesh;
00666 }
00667
00671 void SoFCMeshOpenEdge::GLRender(SoGLRenderAction *action)
00672 {
00673 if (_mesh && shouldGLRender(action))
00674 {
00675 SoState* state = action->getState();
00676
00677 SoMaterialBundle mb(action);
00678 SoTextureCoordinateBundle tb(action, TRUE, FALSE);
00679 SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR);
00680 mb.sendFirst();
00681
00682 drawLines();
00683
00684
00685 SoGLCacheContextElement::shouldAutoCache(state, SoGLCacheContextElement::DONT_AUTO_CACHE);
00686 }
00687 }
00688
00692 void SoFCMeshOpenEdge::drawLines() const
00693 {
00694
00695
00696 const MeshCore::MeshPointArray& rPoints = _mesh->getKernel().GetPoints();
00697 const MeshCore::MeshFacetArray& rFacets = _mesh->getKernel().GetFacets();
00698
00699
00700 GLfloat lineWidth;
00701 glGetFloatv(GL_LINE_WIDTH, &lineWidth);
00702 glLineWidth(3.0f*lineWidth);
00703
00704
00705 glBegin(GL_LINES);
00706 for ( MeshCore::MeshFacetArray::_TConstIterator it = rFacets.begin(); it != rFacets.end(); ++it ) {
00707 for ( int i=0; i<3; i++ ) {
00708 if ( it->_aulNeighbours[i] == ULONG_MAX ) {
00709 glVertex(rPoints[it->_aulPoints[i]]);
00710 glVertex(rPoints[it->_aulPoints[(i+1)%3]]);
00711 }
00712 }
00713 }
00714
00715 glEnd();
00716 }
00717
00718 void SoFCMeshOpenEdge::generatePrimitives(SoAction* action)
00719 {
00720
00721 }
00722
00726 void SoFCMeshOpenEdge::computeBBox(SoAction *action, SbBox3f &box, SbVec3f ¢er)
00727 {
00728
00729 if (_mesh) {
00730 const Base::BoundBox3f& cBox = _mesh->getKernel().GetBoundBox();
00731 box.setBounds(SbVec3f(cBox.MinX,cBox.MinY,cBox.MinZ),
00732 SbVec3f(cBox.MaxX,cBox.MaxY,cBox.MaxZ));
00733 Base::Vector3f mid = cBox.CalcCenter();
00734 center.setValue(mid.x,mid.y,mid.z);
00735 }
00736 else {
00737 box.setBounds(SbVec3f(0,0,0), SbVec3f(0,0,0));
00738 center.setValue(0.0f,0.0f,0.0f);
00739 }
00740 }
00741
00745 void SoFCMeshOpenEdge::getPrimitiveCount(SoGetPrimitiveCountAction * action)
00746 {
00747 if (!this->shouldPrimitiveCount(action)) return;
00748
00749
00750 int ctEdges=0;
00751
00752 const MeshCore::MeshFacetArray& rFaces = _mesh->getKernel().GetFacets();
00753 for ( MeshCore::MeshFacetArray::_TConstIterator jt = rFaces.begin(); jt != rFaces.end(); ++jt ) {
00754 for ( int i=0; i<3; i++ ) {
00755 if ( jt->_aulNeighbours[i] == ULONG_MAX ) {
00756 ctEdges++;
00757 }
00758 }
00759 }
00760
00761 action->addNumLines(ctEdges);
00762 }