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 <float.h>
00036 # include <algorithm>
00037 # include <Inventor/SoPickedPoint.h>
00038 # include <Inventor/actions/SoCallbackAction.h>
00039 # include <Inventor/actions/SoGetBoundingBoxAction.h>
00040 # include <Inventor/actions/SoGetPrimitiveCountAction.h>
00041 # include <Inventor/actions/SoGLRenderAction.h>
00042 # include <Inventor/actions/SoPickAction.h>
00043 # include <Inventor/actions/SoWriteAction.h>
00044 # include <Inventor/bundles/SoMaterialBundle.h>
00045 # include <Inventor/bundles/SoTextureCoordinateBundle.h>
00046 # include <Inventor/elements/SoOverrideElement.h>
00047 # include <Inventor/elements/SoCoordinateElement.h>
00048 # include <Inventor/elements/SoGLCoordinateElement.h>
00049 # include <Inventor/elements/SoGLCacheContextElement.h>
00050 # include <Inventor/elements/SoLineWidthElement.h>
00051 # include <Inventor/elements/SoPointSizeElement.h>
00052 # include <Inventor/errors/SoReadError.h>
00053 # include <Inventor/details/SoFaceDetail.h>
00054 # include <Inventor/details/SoLineDetail.h>
00055 # include <Inventor/misc/SoState.h>
00056 #endif
00057
00058 #include "SoBrepShape.h"
00059 #include <Gui/SoFCUnifiedSelection.h>
00060 #include <Gui/SoFCSelectionAction.h>
00061
00062 using namespace PartGui;
00063
00064
00065 SO_NODE_SOURCE(SoBrepFaceSet);
00066
00067 void SoBrepFaceSet::initClass()
00068 {
00069 SO_NODE_INIT_CLASS(SoBrepFaceSet, SoIndexedFaceSet, "IndexedFaceSet");
00070 }
00071
00072 SoBrepFaceSet::SoBrepFaceSet()
00073 {
00074 SO_NODE_CONSTRUCTOR(SoBrepFaceSet);
00075 SO_NODE_ADD_FIELD(partIndex, (-1));
00076 SO_NODE_ADD_FIELD(highlightIndex, (-1));
00077 SO_NODE_ADD_FIELD(selectionIndex, (-1));
00078 selectionIndex.setNum(0);
00079 }
00080
00081 void SoBrepFaceSet::doAction(SoAction* action)
00082 {
00083 if (action->getTypeId() == Gui::SoHighlightElementAction::getClassTypeId()) {
00084 Gui::SoHighlightElementAction* hlaction = static_cast<Gui::SoHighlightElementAction*>(action);
00085 if (!hlaction->isHighlighted()) {
00086 this->highlightIndex = -1;
00087 return;
00088 }
00089
00090 const SoPickedPoint* pp = hlaction->getElement();
00091 if (pp && pp->getDetail()) {
00092 const SoDetail* detail = pp->getDetail();
00093 if (detail->isOfType(SoFaceDetail::getClassTypeId())) {
00094 int index = static_cast<const SoFaceDetail*>(detail)->getPartIndex();
00095 this->highlightIndex.setValue(index);
00096 this->highlightColor = hlaction->getColor();
00097 }
00098 else {
00099 this->highlightIndex = -1;
00100 return;
00101 }
00102 }
00103 }
00104 else if (action->getTypeId() == Gui::SoSelectionElementAction::getClassTypeId()) {
00105 Gui::SoSelectionElementAction* selaction = static_cast<Gui::SoSelectionElementAction*>(action);
00106 this->selectionColor = selaction->getColor();
00107 if (selaction->getType() == Gui::SoSelectionElementAction::All) {
00108 int num = this->partIndex.getNum();
00109 this->selectionIndex.setNum(num);
00110 int32_t* v = this->selectionIndex.startEditing();
00111 for (int i=0; i<num;i++)
00112 v[i] = i;
00113 this->selectionIndex.finishEditing();
00114 return;
00115 }
00116 else if (selaction->getType() == Gui::SoSelectionElementAction::None) {
00117 this->selectionIndex.setNum(0);
00118 return;
00119 }
00120
00121 const SoPickedPoint* pp = selaction->getElement();
00122 if (pp && pp->getDetail()) {
00123 const SoDetail* detail = pp->getDetail();
00124
00125 if (!detail->isOfType(SoFaceDetail::getClassTypeId())) {
00126 return;
00127 }
00128
00129 int index = static_cast<const SoFaceDetail*>(detail)->getPartIndex();
00130 switch (selaction->getType()) {
00131 case Gui::SoSelectionElementAction::Append:
00132 {
00133 int start = this->selectionIndex.getNum();
00134 this->selectionIndex.set1Value(start, index);
00135 }
00136 break;
00137 case Gui::SoSelectionElementAction::Remove:
00138 {
00139 int start = this->selectionIndex.find(index);
00140 this->selectionIndex.deleteValues(start,1);
00141 }
00142 break;
00143 default:
00144 break;
00145 }
00146 }
00147 }
00148
00149 inherited::doAction(action);
00150 }
00151
00152 void SoBrepFaceSet::GLRender(SoGLRenderAction *action)
00153 {
00154 if (this->coordIndex.getNum() < 3)
00155 return;
00156 if (this->selectionIndex.getNum() > 0)
00157 renderSelection(action);
00158 if (this->highlightIndex.getValue() >= 0)
00159 renderHighlight(action);
00160 if (!this->shouldGLRender(action))
00161 return;
00162
00163 SoState * state = action->getState();
00164
00165 Binding mbind = this->findMaterialBinding(state);
00166 Binding nbind = this->findNormalBinding(state);
00167
00168 const SoCoordinateElement * coords;
00169 const SbVec3f * normals;
00170 const int32_t * cindices;
00171 int numindices;
00172 const int32_t * nindices;
00173 const int32_t * tindices;
00174 const int32_t * mindices;
00175 const int32_t * pindices;
00176 int numparts;
00177 SbBool doTextures;
00178 SbBool normalCacheUsed;
00179
00180 SoMaterialBundle mb(action);
00181
00182 SoTextureCoordinateBundle tb(action, TRUE, FALSE);
00183 doTextures = tb.needCoordinates();
00184 SbBool sendNormals = !mb.isColorOnly() || tb.isFunction();
00185
00186 this->getVertexData(state, coords, normals, cindices,
00187 nindices, tindices, mindices, numindices,
00188 sendNormals, normalCacheUsed);
00189
00190 mb.sendFirst();
00191
00192
00193 if (!mindices) mindices = cindices;
00194 if (!nindices) nindices = cindices;
00195 pindices = this->partIndex.getValues(0);
00196 numparts = this->partIndex.getNum();
00197 renderShape(static_cast<const SoGLCoordinateElement*>(coords), cindices, numindices,
00198 pindices, numparts, normals, nindices, &mb, mindices, &tb, tindices, nbind, mbind, doTextures?1:0);
00199
00200 SoGLCacheContextElement::shouldAutoCache(state, SoGLCacheContextElement::DONT_AUTO_CACHE);
00201
00202
00203
00204 if (this->highlightIndex.getValue() >= 0)
00205 renderHighlight(action);
00206 if (this->selectionIndex.getNum() > 0)
00207 renderSelection(action);
00208
00209 }
00210
00211 void SoBrepFaceSet::GLRenderBelowPath(SoGLRenderAction * action)
00212 {
00213 inherited::GLRenderBelowPath(action);
00214 }
00215
00216 void SoBrepFaceSet::renderHighlight(SoGLRenderAction *action)
00217 {
00218 SoState * state = action->getState();
00219 state->push();
00220
00221 SoLazyElement::setEmissive(state, &this->highlightColor);
00222 SoOverrideElement::setEmissiveColorOverride(state, this, TRUE);
00223 #if 0 // disables shading effect
00224
00225 SoLazyElement::setDiffuse(state, this,1, &this->highlightColor,&this->colorpacker);
00226 SoOverrideElement::setDiffuseColorOverride(state, this, TRUE);
00227 SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR);
00228 #endif
00229
00230 Binding mbind = this->findMaterialBinding(state);
00231 Binding nbind = this->findNormalBinding(state);
00232
00233 const SoCoordinateElement * coords;
00234 const SbVec3f * normals;
00235 const int32_t * cindices;
00236 int numindices;
00237 const int32_t * nindices;
00238 const int32_t * tindices;
00239 const int32_t * mindices;
00240 const int32_t * pindices;
00241 SbBool doTextures;
00242 SbBool normalCacheUsed;
00243
00244 SoMaterialBundle mb(action);
00245 SoTextureCoordinateBundle tb(action, TRUE, FALSE);
00246 doTextures = tb.needCoordinates();
00247 SbBool sendNormals = !mb.isColorOnly() || tb.isFunction();
00248
00249 this->getVertexData(state, coords, normals, cindices,
00250 nindices, tindices, mindices, numindices,
00251 sendNormals, normalCacheUsed);
00252
00253 mb.sendFirst();
00254
00255 int32_t id = this->highlightIndex.getValue();
00256
00257
00258 if (!mindices) mindices = cindices;
00259 if (!nindices) nindices = cindices;
00260 pindices = this->partIndex.getValues(0);
00261
00262
00263 int length = (int)pindices[id]*4;
00264 int start=0;
00265 for (int i=0;i<id;i++)
00266 start+=(int)pindices[i];
00267 start *= 4;
00268
00269
00270 if (nbind == PER_VERTEX_INDEXED)
00271 nindices = &(nindices[start]);
00272 else if (nbind == PER_VERTEX)
00273 normals = &(normals[start]);
00274 else
00275 nbind = OVERALL;
00276
00277
00278 mbind = OVERALL;
00279 doTextures = FALSE;
00280
00281 renderShape(static_cast<const SoGLCoordinateElement*>(coords), &(cindices[start]), length,
00282 &(pindices[id]), 1, normals, nindices, &mb, mindices, &tb, tindices, nbind, mbind, doTextures?1:0);
00283 state->pop();
00284 }
00285
00286 void SoBrepFaceSet::renderSelection(SoGLRenderAction *action)
00287 {
00288 int numSelected = this->selectionIndex.getNum();
00289 const int32_t* selected = this->selectionIndex.getValues(0);
00290 if (numSelected == 0) return;
00291
00292 SoState * state = action->getState();
00293 state->push();
00294
00295 SoLazyElement::setEmissive(state, &this->selectionColor);
00296 SoOverrideElement::setEmissiveColorOverride(state, this, TRUE);
00297 #if 0 // disables shading effect
00298 SoLazyElement::setDiffuse(state, this,1, &this->selectionColor,&this->colorpacker);
00299 SoOverrideElement::setDiffuseColorOverride(state, this, TRUE);
00300 SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR);
00301 #endif
00302
00303 Binding mbind = this->findMaterialBinding(state);
00304 Binding nbind = this->findNormalBinding(state);
00305
00306 const SoCoordinateElement * coords;
00307 const SbVec3f * normals;
00308 const int32_t * cindices;
00309 int numindices;
00310 const int32_t * nindices;
00311 const int32_t * tindices;
00312 const int32_t * mindices;
00313 const int32_t * pindices;
00314 SbBool doTextures;
00315 SbBool normalCacheUsed;
00316
00317 SoMaterialBundle mb(action);
00318 SoTextureCoordinateBundle tb(action, TRUE, FALSE);
00319 doTextures = tb.needCoordinates();
00320 SbBool sendNormals = !mb.isColorOnly() || tb.isFunction();
00321
00322 this->getVertexData(state, coords, normals, cindices,
00323 nindices, tindices, mindices, numindices,
00324 sendNormals, normalCacheUsed);
00325
00326 mb.sendFirst();
00327
00328
00329 if (!mindices) mindices = cindices;
00330 if (!nindices) nindices = cindices;
00331 pindices = this->partIndex.getValues(0);
00332
00333
00334 mbind = OVERALL;
00335 doTextures = FALSE;
00336
00337 for (int i=0; i<numSelected; i++) {
00338 int id = selected[i];
00339
00340
00341 int length = (int)pindices[id]*4;
00342 int start=0;
00343 for (int j=0;j<id;j++)
00344 start+=(int)pindices[j];
00345 start *= 4;
00346
00347
00348 const SbVec3f * normals_s = normals;
00349 const int32_t * nindices_s = nindices;
00350 if (nbind == PER_VERTEX_INDEXED)
00351 nindices_s = &(nindices[start]);
00352 else if (nbind == PER_VERTEX)
00353 normals_s = &(normals[start]);
00354 else
00355 nbind = OVERALL;
00356
00357 renderShape(static_cast<const SoGLCoordinateElement*>(coords), &(cindices[start]), length,
00358 &(pindices[id]), 1, normals_s, nindices_s, &mb, mindices, &tb, tindices, nbind, mbind, doTextures?1:0);
00359 }
00360 state->pop();
00361 }
00362
00363 void SoBrepFaceSet::renderShape(const SoGLCoordinateElement * const vertexlist,
00364 const int32_t *vertexindices,
00365 int numindices,
00366 const int32_t *partindices,
00367 int num_partindices,
00368 const SbVec3f *normals,
00369 const int32_t *normalindices,
00370 SoMaterialBundle *const materials,
00371 const int32_t *matindices,
00372 SoTextureCoordinateBundle * const texcoords,
00373 const int32_t *texindices,
00374 const int nbind,
00375 const int mbind,
00376 const int texture)
00377 {
00378 int texidx = 0;
00379
00380 const SbVec3f * coords3d = NULL;
00381 coords3d = vertexlist->getArrayPtr3();
00382
00383 const int32_t *viptr = vertexindices;
00384 const int32_t *viendptr = viptr + numindices;
00385 const int32_t *piptr = partindices;
00386 const int32_t *piendptr = piptr + num_partindices;
00387 int32_t v1, v2, v3, v4, pi;
00388 SbVec3f dummynormal(0,0,1);
00389 int numverts = vertexlist->getNum();
00390
00391 const SbVec3f *currnormal = &dummynormal;
00392 if (normals) currnormal = normals;
00393
00394 int matnr = 0;
00395 int trinr = 0;
00396 pi = piptr < piendptr ? *piptr++ : -1;
00397
00398 glBegin(GL_TRIANGLES);
00399 while (viptr + 2 < viendptr) {
00400 v1 = *viptr++;
00401 v2 = *viptr++;
00402 v3 = *viptr++;
00403
00404
00405 if (v1 < 0 || v2 < 0 || v3 < 0 ||
00406 v1 >= numverts || v2 >= numverts || v3 >= numverts) {
00407 break;
00408 }
00409 v4 = viptr < viendptr ? *viptr++ : -1;
00410
00411
00412 if (mbind == PER_PART) {
00413 if (trinr == 0)
00414 materials->send(matnr++, TRUE);
00415 }
00416 else if (mbind == PER_PART_INDEXED) {
00417 if (trinr == 0)
00418 materials->send(*matindices++, TRUE);
00419 }
00420 else if (mbind == PER_VERTEX || mbind == PER_FACE) {
00421 materials->send(matnr++, TRUE);
00422 }
00423 else if (mbind == PER_VERTEX_INDEXED || mbind == PER_FACE_INDEXED) {
00424 materials->send(*matindices++, TRUE);
00425 }
00426
00427 if (normals) {
00428 if (nbind == PER_VERTEX || nbind == PER_FACE) {
00429 currnormal = normals++;
00430 glNormal3fv((const GLfloat*)currnormal);
00431 }
00432 else if (nbind == PER_VERTEX_INDEXED || nbind == PER_FACE_INDEXED) {
00433 currnormal = &normals[*normalindices++];
00434 glNormal3fv((const GLfloat*)currnormal);
00435 }
00436 }
00437
00438 if (texture) {
00439 texcoords->send(texindices ? *texindices++ : texidx++,
00440 vertexlist->get3(v1),
00441 *currnormal);
00442 }
00443
00444 glVertex3fv((const GLfloat*) (coords3d + v1));
00445
00446
00447 if (mbind == PER_VERTEX)
00448 materials->send(matnr++, TRUE);
00449 else if (mbind == PER_VERTEX_INDEXED)
00450 materials->send(*matindices++, TRUE);
00451
00452 if (normals) {
00453 if (nbind == PER_VERTEX) {
00454 currnormal = normals++;
00455 glNormal3fv((const GLfloat*)currnormal);
00456 }
00457 else if (nbind == PER_VERTEX_INDEXED) {
00458 currnormal = &normals[*normalindices++];
00459 glNormal3fv((const GLfloat*)currnormal);
00460 }
00461 }
00462
00463 if (texture) {
00464 texcoords->send(texindices ? *texindices++ : texidx++,
00465 vertexlist->get3(v2),
00466 *currnormal);
00467 }
00468
00469 glVertex3fv((const GLfloat*) (coords3d + v2));
00470
00471
00472 if (mbind == PER_VERTEX)
00473 materials->send(matnr++, TRUE);
00474 else if (mbind == PER_VERTEX_INDEXED)
00475 materials->send(*matindices++, TRUE);
00476
00477 if (normals) {
00478 if (nbind == PER_VERTEX) {
00479 currnormal = normals++;
00480 glNormal3fv((const GLfloat*)currnormal);
00481 }
00482 else if (nbind == PER_VERTEX_INDEXED) {
00483 currnormal = &normals[*normalindices++];
00484 glNormal3fv((const GLfloat*)currnormal);
00485 }
00486 }
00487
00488 if (texture) {
00489 texcoords->send(texindices ? *texindices++ : texidx++,
00490 vertexlist->get3(v3),
00491 *currnormal);
00492 }
00493
00494 glVertex3fv((const GLfloat*) (coords3d + v3));
00495
00496 if (mbind == PER_VERTEX_INDEXED)
00497 matindices++;
00498
00499 if (nbind == PER_VERTEX_INDEXED)
00500 normalindices++;
00501
00502 if (texture && texindices) {
00503 texindices++;
00504 }
00505
00506 trinr++;
00507 if (pi == trinr) {
00508 pi = piptr < piendptr ? *piptr++ : -1;
00509 trinr = 0;
00510 }
00511 }
00512 glEnd();
00513 }
00514
00515 SoDetail * SoBrepFaceSet::createTriangleDetail(SoRayPickAction * action,
00516 const SoPrimitiveVertex * v1,
00517 const SoPrimitiveVertex * v2,
00518 const SoPrimitiveVertex * v3,
00519 SoPickedPoint * pp)
00520 {
00521 SoDetail* detail = inherited::createTriangleDetail(action, v1, v2, v3, pp);
00522 const int32_t * indices = this->partIndex.getValues(0);
00523 int num = this->partIndex.getNum();
00524 if (indices) {
00525 SoFaceDetail* face_detail = static_cast<SoFaceDetail*>(detail);
00526 int index = face_detail->getFaceIndex();
00527 int count = 0;
00528 for (int i=0; i<num; i++) {
00529 count += indices[i];
00530 if (index < count) {
00531 face_detail->setPartIndex(i);
00532 break;
00533 }
00534 }
00535 }
00536 return detail;
00537 }
00538
00539 SoBrepFaceSet::Binding
00540 SoBrepFaceSet::findMaterialBinding(SoState * const state) const
00541 {
00542 Binding binding = OVERALL;
00543 SoMaterialBindingElement::Binding matbind =
00544 SoMaterialBindingElement::get(state);
00545
00546 switch (matbind) {
00547 case SoMaterialBindingElement::OVERALL:
00548 binding = OVERALL;
00549 break;
00550 case SoMaterialBindingElement::PER_VERTEX:
00551 binding = PER_VERTEX;
00552 break;
00553 case SoMaterialBindingElement::PER_VERTEX_INDEXED:
00554 binding = PER_VERTEX_INDEXED;
00555 break;
00556 case SoMaterialBindingElement::PER_PART:
00557 binding = PER_PART;
00558 break;
00559 case SoMaterialBindingElement::PER_FACE:
00560 binding = PER_FACE;
00561 break;
00562 case SoMaterialBindingElement::PER_PART_INDEXED:
00563 binding = PER_PART_INDEXED;
00564 break;
00565 case SoMaterialBindingElement::PER_FACE_INDEXED:
00566 binding = PER_FACE_INDEXED;
00567 break;
00568 default:
00569 break;
00570 }
00571 return binding;
00572 }
00573
00574 SoBrepFaceSet::Binding
00575 SoBrepFaceSet::findNormalBinding(SoState * const state) const
00576 {
00577 Binding binding = PER_VERTEX_INDEXED;
00578 SoNormalBindingElement::Binding normbind =
00579 (SoNormalBindingElement::Binding) SoNormalBindingElement::get(state);
00580
00581 switch (normbind) {
00582 case SoNormalBindingElement::OVERALL:
00583 binding = OVERALL;
00584 break;
00585 case SoNormalBindingElement::PER_VERTEX:
00586 binding = PER_VERTEX;
00587 break;
00588 case SoNormalBindingElement::PER_VERTEX_INDEXED:
00589 binding = PER_VERTEX_INDEXED;
00590 break;
00591 case SoNormalBindingElement::PER_PART:
00592 binding = PER_PART;
00593 break;
00594 case SoNormalBindingElement::PER_FACE:
00595 binding = PER_FACE;
00596 break;
00597 case SoNormalBindingElement::PER_PART_INDEXED:
00598 binding = PER_PART_INDEXED;
00599 break;
00600 case SoNormalBindingElement::PER_FACE_INDEXED:
00601 binding = PER_FACE_INDEXED;
00602 break;
00603 default:
00604 break;
00605 }
00606 return binding;
00607 }
00608
00609
00610
00611 SO_NODE_SOURCE(SoBrepEdgeSet);
00612
00613 void SoBrepEdgeSet::initClass()
00614 {
00615 SO_NODE_INIT_CLASS(SoBrepEdgeSet, SoIndexedLineSet, "IndexedLineSet");
00616 }
00617
00618 SoBrepEdgeSet::SoBrepEdgeSet()
00619 {
00620 SO_NODE_CONSTRUCTOR(SoBrepEdgeSet);
00621 SO_NODE_ADD_FIELD(highlightIndex, (-1));
00622 SO_NODE_ADD_FIELD(selectionIndex, (-1));
00623 selectionIndex.setNum(0);
00624 }
00625
00626 void SoBrepEdgeSet::GLRender(SoGLRenderAction *action)
00627 {
00628 if (this->selectionIndex.getNum() > 0)
00629 renderSelection(action);
00630 if (this->highlightIndex.getValue() >= 0)
00631 renderHighlight(action);
00632 inherited::GLRender(action);
00633
00634
00635
00636 if (this->highlightIndex.getValue() >= 0)
00637 renderHighlight(action);
00638 if (this->selectionIndex.getNum() > 0)
00639 renderSelection(action);
00640
00641 }
00642
00643 void SoBrepEdgeSet::GLRenderBelowPath(SoGLRenderAction * action)
00644 {
00645 inherited::GLRenderBelowPath(action);
00646 }
00647
00648 void SoBrepEdgeSet::renderShape(const SoGLCoordinateElement * const coords,
00649 const int32_t *cindices, int numindices)
00650 {
00651
00652 const SbVec3f * coords3d = coords->getArrayPtr3();
00653
00654 int32_t i;
00655 int previ;
00656 const int32_t *end = cindices + numindices;
00657 while (cindices < end) {
00658 glBegin(GL_LINE_STRIP);
00659 previ = *cindices++;
00660 i = (cindices < end) ? *cindices++ : -1;
00661 while (i >= 0) {
00662 glVertex3fv((const GLfloat*) (coords3d + previ));
00663 glVertex3fv((const GLfloat*) (coords3d + i));
00664 previ = i;
00665 i = cindices < end ? *cindices++ : -1;
00666 }
00667 glEnd();
00668 }
00669 }
00670
00671 void SoBrepEdgeSet::renderHighlight(SoGLRenderAction *action)
00672 {
00673 SoState * state = action->getState();
00674 state->push();
00675
00676
00677 SoLazyElement::setEmissive(state, &this->highlightColor);
00678 SoOverrideElement::setEmissiveColorOverride(state, this, TRUE);
00679 SoLazyElement::setDiffuse(state, this,1, &this->highlightColor,&this->colorpacker);
00680 SoOverrideElement::setDiffuseColorOverride(state, this, TRUE);
00681 SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR);
00682
00683 const SoCoordinateElement * coords;
00684 const SbVec3f * normals;
00685 const int32_t * cindices;
00686 int numcindices;
00687 const int32_t * nindices;
00688 const int32_t * tindices;
00689 const int32_t * mindices;
00690 SbBool normalCacheUsed;
00691
00692 this->getVertexData(state, coords, normals, cindices, nindices,
00693 tindices, mindices, numcindices, FALSE, normalCacheUsed);
00694
00695 SoMaterialBundle mb(action);
00696 mb.sendFirst();
00697
00698 const int32_t* id = &(this->hl[0]);
00699 int num = (int)this->hl.size();
00700
00701 renderShape(static_cast<const SoGLCoordinateElement*>(coords), id, num);
00702 state->pop();
00703 }
00704
00705 void SoBrepEdgeSet::renderSelection(SoGLRenderAction *action)
00706 {
00707 int numSelected = this->selectionIndex.getNum();
00708 if (numSelected == 0) return;
00709
00710 SoState * state = action->getState();
00711 state->push();
00712
00713
00714 SoLazyElement::setEmissive(state, &this->selectionColor);
00715 SoOverrideElement::setEmissiveColorOverride(state, this, TRUE);
00716 SoLazyElement::setDiffuse(state, this,1, &this->selectionColor,&this->colorpacker);
00717 SoOverrideElement::setDiffuseColorOverride(state, this, TRUE);
00718 SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR);
00719
00720 const SoCoordinateElement * coords;
00721 const SbVec3f * normals;
00722 const int32_t * cindices;
00723 int numcindices;
00724 const int32_t * nindices;
00725 const int32_t * tindices;
00726 const int32_t * mindices;
00727 SbBool normalCacheUsed;
00728
00729 this->getVertexData(state, coords, normals, cindices, nindices,
00730 tindices, mindices, numcindices, FALSE, normalCacheUsed);
00731
00732 SoMaterialBundle mb(action);
00733 mb.sendFirst();
00734
00735 cindices = &(this->sl[0]);
00736 numcindices = (int)this->sl.size();
00737
00738 renderShape(static_cast<const SoGLCoordinateElement*>(coords), cindices, numcindices);
00739 state->pop();
00740 }
00741
00742 static void createIndexArray(const int32_t* segm, int numsegm,
00743 const int32_t* cindices, int numcindices,
00744 std::vector<int32_t>& out)
00745 {
00746 std::vector<int32_t> v;
00747 for (int j=0; j<numsegm; j++) {
00748 int index = segm[j];
00749 int start=0, num=0;
00750 int section=0;
00751 for (int i=0;i<numcindices;i++) {
00752 if (section < index)
00753 start++;
00754 else if (section == index)
00755 num++;
00756 else if (section > index)
00757 break;
00758 if (cindices[i] < 0)
00759 section++;
00760 }
00761
00762 v.insert(v.end(), cindices+start, cindices+start+num);
00763 }
00764
00765 out.swap(v);
00766 }
00767
00768 void SoBrepEdgeSet::doAction(SoAction* action)
00769 {
00770 if (action->getTypeId() == Gui::SoHighlightElementAction::getClassTypeId()) {
00771 Gui::SoHighlightElementAction* hlaction = static_cast<Gui::SoHighlightElementAction*>(action);
00772 if (!hlaction->isHighlighted()) {
00773 this->highlightIndex = -1;
00774 this->hl.clear();
00775 return;
00776 }
00777 const SoPickedPoint* pp = hlaction->getElement();
00778 if (pp && pp->getDetail()) {
00779 const SoDetail* detail = pp->getDetail();
00780 if (!detail->isOfType(SoLineDetail::getClassTypeId())) {
00781 this->highlightIndex = -1;
00782 this->hl.clear();
00783 return;
00784 }
00785
00786 this->highlightColor = hlaction->getColor();
00787 int32_t index = static_cast<const SoLineDetail*>(detail)->getLineIndex();
00788 const int32_t* cindices = this->coordIndex.getValues(0);
00789 int numcindices = this->coordIndex.getNum();
00790
00791 createIndexArray(&index, 1, cindices, numcindices, this->hl);
00792 this->highlightIndex.setValue(index);
00793 }
00794 }
00795 else if (action->getTypeId() == Gui::SoSelectionElementAction::getClassTypeId()) {
00796 Gui::SoSelectionElementAction* selaction = static_cast<Gui::SoSelectionElementAction*>(action);
00797
00798 this->selectionColor = selaction->getColor();
00799 if (selaction->getType() == Gui::SoSelectionElementAction::All) {
00800 const int32_t* cindices = this->coordIndex.getValues(0);
00801 int numcindices = this->coordIndex.getNum();
00802 unsigned int num = std::count_if(cindices, cindices+numcindices,
00803 std::bind2nd(std::equal_to<int32_t>(), -1));
00804
00805 this->sl.clear();
00806 this->selectionIndex.setNum(num);
00807 int32_t* v = this->selectionIndex.startEditing();
00808 for (unsigned int i=0; i<num;i++)
00809 v[i] = i;
00810 this->selectionIndex.finishEditing();
00811
00812 int numsegm = this->selectionIndex.getNum();
00813 if (numsegm > 0) {
00814 const int32_t* selsegm = this->selectionIndex.getValues(0);
00815 const int32_t* cindices = this->coordIndex.getValues(0);
00816 int numcindices = this->coordIndex.getNum();
00817 createIndexArray(selsegm, numsegm, cindices, numcindices, this->sl);
00818 }
00819 return;
00820 }
00821 else if (selaction->getType() == Gui::SoSelectionElementAction::None) {
00822 this->selectionIndex.setNum(0);
00823 this->sl.clear();
00824 return;
00825 }
00826
00827 const SoPickedPoint* pp = selaction->getElement();
00828 if (pp && pp->getDetail()) {
00829 const SoDetail* detail = pp->getDetail();
00830 if (!detail->isOfType(SoLineDetail::getClassTypeId())) {
00831 return;
00832 }
00833
00834 int index = static_cast<const SoLineDetail*>(detail)->getLineIndex();
00835 switch (selaction->getType()) {
00836 case Gui::SoSelectionElementAction::Append:
00837 {
00838 int start = this->selectionIndex.getNum();
00839 this->selectionIndex.set1Value(start, index);
00840 }
00841 break;
00842 case Gui::SoSelectionElementAction::Remove:
00843 {
00844 int start = this->selectionIndex.find(index);
00845 this->selectionIndex.deleteValues(start,1);
00846 }
00847 break;
00848 default:
00849 break;
00850 }
00851
00852 int numsegm = this->selectionIndex.getNum();
00853 if (numsegm > 0) {
00854 const int32_t* selsegm = this->selectionIndex.getValues(0);
00855 const int32_t* cindices = this->coordIndex.getValues(0);
00856 int numcindices = this->coordIndex.getNum();
00857 createIndexArray(selsegm, numsegm, cindices, numcindices, this->sl);
00858 }
00859 }
00860 }
00861
00862 inherited::doAction(action);
00863 }
00864
00865 SoDetail * SoBrepEdgeSet::createLineSegmentDetail(SoRayPickAction * action,
00866 const SoPrimitiveVertex * v1,
00867 const SoPrimitiveVertex * v2,
00868 SoPickedPoint * pp)
00869 {
00870 SoDetail* detail = inherited::createLineSegmentDetail(action, v1, v2, pp);
00871 SoLineDetail* line_detail = static_cast<SoLineDetail*>(detail);
00872 int index = line_detail->getLineIndex();
00873 line_detail->setPartIndex(index);
00874 return detail;
00875 }
00876
00877
00878
00879 SO_NODE_SOURCE(SoBrepPointSet);
00880
00881 void SoBrepPointSet::initClass()
00882 {
00883 SO_NODE_INIT_CLASS(SoBrepPointSet, SoPointSet, "PointSet");
00884 }
00885
00886 SoBrepPointSet::SoBrepPointSet()
00887 {
00888 SO_NODE_CONSTRUCTOR(SoBrepPointSet);
00889 SO_NODE_ADD_FIELD(highlightIndex, (-1));
00890 SO_NODE_ADD_FIELD(selectionIndex, (-1));
00891 selectionIndex.setNum(0);
00892 }
00893
00894 void SoBrepPointSet::GLRender(SoGLRenderAction *action)
00895 {
00896 if (this->selectionIndex.getNum() > 0)
00897 renderSelection(action);
00898 if (this->highlightIndex.getValue() >= 0)
00899 renderHighlight(action);
00900 inherited::GLRender(action);
00901
00902
00903
00904 if (this->highlightIndex.getValue() >= 0)
00905 renderHighlight(action);
00906 if (this->selectionIndex.getNum() > 0)
00907 renderSelection(action);
00908
00909 }
00910
00911 void SoBrepPointSet::GLRenderBelowPath(SoGLRenderAction * action)
00912 {
00913 inherited::GLRenderBelowPath(action);
00914 }
00915
00916 void SoBrepPointSet::renderShape(const SoGLCoordinateElement * const coords,
00917 const int32_t *cindices,
00918 int numindices)
00919 {
00920 const SbVec3f * coords3d = coords->getArrayPtr3();
00921
00922 int previ;
00923 const int32_t *end = cindices + numindices;
00924 glBegin(GL_POINTS);
00925 while (cindices < end) {
00926 previ = *cindices++;
00927 glVertex3fv((const GLfloat*) (coords3d + previ));
00928 }
00929 glEnd();
00930 }
00931
00932 void SoBrepPointSet::renderHighlight(SoGLRenderAction *action)
00933 {
00934 SoState * state = action->getState();
00935 state->push();
00936 float ps = SoPointSizeElement::get(state);
00937 if (ps < 4.0f) SoPointSizeElement::set(state, this, 4.0f);
00938
00939 SoLazyElement::setEmissive(state, &this->highlightColor);
00940 SoOverrideElement::setEmissiveColorOverride(state, this, TRUE);
00941 SoLazyElement::setDiffuse(state, this,1, &this->highlightColor,&this->colorpacker);
00942 SoOverrideElement::setDiffuseColorOverride(state, this, TRUE);
00943
00944 const SoCoordinateElement * coords;
00945 const SbVec3f * normals;
00946
00947 this->getVertexData(state, coords, normals, FALSE);
00948
00949 SoMaterialBundle mb(action);
00950 mb.sendFirst();
00951
00952 int32_t id = this->highlightIndex.getValue();
00953
00954 renderShape(static_cast<const SoGLCoordinateElement*>(coords), &id, 1);
00955 state->pop();
00956 }
00957
00958 void SoBrepPointSet::renderSelection(SoGLRenderAction *action)
00959 {
00960 SoState * state = action->getState();
00961 state->push();
00962 float ps = SoPointSizeElement::get(state);
00963 if (ps < 4.0f) SoPointSizeElement::set(state, this, 4.0f);
00964
00965 SoLazyElement::setEmissive(state, &this->selectionColor);
00966 SoOverrideElement::setEmissiveColorOverride(state, this, TRUE);
00967 SoLazyElement::setDiffuse(state, this,1, &this->selectionColor,&this->colorpacker);
00968 SoOverrideElement::setDiffuseColorOverride(state, this, TRUE);
00969
00970 const SoCoordinateElement * coords;
00971 const SbVec3f * normals;
00972 const int32_t * cindices;
00973 int numcindices;
00974
00975 this->getVertexData(state, coords, normals, FALSE);
00976
00977 SoMaterialBundle mb(action);
00978 mb.sendFirst();
00979
00980 cindices = this->selectionIndex.getValues(0);
00981 numcindices = this->selectionIndex.getNum();
00982
00983 renderShape(static_cast<const SoGLCoordinateElement*>(coords), cindices, numcindices);
00984 state->pop();
00985 }
00986
00987 void SoBrepPointSet::doAction(SoAction* action)
00988 {
00989 if (action->getTypeId() == Gui::SoHighlightElementAction::getClassTypeId()) {
00990 Gui::SoHighlightElementAction* hlaction = static_cast<Gui::SoHighlightElementAction*>(action);
00991 if (!hlaction->isHighlighted()) {
00992 this->highlightIndex = -1;
00993 return;
00994 }
00995 const SoPickedPoint* pp = hlaction->getElement();
00996 if (pp && pp->getDetail()) {
00997 const SoDetail* detail = pp->getDetail();
00998 if (!detail->isOfType(SoPointDetail::getClassTypeId())) {
00999 this->highlightIndex = -1;
01000 return;
01001 }
01002
01003 int index = static_cast<const SoPointDetail*>(detail)->getCoordinateIndex();
01004 this->highlightIndex.setValue(index);
01005 this->highlightColor = hlaction->getColor();
01006 }
01007 }
01008 else if (action->getTypeId() == Gui::SoSelectionElementAction::getClassTypeId()) {
01009 Gui::SoSelectionElementAction* selaction = static_cast<Gui::SoSelectionElementAction*>(action);
01010 this->selectionColor = selaction->getColor();
01011 if (selaction->getType() == Gui::SoSelectionElementAction::All) {
01012 const SoCoordinateElement* coords = SoCoordinateElement::getInstance(action->getState());
01013 int num = coords->getNum() - this->startIndex.getValue();
01014 this->selectionIndex.setNum(num);
01015 int32_t* v = this->selectionIndex.startEditing();
01016 int32_t s = this->startIndex.getValue();
01017 for (int i=0; i<num;i++)
01018 v[i] = i + s;
01019 this->selectionIndex.finishEditing();
01020 return;
01021 }
01022 else if (selaction->getType() == Gui::SoSelectionElementAction::None) {
01023 this->selectionIndex.setNum(0);
01024 return;
01025 }
01026
01027 const SoPickedPoint* pp = selaction->getElement();
01028 if (pp && pp->getDetail()) {
01029 const SoDetail* detail = pp->getDetail();
01030 if (!detail->isOfType(SoPointDetail::getClassTypeId())) {
01031 return;
01032 }
01033
01034 int index = static_cast<const SoPointDetail*>(detail)->getCoordinateIndex();
01035 switch (selaction->getType()) {
01036 case Gui::SoSelectionElementAction::Append:
01037 {
01038 int start = this->selectionIndex.getNum();
01039 this->selectionIndex.set1Value(start, index);
01040 }
01041 break;
01042 case Gui::SoSelectionElementAction::Remove:
01043 {
01044 int start = this->selectionIndex.find(index);
01045 this->selectionIndex.deleteValues(start,1);
01046 }
01047 break;
01048 default:
01049 break;
01050 }
01051 }
01052 }
01053
01054 inherited::doAction(action);
01055 }