1 /*
2  * NodeIndexedFaceSet.cpp
3  *
4  * Copyright (C) 1999 Stephen F. White, 2018 J. "MUFTI" Scheurich
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program (see the file "COPYING" for details); if
18  * not, write to the Free Software Foundation, Inc., 675 Mass Ave,
19  * Cambridge, MA 02139, USA.
20  */
21 
22 // if this file is compiled with CGAL: CGAL is licenced under different
23 // licences including GNU General Public License 3
24 
25 // if this file is compiled with VCG: VCG is licenced under
26 // GNU General Public License 3
27 
28 #include <stdio.h>
29 #include <string.h>
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <fcntl.h>
33 #include <errno.h>
34 
35 #include <algorithm>
36 
37 #include "stdafx.h"
38 
39 #include "NodeIndexedFaceSet.h"
40 #include "Proto.h"
41 #include "Scene.h"
42 #include "FieldValue.h"
43 #include "Node.h"
44 #include "MyMesh.h"
45 #include "FaceData.h"
46 #include "Vec3f.h"
47 #include "NodeColor.h"
48 #include "NodeColorRGBA.h"
49 #include "NodeCoordinate.h"
50 #include "NodeGeoCoordinate.h"
51 #include "NodeNormal.h"
52 #include "NodeTextureCoordinate.h"
53 #include "NodeIndexedLineSet.h"
54 #include "NodeShape.h"
55 #include "NodeFogCoordinate.h"
56 #include "Util.h"
57 #include "MoveCommand.h"
58 #include "Field.h"
59 #include "resource.h"
60 #include "Path.h"
61 #include "MyString.h"
62 
63 class FaceVec {
64     int m_face;
65     Vec3f m_vec;
66 public:
FaceVec(int face,Vec3f vec)67     FaceVec(int face, Vec3f vec) {
68         m_face = face;
69         m_vec = vec;
70     }
getFace(void)71     int getFace(void) { return m_face; }
getVec(void)72     Vec3f getVec(void) { return m_vec; }
73 };
74 
75 MyArray<FaceVec *> m_faces;
76 
ProtoIndexedFaceSet(Scene * scene)77 ProtoIndexedFaceSet::ProtoIndexedFaceSet(Scene *scene)
78   : GeometryProto(scene, "IndexedFaceSet")
79 {
80     color.set(
81           addExposedField(SFNODE, "color", new SFNode(NULL), COLOR_NODE));
82     coord.set(
83           addExposedField(SFNODE, "coord", new SFNode(NULL), COORDINATE_NODE));
84     normal.set(
85           addExposedField(SFNODE, "normal", new SFNode(NULL), VRML_NORMAL));
86     texCoord.set(
87           addExposedField(SFNODE, "texCoord", new SFNode(NULL),
88                           TEXTURE_COORDINATE_NODE));
89     if (TheApp->getCoverMode()) {
90         // non standard Covise/COVER extensions
91         texCoord2.set(
92           addExposedField(SFNODE, "texCoord2", new SFNode(NULL),
93                           TEXTURE_COORDINATE_NODE));
94         setFieldFlags(texCoord2, FF_COVER_ONLY);
95         texCoord3.set(
96           addExposedField(SFNODE, "texCoord3", new SFNode(NULL),
97                           TEXTURE_COORDINATE_NODE));
98         setFieldFlags(texCoord3, FF_COVER_ONLY);
99         texCoord4.set(
100           addExposedField(SFNODE, "texCoord4", new SFNode(NULL),
101                           TEXTURE_COORDINATE_NODE));
102         setFieldFlags(texCoord4, FF_COVER_ONLY);
103     }
104     ccw.set(
105           addField(SFBOOL, "ccw", new SFBool(true)));
106     setFieldFlags(ccw, FF_4KIDS);
107     colorIndex.set(
108           addField(MFINT32, "colorIndex", new MFInt32(), new SFInt32(-1)));
109     colorPerVertex.set(
110           addField(SFBOOL, "colorPerVertex", new SFBool(true)));
111     convex.set(
112           addField(SFBOOL, "convex", new SFBool(true)));
113     coordIndex.set(
114           addField(MFINT32, "coordIndex", new MFInt32(), new SFInt32(-1)));
115     creaseAngle.set(
116           addField(SFFLOAT, "creaseAngle", new SFFloat(0.0),
117                    new SFFloat(0.0f)));
118     setFieldFlags(creaseAngle, FF_4KIDS);
119     normalIndex.set(
120           addField(MFINT32, "normalIndex", new MFInt32(), new SFInt32(-1)));
121     normalPerVertex.set(
122           addField(SFBOOL, "normalPerVertex", new SFBool(true)));
123     solid.set(
124           addField(SFBOOL, "solid", new SFBool(true)));
125     setFieldFlags(solid, FF_4KIDS);
126     texCoordIndex.set(
127           addField(MFINT32, "texCoordIndex", new MFInt32(), new SFInt32(-1)));
128     if (TheApp->getCoverMode()) {
129         // non standard Covise/COVER extensions
130         texCoordIndex2.set(
131           addField(MFINT32, "texCoordIndex2", new MFInt32(), new SFInt32(-1)));
132         setFieldFlags(texCoordIndex2, FF_COVER_ONLY);
133         texCoordIndex3.set(
134           addField(MFINT32, "texCoordIndex3", new MFInt32(), new SFInt32(-1)));
135         setFieldFlags(texCoordIndex3, FF_COVER_ONLY);
136         texCoordIndex4.set(
137           addField(MFINT32, "texCoordIndex4", new MFInt32(), new SFInt32(-1)));
138         setFieldFlags(texCoordIndex4, FF_COVER_ONLY);
139     }
140     ComposedGeometryElements()
141     x3domGeometryCommonFields()
142     normalUpdateMode.set(
143       addExposedField(SFSTRING, "normalUpdateMode", new SFString("fast")));
144     setFieldFlags(normalUpdateMode, FF_X3DOM_ONLY);
145     addEventIn(MFINT32, "set_colorIndex", 0, colorIndex);
146     addEventIn(MFINT32, "set_coordIndex", 0, coordIndex);
147     addEventIn(MFINT32, "set_normalIndex", 0, normalIndex);
148     addEventIn(MFINT32, "set_texCoordIndex", 0, texCoordIndex);
149 }
150 
151 Node *
create(Scene * scene)152 ProtoIndexedFaceSet::create(Scene *scene)
153 {
154       Node *node = new NodeIndexedFaceSet(scene, this);
155       return node;
156 }
157 
NodeIndexedFaceSet(Scene * scene,Proto * def)158 NodeIndexedFaceSet::NodeIndexedFaceSet(Scene *scene, Proto *def)
159   : MeshBasedNode(scene, def)
160 {
161      m_alreadyInChangeColorPerVertex = false;
162 }
163 
~NodeIndexedFaceSet()164 NodeIndexedFaceSet::~NodeIndexedFaceSet()
165 {
166 }
167 
168 void
draw()169 NodeIndexedFaceSet::draw()
170 {
171     Node *ncoord = coord()->getValue();
172     if (ncoord != NULL) {
173         glPushName(coord_Field());       // field coord
174         glPushName(0);                   // index 0
175         if (ncoord->getType() == VRML_COORDINATE)
176             ((NodeCoordinate *)ncoord)->draw(this);
177         else if (ncoord->getType() == VRML_GEO_COORDINATE) {
178             setDoubleMesh(true);
179             ((NodeGeoCoordinate *)ncoord)->draw(this);
180         }
181         glPopName();
182         glPopName();
183     }
184 }
185 
186 void
setField(int index,FieldValue * value,int cf)187 NodeIndexedFaceSet::setField(int index, FieldValue *value, int cf)
188 {
189     m_meshDirty = true;
190     if (index == colorPerVertexField()) {
191         bool bColorPerVertex = ((SFBool *)value)->getValue();
192         if (bColorPerVertex && !colorPerVertex()->getValue())
193             changeToColorPerVertex();
194         if (!bColorPerVertex && colorPerVertex()->getValue())
195             changeToColorPerFace();
196     }
197     Node::setField(index, value, cf);
198 }
199 
200 void
addToConvertedNodes(int flags)201 NodeIndexedFaceSet::addToConvertedNodes(int flags)
202 {
203     if (m_already_converted)
204         return;
205     m_already_converted = true;
206     if (flags & TRIANGULATE) {
207         if (!canSimpleTriangulate() || !hasBranchInputs()) {
208             MeshBasedNode::addToConvertedNodes(flags);
209             setAlreadyConverted();
210             m_meshDirty = true;
211             return;
212         }
213     }
214     if (getHumanoid() != NULL)
215         return;
216     NodeIndexedFaceSet *node = (NodeIndexedFaceSet *)this->copy();
217     node->setVariableName(strdup(this->getVariableName()));
218     m_scene->copyRoutes(node, this);
219     if (coord()->getValue() != NULL) {
220         Node *target = node->coord()->getValue();
221         m_scene->copyRoutes(target, this->coord()->getValue());
222         target->addParent(node, node->coord_Field());
223 
224     }
225     if (normal()->getValue() != NULL) {
226         Node *target = node->normal()->getValue();
227         target->setVariableName(strdup(target->getVariableName()));
228         m_scene->copyRoutes(target, this->normal()->getValue());
229         target->addParent(node,  node->normal_Field());
230     }
231     if (color()->getValue() != NULL) {
232         Node *target = node->color()->getValue();
233         m_scene->copyRoutes(target, this->color()->getValue());
234         target->addParent(node,  node->color_Field());
235     }
236     if (texCoord()->getValue() != NULL) {
237         Node *target = node->texCoord()->getValue();
238         m_scene->copyRoutes(target, this->texCoord()->getValue());
239         target->addParent(node,  node->texCoord_Field());
240     }
241     if (fogCoord()->getValue() != NULL) {
242         Node *target = node->fogCoord()->getValue();
243         m_scene->copyRoutes(target, this->fogCoord()->getValue());
244         target->addParent(node,  node->fogCoord_Field());
245     }
246 
247     if (m_convertedNodes.size() != 0)
248         return;
249     m_meshDirty = true;
250     m_mesh = NULL;
251 
252     node->createMesh(false);
253     if (normal()->getValue() == NULL) {
254         MFVec3f *smoothNormals = node->getSmoothNormals();
255         if (smoothNormals && (smoothNormals->getValues() != NULL)) {
256             NodeNormal *normals = (NodeNormal *)m_scene->createNode("Normal");
257             normals->vector(new MFVec3f((MFVec3f *)smoothNormals->copy()));
258             m_scene->setField(node, normal_Field(), new SFNode(normals));
259             MFInt32 *smoothNormalIndex = node->getSmoothNormalIndex();
260             m_scene->setField(node, normalIndex_Field(),
261                              new MFInt32((MFInt32 *)smoothNormalIndex->copy()));
262         }
263     }
264     MyMesh *mesh = node->simpleQuadTriangulateMesh();
265     MFInt32 *mfcoordIndex = mesh->getCoordIndex();
266     if (mfcoordIndex && (mfcoordIndex->getValues() != NULL)) {
267         mfcoordIndex = (MFInt32 *)mfcoordIndex->copy();
268         m_scene->setField(node, coordIndex_Field(), new MFInt32(mfcoordIndex));
269     }
270     MFInt32 *mfnormalIndex = mesh->getNormalIndex();
271     if (mfnormalIndex && (mfnormalIndex->getValues() != NULL)) {
272         mfnormalIndex = (MFInt32 *)mfnormalIndex->copy();
273         m_scene->setField(node, normalIndex_Field(), new MFInt32(mfnormalIndex));
274     }
275     MFInt32 *mfcolorIndex = mesh->getColorIndex();
276     if (mfcolorIndex && (mfcolorIndex->getValues() != NULL) &&
277         (mfcolorIndex != mesh->getCoordIndex())) {
278         mfcolorIndex = (MFInt32 *)mfcolorIndex->copy();
279         m_scene->setField(node, colorIndex_Field(), new MFInt32(mfcolorIndex));
280     }
281     MFInt32 *mftexCoordIndex = mesh->getTexCoordIndex();
282     if (mftexCoordIndex && (mftexCoordIndex->getValues() != NULL) &&
283         (mftexCoordIndex != mesh->getCoordIndex())) {
284         mftexCoordIndex = (MFInt32 *)mftexCoordIndex->copy();
285         m_scene->setField(node, texCoordIndex_Field(),
286                          new MFInt32(mftexCoordIndex));
287     }
288     m_convertedNodes.append(node);
289     node->setAlreadyConverted();
290     node->addParent(getParent(), getParentField());
291     return;
292 }
293 
294 
295 MFVec3f *
getCoordinates()296 NodeIndexedFaceSet::getCoordinates()
297 {
298     Node *ncoord = coord()->getValue();
299     if (ncoord == NULL)
300         return NULL;
301     else
302         return ((NodeCoordinate *)ncoord)->point();
303 }
304 
305 MFInt32 *
getCoordIndex()306 NodeIndexedFaceSet::getCoordIndex()
307 {
308     return coordIndex();
309 }
310 
311 MFInt32 *
getColorIndex()312 NodeIndexedFaceSet::getColorIndex()
313 {
314     return colorIndex();
315 }
316 
317 MFInt32 *
getNormalIndex()318 NodeIndexedFaceSet::getNormalIndex()
319 {
320     return normalIndex();
321 }
322 
323 MFVec2f *
getTextureCoordinates()324 NodeIndexedFaceSet::getTextureCoordinates()
325 {
326     Node *ntexCoord = texCoord()->getValue();
327     if (ntexCoord == NULL)
328         return NULL;
329     else
330         return ((NodeTextureCoordinate *)ntexCoord)->point();
331 }
332 
333 MFInt32 *
getTexCoordIndex()334 NodeIndexedFaceSet::getTexCoordIndex()
335 {
336     return texCoordIndex();
337 }
338 
339 void
createMesh(bool cleanDoubleVertices,bool triangulate)340 NodeIndexedFaceSet::createMesh(bool cleanDoubleVertices, bool triangulate)
341 {
342     Node *coord = ((SFNode *) getField(coord_Field()))->getValue();
343     bool bcolorPerVertex = colorPerVertex() ?
344                            colorPerVertex()->getValue() : true;
345     bool bnormalPerVertex = normalPerVertex() ?
346                             normalPerVertex()->getValue() : true;
347     MFInt32 *colorIndex = getColorIndex();
348     MFInt32 *coordIndex = getCoordIndex();
349     MFInt32 *normalIndex = getNormalIndex();
350     MFInt32 *texCoordIndex = getTexCoordIndex();
351 
352     if (!coord)
353         return;
354 
355     MFVec3f *normals = NULL;
356     MFFloat *colors = NULL;
357 
358     if (normal() && normal()->getValue())
359         if (normal()->getValue()->getType() == VRML_NORMAL)
360             normals = ((NodeNormal *)(normal()->getValue()))->vector();
361 
362     int meshFlags = 0;
363     if (color() && color()->getValue()) {
364         if (color()->getValue()->getType() == VRML_COLOR)
365             colors = ((NodeColor *)(color()->getValue()))->color();
366         else if (color()->getValue()->getType() == X3D_COLOR_RGBA) {
367             colors = ((NodeColorRGBA *)(color()->getValue()))->color();
368             meshFlags |= MESH_COLOR_RGBA;
369         }
370     }
371 
372     MFFloat *fogCoords = NULL;
373     if (fogCoord() && fogCoord()->getValue())
374         if (fogCoord()->getValue()->getType() == X3D_FOG_COORDINATE)
375             fogCoords = ((NodeFogCoordinate *)
376                          (fogCoord()->getValue()))->depth();
377 
378     MyArray<MFVec2f *> texCoords;
379     if (texCoord())
380         Util::getTexCoords(texCoords, texCoord()->getValue());
381 
382     if (bcolorPerVertex)
383         if (colorIndex && colorIndex->getSize() != coordIndex->getSize())
384             colorIndex = NULL;
385     if (texCoordIndex && texCoordIndex->getSize() != coordIndex->getSize())
386         texCoordIndex = NULL;
387     if (bnormalPerVertex)
388         if (normalIndex && normalIndex->getSize() != coordIndex->getSize())
389             normalIndex = NULL;
390     float transparency = 0;
391     if (hasParent())
392         transparency = getParent()->getTransparency();
393     if (ccw() && ccw()->getValue())
394         meshFlags |= MESH_CCW;
395     if (solid() && solid()->getValue())
396         meshFlags |= MESH_SOLID;
397     if (convex() && convex()->getValue())
398         meshFlags |= MESH_CONVEX;
399     if (bcolorPerVertex)
400         meshFlags |= MESH_COLOR_PER_VERTEX;
401     if (bnormalPerVertex)
402         meshFlags |= MESH_NORMAL_PER_VERTEX;
403     if (coord->getType() == VRML_COORDINATE) {
404         MFVec3f *coords = ((NodeCoordinate *)coord)->point();
405         m_mesh = new MyMesh(this, coords, coordIndex, normals, normalIndex,
406                             colors, colorIndex, texCoords, texCoordIndex,
407                             creaseAngle()->getFixedAngle(
408                                 m_scene->getUnitAngle()),
409                             meshFlags, transparency, fogCoords);
410         m_isDoubleMesh = false;
411     } else if (coord->getType() == VRML_GEO_COORDINATE) {
412         MFVec3d *coords = ((NodeGeoCoordinate *)coord)->pointX3D();
413         m_meshDouble = new MyMeshDouble(this, coords, coordIndex, normals,
414                                         normalIndex, colors, colorIndex,
415                                         texCoords, texCoordIndex,
416                                         creaseAngle()->getFixedAngle(
417                                             m_scene->getUnitAngle()),
418                                         meshFlags, transparency, fogCoords);
419         m_isDoubleMesh = true;
420     }
421 }
422 
423 Node *
toIndexedLineSet(void)424 NodeIndexedFaceSet::toIndexedLineSet(void)
425 {
426     if (m_mesh == NULL)
427         return NULL;
428     NodeCoordinate *ncoord = (NodeCoordinate *)m_scene->createNode("Coordinate");
429     ncoord->point(new MFVec3f((MFVec3f *)m_mesh->getVertices()->copy()));
430     NodeIndexedLineSet *node = (NodeIndexedLineSet *)
431                                m_scene->createNode("IndexedLineSet");
432     node->coord(new SFNode(ncoord));
433     node->coordIndex(new MFInt32((MFInt32 *)m_mesh->getCoordIndex()->copy()));
434     return node;
435 }
436 
437 void
flip(int index)438 NodeIndexedFaceSet::flip(int index)
439 {
440     NodeCoordinate *ncoord = (NodeCoordinate *)coord()->getValue();
441     if (ncoord)
442         if (ncoord->getType() == VRML_COORDINATE)
443             ncoord->flip(index);
444     NodeNormal *nnormal = (NodeNormal *)normal()->getValue();
445     if (nnormal)
446         if (nnormal->getType() == VRML_NORMAL)
447             nnormal->flip(index);
448     SFBool *bccw = new SFBool(!(ccw()->getValue()));
449     ccw(bccw);
450     m_meshDirty = true;
451 }
452 
453 void
swap(int fromTo)454 NodeIndexedFaceSet::swap(int fromTo)
455 {
456     NodeCoordinate *ncoord = (NodeCoordinate *)coord()->getValue();
457     if (ncoord)
458         if (ncoord->getType() == VRML_COORDINATE)
459              ncoord->swap(fromTo);
460     NodeNormal *nnormal = (NodeNormal *)normal()->getValue();
461     if (nnormal)
462         if (nnormal->getType() == VRML_NORMAL)
463             nnormal->swap(fromTo);
464     SFBool *bccw = new SFBool(!(ccw()->getValue()));
465     ccw(bccw);
466     m_meshDirty = true;
467 }
468 
469 void
setNormalFromMesh(Node * nnormal)470 NodeIndexedFaceSet::setNormalFromMesh(Node *nnormal)
471 {
472     if (nnormal->getType() != VRML_NORMAL)
473         return;
474 
475     if (meshDirty() || (m_mesh == NULL)) {
476         createMesh();
477         m_meshDirty = false;
478     }
479 
480     if (m_mesh == NULL)
481         return;
482 
483     MFVec3f *v = m_mesh->getNormals();
484     if (v != NULL) {
485         ((NodeNormal *)nnormal)->vector(v);
486         MFInt32 *ni = m_mesh->getNormalIndex();
487         if (ni != NULL)
488             normalIndex(ni);
489         normalPerVertex(new SFBool(true));
490     }
491 }
492 
493 void
setTexCoordFromMesh(Node * ntexCoord)494 NodeIndexedFaceSet::setTexCoordFromMesh(Node *ntexCoord)
495 {
496     if (ntexCoord->getType() != VRML_TEXTURE_COORDINATE)
497         return;
498     if (m_mesh == NULL)
499         return;
500     MFVec2f *v = m_mesh->generateTextureCoordinates();
501     if (v != NULL) {
502         ((NodeTextureCoordinate *)ntexCoord)->point(v);
503         MFInt32 *ni = (MFInt32 *)getTexCoordIndex()->copy();
504         if (ni != NULL)
505             texCoordIndex(ni);
506     }
507 }
508 
509 void
optimize(void)510 NodeIndexedFaceSet::optimize(void)
511 {
512     MFVec3f *mfVertices = NULL;
513     MFInt32 *mfCoordIndex = NULL;
514     optimizeMesh(&mfVertices, &mfCoordIndex);
515     if (mfVertices && mfCoordIndex) {
516         NodeCoordinate *ncoord = (NodeCoordinate *)coord()->getValue();
517         m_scene->backupFieldsStart();
518         m_scene->backupFieldsAppend(ncoord, ncoord->point_Field());
519         m_scene->backupFieldsAppend(this, coordIndex_Field());
520         m_scene->backupFieldsDone();
521 
522         ncoord->point(new MFVec3f(*mfVertices));
523         coordIndex(new MFInt32(*mfCoordIndex));
524     }
525 }
526 
527 void
optimizeCoordIndex(void)528 NodeIndexedFaceSet::optimizeCoordIndex(void)
529 {
530     MyMesh *mesh = getMesh();
531     mesh->optimizeCoordIndex();
532     m_scene->backupField(this, coordIndex_Field());
533     MFInt32 *ci = new MFInt32((MFInt32 *)mesh->getCoordIndex()->copy());
534     m_scene->setField(this, coordIndex_Field(), ci);
535     m_meshDirty = true;
536 }
537 
538 NodeIndexedFaceSet *
splitSelectedFaces(void)539 NodeIndexedFaceSet::splitSelectedFaces(void)
540 {
541     bool bccw = ccw()->getValue();
542     bool bsolid = solid()->getValue();
543     bool bconvex = convex()->getValue();
544     float fcreaseAngle = creaseAngle()->getValue();
545     if (m_scene->getSelectionMode() != SELECTION_MODE_FACES)
546         return NULL;
547     MFVec3f *newVertices = new MFVec3f();
548     MFInt32 *newCoordIndex = new MFInt32();
549     MFVec3f *splitVertices = new MFVec3f();
550     MFInt32 *splitCoordIndex = new MFInt32();
551     NodeCoordinate *ncoord = (NodeCoordinate *)coord()->getValue();
552     if (ncoord == NULL)
553         return NULL;
554     int numNewCoordIndex = 0;
555     int numSplitCoordIndex = 0;
556     for (int i = 0; i < getMesh()->getNumFaces(); i++) {
557         FaceData *face = getMesh()->getFace(i);
558         int offset = face->getOffset();
559         int numVertices = face->getNumVertices();
560         bool addedNew = false;
561         bool addedSplit = false;
562         for (int j = 0; j < numVertices; j++) {
563             int ci = coordIndex()->getValue(offset + j);
564             if (m_scene->isInSelectedHandles(i)) {
565                 newVertices->appendSFValue(ncoord->point()->getValue(ci));
566                 newCoordIndex->appendSFValue(numNewCoordIndex++);
567                 addedNew = true;
568             } else {
569                 splitVertices->appendSFValue(ncoord->point()->getValue(ci));
570                 splitCoordIndex->appendSFValue(numSplitCoordIndex++);
571                 addedSplit = true;
572             }
573         }
574         if (addedNew)
575             newCoordIndex->appendSFValue(-1);
576         if (addedSplit)
577             splitCoordIndex->appendSFValue(-1);
578     }
579     if (newVertices && newCoordIndex && hasParent()) {
580         Node *parent = getParent();
581         Node *grandParent = parent->getParent();
582         if (grandParent == NULL)
583             return NULL;
584         int grandParentField = parent->getParentField();
585         if (grandParent->getProto()->getField(grandParentField)->getType() !=
586             MFNODE)
587             return NULL;
588         NodeIndexedFaceSet *newFaceSet = (NodeIndexedFaceSet *)
589                                          m_scene->createNode("IndexedFaceSet");
590         NodeCoordinate *coord = (NodeCoordinate *)
591                                 m_scene->createNode("Coordinate");
592         coord->point(new MFVec3f(newVertices));
593 
594         newFaceSet->coordIndex(new MFInt32(newCoordIndex));
595         newFaceSet->ccw(new SFBool(bccw));
596         newFaceSet->solid(new SFBool(bsolid));
597         newFaceSet->convex(new SFBool(bconvex));
598         newFaceSet->creaseAngle(new SFFloat(fcreaseAngle));
599 
600         NodeIndexedFaceSet *splitFaceSet = (NodeIndexedFaceSet *)
601                                            m_scene->createNode("IndexedFaceSet");
602         NodeCoordinate *ncoord = (NodeCoordinate *)
603                                  m_scene->createNode("Coordinate");
604         splitFaceSet->coord(new SFNode(ncoord));
605         ncoord->point(new MFVec3f(splitVertices));
606         splitFaceSet->coordIndex(new MFInt32(splitCoordIndex));
607 
608         MFVec3f *mfVertices = NULL;
609         MFInt32 *mfCoordIndex = NULL;
610         splitFaceSet->optimizeMesh(&mfVertices, &mfCoordIndex);
611         if (mfVertices && mfCoordIndex) {
612             ncoord->point(new MFVec3f(*mfVertices));
613             splitFaceSet->coordIndex(new MFInt32(*mfCoordIndex));
614             splitFaceSet->ccw(new SFBool(bccw));
615             splitFaceSet->solid(new SFBool(bsolid));
616             splitFaceSet->convex(new SFBool(bconvex));
617             splitFaceSet->creaseAngle(new SFFloat(fcreaseAngle));
618             NodeShape *newShape = (NodeShape *) m_scene->createNode("Shape");
619             NodeMaterial *newMaterial = (NodeMaterial *)
620                                         m_scene->createNode("Material");
621             NodeAppearance *newAppearance = (NodeAppearance *)
622                                             m_scene->createNode("Appearance");
623             newFaceSet->coord(new SFNode(coord));
624 
625             m_scene->execute(new MoveCommand(newShape, NULL, -1,
626                                              grandParent, grandParentField));
627             m_scene->execute(new MoveCommand(newAppearance, NULL, -1,
628                                              newShape,
629                                              newShape->appearance_Field()));
630             m_scene->execute(new MoveCommand(newMaterial, NULL, -1,
631                                              newAppearance,
632                                              newAppearance->material_Field()));
633             m_scene->execute(new MoveCommand(newFaceSet, NULL, -1,
634                                              newShape,
635                                              newShape->geometry_Field()));
636             return splitFaceSet;
637         }
638     }
639     return NULL;
640 }
641 
642 bool
checkBorderMidPoint(int icoordIndex,MyArray<int> symFaces)643 NodeIndexedFaceSet::checkBorderMidPoint(int icoordIndex, MyArray<int> symFaces)
644 {
645     int verticesCount = 0;
646     NodeCoordinate *ncoord = (NodeCoordinate *)coord()->getValue();
647     if (ncoord == NULL)
648         return true;
649     if (icoordIndex < 0)
650         return true;
651     Vec3f vec1(ncoord->point()->getVec(icoordIndex));
652     for (int i = 0; i < getMesh()->getNumFaces(); i++) {
653         if (!(m_scene->isInSelectedHandles(i) || symFaces.contains(i)))
654             continue;
655         FaceData *face = getMesh()->getFace(i);
656         int offset = face->getOffset();
657         int numVertices = face->getNumVertices();
658         for (int j = offset; j < offset + numVertices; j++) {
659             int ci = coordIndex()->getValue(j);
660             Vec3f vec2(ncoord->point()->getVec(ci));
661             if ((vec1 - vec2).length() == 0.0f)
662                 verticesCount++;
663         }
664     }
665     return verticesCount > 3;
666 }
667 
668 bool
checkBorderFace(MyArray<int> innerBorder,MyArray<int> outerBorder,MFInt32 * coordIndex,int borderIndex1,int borderIndex2,MyArray<int> symFaces,bool sym)669 NodeIndexedFaceSet::checkBorderFace(MyArray<int> innerBorder,
670                                     MyArray<int> outerBorder, MFInt32 *coordIndex,
671                                     int borderIndex1, int borderIndex2,
672                                     MyArray<int> symFaces, bool sym)
673 {
674     NodeCoordinate *ncoord = (NodeCoordinate *)coord()->getValue();
675     if (ncoord == NULL)
676         return false;
677     if (checkBorderMidPoint(outerBorder[borderIndex1], symFaces) ||
678         checkBorderMidPoint(outerBorder[borderIndex2], symFaces))
679         return false;
680     if (outerBorder[borderIndex1] < 0)
681         return true;
682     if (outerBorder[borderIndex2] < 0)
683         return true;
684     Vec3f vec11(ncoord->point()->getVec(outerBorder[borderIndex1]));
685     Vec3f vec12(ncoord->point()->getVec(outerBorder[borderIndex2]));
686     for (long j = 0; j < (long)innerBorder.size() - 1; j++) {
687         int n = j + 1;
688         if (innerBorder[j] == -1)
689             continue;
690         if (innerBorder[n] == -1)
691             continue;
692         if ((j != borderIndex2) && (n != borderIndex1)) {
693             Vec3f vec21(ncoord->point()->getVec(outerBorder[j]));
694             Vec3f vec22(ncoord->point()->getVec(outerBorder[n]));
695             if (((vec22 - vec11).length() == 0) &&
696                 ((vec21 - vec12).length() == 0))
697                 return false;
698         }
699     }
700     return true;
701 }
702 
compareVectors(Vec3f vec,Vec3f vec2)703 static bool compareVectors(Vec3f vec, Vec3f vec2)
704 {
705      bool ret = true;
706      float epsilon = TheApp->GetHandleEpsilon();
707      if ((fabs(vec.x + vec2.x) > epsilon) ||
708          (fabs(vec.y - vec2.y) > epsilon) ||
709          (fabs(vec.z - vec2.z) > epsilon)) {
710          return false;
711      }
712      return ret;
713 }
714 
715 
comparePermutation(MyArray<int> intArrayCi,MyArray<int> intArrayPerm,MFVec3f * mfvec)716 static bool comparePermutation(MyArray<int> intArrayCi,
717                                MyArray<int> intArrayPerm, MFVec3f *mfvec)
718 {
719     bool ret = true;
720     int *arr = new int[intArrayPerm.size()];
721     for (int i = 0; i < intArrayPerm.size(); i++)
722         arr[i] = intArrayPerm[i];
723     std::sort(arr, arr + intArrayPerm.size());
724     do {
725         bool vectorsEqual = true;
726         for (int i = 0; i < intArrayPerm.size(); i++)
727         for (int i = 0; i < intArrayPerm.size(); i++) {
728              if (!compareVectors(mfvec->getValue(intArrayCi[i]),
729                                  mfvec->getValue(arr[i]))) {
730                  vectorsEqual = false;
731                  break;
732              }
733         }
734         if (vectorsEqual) {
735             delete [] arr;
736             return true;
737         }
738     } while (std::next_permutation(arr, arr + intArrayPerm.size()));
739     bool vectorsEqual = true;
740         for (int i = 0; i < intArrayPerm.size(); i++)
741     for (int i = 0; i < intArrayPerm.size(); i++) {
742          if (!compareVectors(mfvec->getValue(intArrayCi[i]),
743                              mfvec->getValue(arr[i]))) {
744              vectorsEqual = false;
745              break;
746         }
747     }
748     if (vectorsEqual) {
749         delete [] arr;
750         return true;
751     }
752     delete [] arr;
753     return false;
754 }
755 
756 int
symetricFace(int iface)757 NodeIndexedFaceSet::symetricFace(int iface)
758 {
759     NodeCoordinate *ncoord = (NodeCoordinate *)coord()->getValue();
760     if (ncoord == NULL)
761         return -1;
762     FaceData *face = getMesh()->getFace(iface);
763     int offset = face->getOffset();
764     int numVertices = face->getNumVertices();
765     int numFaces = getMesh()->getNumFaces();
766     for (int i = 0; i < numFaces; i++) {
767         if (i == iface)
768             continue;
769         FaceData *face2 = getMesh()->getFace(i);
770         int offset2 = face2->getOffset();
771         int numVertices2 = face2->getNumVertices();
772         if (numVertices != numVertices2)
773             continue;
774         MyArray<int> intArrayCi;
775         for (int j = 0; j < numVertices; j++) {
776              int ci = coordIndex()->getValue(offset + j);
777              intArrayCi.append(ci);
778         }
779         MyArray<int> intArrayPerm;
780         for (int n = 0; n < numVertices; n++) {
781             int ci2 = coordIndex()->getValue(offset2 + n);
782             intArrayPerm.append(ci2);
783         }
784         if (comparePermutation(intArrayCi, intArrayPerm, ncoord->point()))
785             return i;
786      }
787      return -1;
788 }
789 
790 void
deleteFaces(MFInt32 * coordIndex,MyArray<int> * facesToDelete)791 NodeIndexedFaceSet::deleteFaces(MFInt32 *coordIndex,
792                                 MyArray<int> *facesToDelete)
793 {
794     MyArray<int> sortedFaces;
795     int facesToDeleteSize = (*facesToDelete).size();
796     for (int i = 0; i < facesToDeleteSize; i++) {
797         long k = 0;
798         while (k < sortedFaces.size()) {
799             if ((*facesToDelete)[i] > sortedFaces[k]) {
800                 sortedFaces.insert((*facesToDelete)[i], k);
801                 break;
802             }
803             k++;
804         }
805         if (k >= sortedFaces.size()) {
806             sortedFaces.append((*facesToDelete)[i]);
807         }
808     }
809 
810     for (long i = 0; i < sortedFaces.size(); i++) {
811         FaceData *face = getMesh()->getFace(sortedFaces[i]);
812         int offset = face->getOffset();
813         int numVertices = face->getNumVertices();
814         for (int j = offset; j < offset + numVertices; j++)
815             coordIndex->removeSFValue(offset);
816         coordIndex->removeSFValue(offset);
817     }
818 }
819 
820 bool
isSymetricFace(int iface)821 NodeIndexedFaceSet::isSymetricFace(int iface)
822 {
823     FaceData *face = getMesh()->getFace(iface);
824     int offset = face->getOffset();
825     int numVertices = face->getNumVertices();
826     bool sym = false;
827     float fepsilon = TheApp->GetHandleEpsilon();
828     NodeCoordinate *ncoord = (NodeCoordinate *)coord()->getValue();
829     if (ncoord == NULL)
830         return false;
831     for (int i = offset; i < offset + numVertices; i++) {
832         int ci = coordIndex()->getValue(i);
833         Vec3f vec = ncoord->point()->getValue(ci);
834         sym = false;
835         for (int j = offset; j < offset + numVertices; j++) {
836             if (i == j)
837                 continue;
838             int ci2 = coordIndex()->getValue(j);
839             Vec3f vec2 = ncoord->point()->getValue(ci2);
840             if (((vec2.x + vec.x) < fepsilon) &&
841                 ((vec2.y - vec.y) < fepsilon) &&
842                 ((vec2.z - vec.z) < fepsilon))
843                 sym = true;
844         }
845         if (!sym)
846             return false;
847     }
848     return sym;
849 }
850 
851 void
extrudeFaces(float dist)852 NodeIndexedFaceSet::extrudeFaces(float dist)
853 {
854     if (m_scene->getSelectionMode() != SELECTION_MODE_FACES)
855         return;
856     NodeCoordinate *ncoord = (NodeCoordinate *)coord()->getValue();
857     if (ncoord == NULL)
858         return;
859     MFVec3f *newVertices = new MFVec3f((MFVec3f *)ncoord->point()->copy());
860     MFInt32 *newCoordIndex = new MFInt32((MFInt32 *)coordIndex()->copy());
861     int numNewCoordIndex = newVertices->getSFSize();
862     int borderCount = 0;
863     MyArray<int> innerBorder;
864     MyArray<int> outerBorder;
865     MyArray<bool> symBorder;
866     MyArray<bool> validBorder;
867     int numFaces = 0;
868     MyArray<int> newFaces;
869     MyArray<int> symFaces;
870     MyArray<int> bothSidesSymFaces;
871     for (int i = 0; i < m_scene->getSelectedHandlesSize(); i++) {
872         int iface = m_scene->getSelectedHandle(i);
873         if (isSymetricFace(iface))
874             symFaces.append(iface);
875         int symFace = symetricFace(iface);
876         if (symFace > 0)
877             bothSidesSymFaces.append(symFace);
878     }
879     bool sym = m_scene->getXSymetricMode();
880     bool symFace = sym;
881     for (int i = 0; i < getMesh()->getNumFaces(); i++) {
882         FaceData *face = getMesh()->getFace(i);
883        int offset = face->getOffset();
884         int numVertices = face->getNumVertices();
885         if (m_scene->isInSelectedHandles(i))
886             if (sym)
887                 if (!symFaces.contains(i)) {
888                     symFace = false;
889                 }
890     }
891     for (int i = 0; i < getMesh()->getNumFaces(); i++) {
892         FaceData *face = getMesh()->getFace(i);
893         int offset = face->getOffset();
894         int numVertices = face->getNumVertices();
895         int ci2 = -1;
896         int oldBorderCount = borderCount;
897         for (int j = offset; j < offset + numVertices; j++) {
898             int ci = coordIndex()->getValue(j);
899             if (m_scene->isInSelectedHandles(i)) {
900                 Vec3f vec = ncoord->point()->getValue(ci);
901                 vec.x = vec.x;
902                 if (!symFace)
903                     vec.x += dist;
904                 vec.z = vec.z + dist;
905                 newVertices->appendSFValue(vec.x, vec.y, vec.z);
906                 if (j == offset)
907                     ci2 = numNewCoordIndex;
908                 innerBorder[borderCount] = numNewCoordIndex++;
909                 outerBorder[borderCount] = ci;
910                 symBorder[borderCount] = false;
911                 validBorder[borderCount] = true;
912                 borderCount++;
913             }
914         }
915         if (m_scene->isInSelectedHandles(i)) {
916             int ci3 = coordIndex()->getValue(offset + numVertices - 1);
917             int ci4 = coordIndex()->getValue(offset);
918             if ((ncoord->point()->getVec(ci3) -
919                  ncoord->point()->getVec(ci4)).length() != 0) {
920                 innerBorder[borderCount] = ci2;
921                 outerBorder[borderCount] = ci4;
922                 symBorder[borderCount] = false;
923                 validBorder[borderCount] = false;
924                 borderCount++;
925             }
926         }
927         if (borderCount > oldBorderCount) {
928             newFaces[numFaces] = getMesh()->getNumFaces() + numFaces;
929             numFaces++;
930             innerBorder[borderCount] = -1;
931             outerBorder[borderCount] = -1;
932             symBorder[borderCount] = false;
933             validBorder[borderCount] = true;
934             borderCount++;
935         }
936 
937         if (sym && (bothSidesSymFaces.contains(i))) {
938             oldBorderCount = borderCount;
939             for (int j = offset; j < offset + numVertices; j++) {
940                 int ci = coordIndex()->getValue(j);
941                 Vec3f vec = ncoord->point()->getValue(ci);
942                 if (!symFace)
943                     vec.x = vec.x - dist;
944                 vec.z = vec.z + dist;
945                 newVertices->appendSFValue(vec.x, vec.y, vec.z);
946                 if (j == offset)
947                     ci2 = numNewCoordIndex;
948                 innerBorder[borderCount] = numNewCoordIndex++;
949                 outerBorder[borderCount] = ci;
950                 symBorder[borderCount] = true;
951                 validBorder[borderCount] = true;
952                 borderCount++;
953             }
954             int ci5 = coordIndex()->getValue(offset + numVertices - 1);
955             int ci6 = coordIndex()->getValue(offset);
956             if ((ncoord->point()->getVec(ci5) -
957                  ncoord->point()->getVec(ci6)).length() != 0) {
958                 innerBorder[borderCount] = ci2;
959                 outerBorder[borderCount] = ci6;
960                 symBorder[borderCount] = true;
961                 validBorder[borderCount] = false;
962                 borderCount++;
963             }
964             if (borderCount > oldBorderCount) {
965                 innerBorder[borderCount] = -1;
966                 outerBorder[borderCount] = -1;
967                 symBorder[borderCount] = true;
968                 validBorder[borderCount] = true;
969                 borderCount++;
970             }
971         }
972     }
973 
974     for (int i = 0; i < borderCount; i++)
975         if (validBorder[i] && !symBorder[i])
976             newCoordIndex->appendSFValue(innerBorder[i]);
977     for (int i = 0; i < borderCount; i++)
978         if (validBorder[i] && symBorder[i])
979             newCoordIndex->appendSFValue(innerBorder[i]);
980 
981     if (newCoordIndex->getValue(newCoordIndex->getSFSize() - 1) > -1)
982         newCoordIndex->appendSFValue(-1);
983 
984     MyArray<int> facesToDelete;
985     for (int i = 0; i < getMesh()->getNumFaces(); i++)
986         if (m_scene->isInSelectedHandles(i)) {
987             int facesToDeleteSize = facesToDelete.size();
988             bool inserted = false;
989             for (int j = 0; j < facesToDeleteSize; j++)
990                 if (i > facesToDelete[j]) {
991                     facesToDelete.insert(i, j);
992                     inserted = true;
993                     break;
994                 }
995             if (!inserted)
996                 facesToDelete.append(i);
997         }
998 
999     for (long i = 0; i < symFaces.size(); i++) {
1000         int facesToDeleteSize = facesToDelete.size();
1001         bool inserted = false;
1002         for (int j = 0; j < facesToDeleteSize; j++)
1003             if (symFaces[i] > facesToDelete[j]) {
1004                 facesToDelete.insert(symFaces[i], j);
1005                 inserted = true;
1006                 break;
1007             }
1008         if (!inserted)
1009             facesToDelete.append(symFaces[i]);
1010     }
1011     int face1[4];
1012     int face1Count = 0;
1013     int face2[4];
1014     int face2Count = 0;
1015     for (int i = 0; i < borderCount - 1; i++) {
1016         int n = i + 1;
1017 
1018         if (!checkBorderFace(innerBorder, outerBorder, newCoordIndex, i, n,
1019                              symFaces, symBorder[i]))
1020             continue;
1021         if (symBorder[i]) {
1022             if ((innerBorder[i] < 0) || (!symBorder[n])) {
1023                 continue;
1024             } else {
1025                 face1[face1Count++] = innerBorder[i];
1026             }
1027             if (outerBorder[i] < 0) {
1028                 continue;
1029             } else {
1030                 face1[face1Count++] = outerBorder[i];
1031             }
1032 
1033             if (outerBorder[n] < 0) {
1034                 continue;
1035             } else {
1036                 face1[face1Count++] = outerBorder[n];
1037             }
1038             if (innerBorder[n] < 0) {
1039                 continue;
1040             } else {
1041                 face1[face1Count++] = innerBorder[n];
1042             }
1043         } else {
1044             if ((innerBorder[i] < 0) || (symBorder[n])) {
1045                 continue;
1046             } else {
1047                 face2[face2Count++] = innerBorder[i];
1048             }
1049             if (outerBorder[i] < 0) {
1050                 continue;
1051             } else {
1052                 face2[face2Count++] = outerBorder[i];
1053             }
1054 
1055             if (outerBorder[n] < 0) {
1056                 continue;
1057             } else {
1058                 face2[face2Count++] = outerBorder[n];
1059             }
1060             if (innerBorder[n] < 0) {
1061                 continue;
1062             } else {
1063                 face2[face2Count++] = innerBorder[n];
1064             }
1065         }
1066         if (face1Count >= 4) {
1067             for (int j = 0; j < 4; j++)
1068                 newCoordIndex->appendSFValue(face1[j]);
1069             newCoordIndex->appendSFValue(-1);
1070             face1Count = 0;
1071         }
1072         if (face2Count >= 4) {
1073             for (int j = 0; j < 4; j++)
1074                 newCoordIndex->appendSFValue(face2[j]);
1075             newCoordIndex->appendSFValue(-1);
1076             face2Count = 0;
1077         }
1078     }
1079     m_scene->backupFieldsStart();
1080     m_scene->backupFieldsAppend(ncoord, ncoord->point_Field());
1081     ncoord->point(new MFVec3f(newVertices));
1082     m_scene->backupFieldsAppend(this, coordIndex_Field());
1083     coordIndex(new MFInt32(newCoordIndex));
1084     m_scene->backupFieldsDone();
1085     m_scene->execute(new MoveCommand(normal()->getValue(), this, normal_Field(),
1086                                      NULL, -1));
1087     this->createMesh(false);
1088     ncoord->drawHandles();
1089     m_scene->setSelection(ncoord);
1090     m_scene->removeSelectedHandles();
1091     for (int i = 0; i < numFaces; i++)
1092         m_scene->addSelectedHandle(newFaces[i]);
1093     m_scene->UpdateViews(NULL, UPDATE_SELECTION);
1094 }
1095 
1096 bool
buildQuad(void)1097 NodeIndexedFaceSet::buildQuad(void)
1098 {
1099     NodeCoordinate *ncoord = (NodeCoordinate *)coord()->getValue();
1100     if (ncoord == NULL)
1101         return false;
1102     MFVec3f *point = ncoord->point();
1103     MFInt32 *ci = coordIndex();
1104     int iface1 = m_scene->getSelectedHandle(0);
1105     int iface2 = m_scene->getSelectedHandle(1);
1106     if (iface1 == iface2)
1107         return false;
1108     FaceData *face1 = getMesh()->getFace(iface1);
1109     int offset1 = face1->getOffset();
1110     int numVertices1 = face1->getNumVertices();
1111     FaceData *face2 = getMesh()->getFace(iface2);
1112     int offset2 = face2->getOffset();
1113     int numVertices2 = face2->getNumVertices();
1114     if ((numVertices1 != 3) || (numVertices2 != 3))
1115         return false;
1116     for (int i = offset1; i < offset1 + numVertices1; i++) {
1117         int first = i;
1118         Vec3f firstVertex = point->getVec(ci->getValue(first));
1119         int first2 = i + 1 < offset1 + numVertices1 ? i + 1 : offset1;
1120         Vec3f firstVertex2 = point->getVec(ci->getValue(first2));
1121         for (int j = offset2; j < offset2 + numVertices2; j++) {
1122              if (firstVertex == point->getVec(ci->getValue(j))) {
1123                  int second = -1;
1124                  bool validSecond = false;
1125                  second = j + 1 < offset2 + numVertices2 ? j + 1 : offset2;
1126                  Vec3f secondVertex = point->getVec(ci->getValue(second));
1127                  if (secondVertex == firstVertex2)
1128                      validSecond = true;
1129                  else {
1130                      second = j - 1 >= offset2 ? j - 1 :
1131                                                  offset2 + numVertices2 - 1;
1132                      Vec3f secondVertex = point->getVec(ci->getValue(second));
1133                      if (secondVertex == firstVertex2)
1134                          validSecond = true;
1135                  }
1136                  if (validSecond) {
1137                      for (int n = offset1; n < offset1 + numVertices1; n++)
1138                          if (((point->getVec(ci->getValue(first))) !=
1139                               (point->getVec(ci->getValue(n)))) &&
1140                              ((point->getVec(ci->getValue(second))) !=
1141                               (point->getVec(ci->getValue(n))))) {
1142                              ci->appendSFValue(ci->getValue(n));
1143                              break;
1144                          }
1145                      ci->appendSFValue(ci->getValue(first));
1146                      for (int n = offset2; n < offset2 + numVertices2; n++)
1147                          if (((point->getVec(ci->getValue(first))) !=
1148                               (point->getVec(ci->getValue(n)))) &&
1149                              ((point->getVec(ci->getValue(second))) !=
1150                               (point->getVec(ci->getValue(n))))) {
1151                              ci->appendSFValue(ci->getValue(n));
1152                              break;
1153                          }
1154                      ci->appendSFValue(ci->getValue(second));
1155                      ci->appendSFValue(-1);
1156                      MyArray<int> facesToDelete;
1157                      if (iface1 < iface2) {
1158                          facesToDelete.append(iface2);
1159                          facesToDelete.append(iface1);
1160                      } else {
1161                          facesToDelete.append(iface1);
1162                          facesToDelete.append(iface2);
1163                      }
1164                      deleteFaces(ci, &facesToDelete);
1165                      m_scene->removeSelectedHandles();
1166                      m_scene->setSelectedHandle(getMesh()->getNumFaces() - 2);
1167                      m_scene->backupFieldsStart();
1168                      m_scene->backupFieldsAppend(this, coordIndex_Field());
1169                      coordIndex(new MFInt32(ci));
1170                      m_scene->backupFieldsDone();
1171                      m_meshDirty = true;
1172                      return true;
1173                  }
1174              }
1175         }
1176     }
1177     return false;
1178 }
1179 
1180 void
snapTogether(void)1181 NodeIndexedFaceSet::snapTogether(void)
1182 {
1183     NodeCoordinate *ncoord = (NodeCoordinate *)coord()->getValue();
1184     if (ncoord == NULL)
1185         return;
1186     MFVec3f *point = ncoord->point();
1187     int numVertices = m_scene->getSelectedHandlesSize();
1188     Vec3f sum(0, 0, 0);
1189     for (int i = 0; i < numVertices; i++) {
1190         int vertex = m_scene->getSelectedHandle(i);
1191         sum = sum + point->getVec(vertex);
1192     }
1193     sum = sum / numVertices;
1194     for (int i = 0; i < numVertices; i++) {
1195         int vertex = m_scene->getSelectedHandle(i);
1196         point->setVec(vertex, sum);
1197     }
1198     m_scene->backupFieldsStart();
1199     m_scene->backupFieldsAppend(ncoord, ncoord->point_Field());
1200     ncoord->point(new MFVec3f(point));
1201     m_scene->backupFieldsDone();
1202     m_meshDirty = true;
1203 }
1204 
1205 bool
canSplitFace(int iface)1206 NodeIndexedFaceSet::canSplitFace(int iface)
1207 {
1208     NodeCoordinate *ncoord = (NodeCoordinate *)coord()->getValue();
1209     if (ncoord == NULL)
1210         return false;
1211     MFVec3f *point = ncoord->point();
1212     MFInt32 *ci = coordIndex();
1213     bool has4Edges = false;
1214     FaceData *face = getMesh()->getFace(iface);
1215     int offset = face->getOffset();
1216     if (face->getNumVertices() == 4)
1217         if (point->getValue(ci->getValue(offset)) !=
1218             point->getValue(ci->getValue(offset + face->getNumVertices() - 1)))
1219             has4Edges = true;
1220     if (face->getNumVertices() == 5)
1221         if (point->getValue(ci->getValue(offset)) ==
1222             point->getValue(ci->getValue(offset + face->getNumVertices() - 1)))
1223         has4Edges = true;
1224     return has4Edges;
1225 }
1226 
1227 class CoordIndexMapper {
1228 public:
1229     int count;
1230     int coordIndex;
1231     int edgeCoordIndex;
1232     int offset;
CoordIndexMapper()1233     CoordIndexMapper() {
1234         count = -1;
1235         coordIndex = -1;
1236         edgeCoordIndex = -1;
1237         offset = -1;
1238     }
CoordIndexMapper(int i,int c,int e,int o)1239     CoordIndexMapper(int i, int c, int e, int o) {
1240         count = i;
1241         coordIndex = c;
1242         edgeCoordIndex = e;
1243         offset = o;
1244     }
1245 };
1246 
1247 bool
checkMidpoint(Vec3f midPoint,int jLoop,int nLoop,int point1,int point2,int uPieces,int vPieces)1248 NodeIndexedFaceSet::checkMidpoint(Vec3f midPoint, int jLoop, int nLoop,
1249                                   int point1, int point2,
1250                                   int uPieces, int vPieces)
1251 {
1252     MFInt32 *ci = coordIndex();
1253     NodeCoordinate *ncoord = (NodeCoordinate *)coord()->getValue();
1254     if (ncoord == NULL)
1255         return false;
1256     MFVec3f *vertices = new MFVec3f(ncoord->point());
1257     Vec3f v1 = vertices->getValue(ci->getValue(point1));
1258     Vec3f v2 = vertices->getValue(ci->getValue(point2));
1259     float loop = -1;
1260     float maxLoop = -1;
1261     if ((jLoop == 0) || (jLoop == uPieces -1)) {
1262         loop = nLoop;
1263         if (uPieces == 1)
1264             maxLoop = vPieces;
1265         else
1266             maxLoop = uPieces;
1267     } else if ((nLoop == 0) || (nLoop == vPieces -1)) {
1268         loop = jLoop;
1269         if (vPieces == 1)
1270             maxLoop = uPieces;
1271         else
1272             maxLoop = vPieces;
1273     }
1274     if (loop == -1)
1275         return false;
1276     if (loop == 0)
1277         loop = 1;
1278     if (loop == maxLoop)
1279         loop = 1;
1280     Vec3f v = v1 + (v2 - v1) * loop / maxLoop;
1281     if ((fabs(v.x - midPoint.x) < floatEpsilon()) &&
1282         (fabs(v.y - midPoint.y) < floatEpsilon()) &&
1283         (fabs(v.z - midPoint.z) < floatEpsilon()))
1284         return true;
1285     return false;
1286 }
1287 
1288 bool
canSplitFaces(void)1289 NodeIndexedFaceSet::canSplitFaces(void)
1290 {
1291     for (int i = 0; i < m_scene->getSelectedHandlesSize(); i++) {
1292         int iface = m_scene->getSelectedHandle(i);
1293         if (canSplitFace(iface))
1294             return true;
1295     }
1296     return false;
1297 }
1298 
isInVertices(MFVec3f * newVertices,Vec3f v)1299 static int isInVertices(MFVec3f *newVertices, Vec3f v)
1300 {
1301     MFVec3f *vertices = newVertices;
1302     for (int i = 0; i < vertices->getSFSize(); i++)
1303         if (v == vertices->getValue(i))
1304             return i;
1305     return -1;
1306 }
1307 
1308 int
getEgdeCoordIndex(int iface,Vec3f midPoint,int uLoop,int vLoop,int uPieces,int vPieces)1309 NodeIndexedFaceSet::getEgdeCoordIndex(int iface, Vec3f midPoint,
1310                                       int uLoop, int vLoop,
1311                                       int uPieces, int vPieces)
1312 {
1313     for (int i = 0; i < getMesh()->getNumFaces(); i++) {
1314         if (iface == i)
1315             continue;
1316         FaceData *face = getMesh()->getFace(i);
1317         int offset = face->getOffset();
1318         int numVertices = face->getNumVertices();
1319         for (int j = offset + 1; j < offset + numVertices; j++) {
1320             if (checkMidpoint(midPoint, uLoop, vLoop, j - 1, j,
1321                               uPieces, vPieces))
1322                 return j;
1323         }
1324         if (checkMidpoint(midPoint, uLoop, vLoop,
1325                           offset, offset + numVertices -1, uPieces, vPieces))
1326             return offset;
1327     }
1328     return -1;
1329 }
1330 
1331 void
splitIntoPieces(int u,int v)1332 NodeIndexedFaceSet::splitIntoPieces(int u, int v)
1333 {
1334     if (!canSplitFaces())
1335         return;
1336     NodeCoordinate *ncoord = (NodeCoordinate *)coord()->getValue();
1337     if (ncoord == NULL)
1338         return;
1339     MFVec3f *newVertices = new MFVec3f((MFVec3f *)ncoord->point()->copy());
1340     MFInt32 *newCoordIndex = new MFInt32((MFInt32 *)coordIndex()->copy());
1341     MyArray<int> symFaces;
1342     if (m_scene->getXSymetricMode())
1343         for (int i = 0; i < m_scene->getSelectedHandlesSize(); i++) {
1344             int iface = symetricFace(m_scene->getSelectedHandle(i));
1345             if (iface > -1)
1346                 if (!m_scene->isInSelectedHandles(iface))
1347                     symFaces.append(iface);
1348     }
1349     MyArray<CoordIndexMapper> coordIndexToAdded;
1350     int numAddedVertices = 0;
1351     for (int i = 0; i < getMesh()->getNumFaces(); i++) {
1352         FaceData *face = getMesh()->getFace(i);
1353         if ((!m_scene->isInSelectedHandles(i)) && (!symFaces.contains(i)))
1354             continue;
1355         int offset = face->getOffset();
1356         if (canSplitFace(i)) {
1357             int piecesU = u;
1358             int piecesV = v;
1359             int off = newCoordIndex->getValue(offset);
1360             Vec3f vec = newVertices->getValue(off);
1361             int off1 = newCoordIndex->getValue(offset + 1);
1362             Vec3f s = newVertices->getValue(off1);
1363             int off2 = newCoordIndex->getValue(offset + 2);
1364             Vec3f t = newVertices->getValue(off2);
1365             int off3 = newCoordIndex->getValue(offset + 3);
1366             Vec3f r = newVertices->getValue(off3);
1367             for (int j = 0; j < piecesU; j++) {
1368                 for (int n = 0; n < piecesV; n++) {
1369                     if ((n > 0) && (n == piecesV - 1))
1370                         continue;
1371 
1372                     Vec3f p1 = vec + (r - vec) * j / piecesU;
1373                     Vec3f p2 = s + (t - s) * j / piecesU;
1374                     Vec3f q1 = vec + (r - vec) * (j + 1) / piecesU;
1375                     Vec3f q2 = s + (t - s) * (j + 1) / piecesU;
1376 
1377                     Vec3f v1 = p1 + (p2 - p1) * n / piecesV;
1378                     int n1 = isInVertices(newVertices, v1);
1379                     if (n1 < 0) {
1380                         CoordIndexMapper coordIndexMap(numAddedVertices++,
1381                             newVertices->getSFSize(),
1382                             getEgdeCoordIndex(i, v1, j, n, piecesU, piecesV),
1383                             off);
1384                         newVertices->appendSFValue(v1.x, v1.y, v1.z);
1385                         coordIndexToAdded.append(coordIndexMap);
1386                     }
1387                     Vec3f v2 = p1 + (p2 - p1) * (n + 1) / piecesV;
1388                     int n2 = isInVertices(newVertices, v2);
1389                     if (n2 < 0) {
1390                         CoordIndexMapper coordIndexMap(numAddedVertices++,
1391                             newVertices->getSFSize(),
1392                             getEgdeCoordIndex(i, v2, j, n + 1,
1393                                               piecesU, piecesV),
1394                             off1);
1395                         newVertices->appendSFValue(v2.x, v2.y, v2.z);
1396                         coordIndexToAdded.append(coordIndexMap);
1397                     }
1398                     Vec3f v3 = q1 + (q2 - q1) * (n + 1) / piecesV;
1399                     int n3 = isInVertices(newVertices, v3);
1400                     if (n3 < 0) {
1401                         CoordIndexMapper coordIndexMap(numAddedVertices++,
1402                             newVertices->getSFSize(),
1403                             getEgdeCoordIndex(i, v3, j + 1, n + 1,
1404                                               piecesU, piecesV),
1405                             off2);
1406                         newVertices->appendSFValue(v3.x, v3.y, v3.z);
1407                         coordIndexToAdded.append(coordIndexMap);
1408                     }
1409                     Vec3f v4 = q1 + (q2 - q1) * n / piecesV;
1410                     int n4 = isInVertices(newVertices, v4);
1411                     if (n4 < 0) {
1412                         CoordIndexMapper coordIndexMap(numAddedVertices++,
1413                             newVertices->getSFSize(),
1414                             getEgdeCoordIndex(i, v4, j + 1, n,
1415                                               piecesU, piecesV),
1416                             off3);
1417                         newVertices->appendSFValue(v4.x, v4.y, v4.z);
1418                         coordIndexToAdded.append(coordIndexMap);
1419                     }
1420                }
1421             }
1422             for (int j = 0; j < piecesU; j++) {
1423                 Vec3f p1 = vec + (r - vec) * j / piecesU;
1424                 Vec3f p2 = s + (t - s) * j / piecesU;
1425                 Vec3f q1 = vec + (r - vec) * (j + 1) / piecesU;
1426                 Vec3f q2 = s + (t - s) * (j + 1) / piecesU;
1427                 for (int n = 0; n < piecesV; n++) {
1428                     Vec3f v1 = p1 + (p2 - p1) * n / piecesV;
1429                     int n1 = isInVertices(newVertices, v1);
1430                     if (n1 < 0) {
1431                         n1 = newVertices->getSFSize();
1432                         newVertices->appendSFValue(v1.x, v1.y, v1.z);
1433                     }
1434                     Vec3f v2 = p1 + (p2 - p1) * (n + 1) / piecesV;
1435                     int n2 = isInVertices(newVertices, v2);
1436                     if (n2 < 0) {
1437                         n2 = newVertices->getSFSize();
1438                         newVertices->appendSFValue(v2.x, v2.y, v2.z);
1439                     }
1440                     Vec3f v3 = q1 + (q2 - q1) * (n + 1) / piecesV;
1441                     int n3 = isInVertices(newVertices, v3);
1442                     if (n3 < 0) {
1443                         n3 = newVertices->getSFSize();
1444                         newVertices->appendSFValue(v3.x, v3.y, v3.z);
1445                     }
1446                     Vec3f v4 = q1 + (q2 - q1) * n / piecesV;
1447                     int n4 = isInVertices(newVertices, v4);
1448                     if (n4 < 0) {
1449                         n4 = newVertices->getSFSize();
1450                         newVertices->appendSFValue(v4.x, v4.y, v4.z);
1451                     }
1452                     newCoordIndex->appendSFValue(n1);
1453                     newCoordIndex->appendSFValue(n2);
1454                     newCoordIndex->appendSFValue(n3);
1455                     newCoordIndex->appendSFValue(n4);
1456                     newCoordIndex->appendSFValue(-1);
1457                 }
1458             }
1459         }
1460     }
1461     MyArray<int> sortedM;
1462     MyArray<int> sortedL;
1463     MyArray<int> sortedO;
1464     for (long n = 0; n < coordIndexToAdded.size(); n++) {
1465         int m = coordIndexToAdded[n].edgeCoordIndex;
1466         int l = coordIndexToAdded[n].coordIndex;
1467         int o = coordIndexToAdded[n].offset;
1468         long k = 0;
1469         while (k < sortedM.size()) {
1470             if ((m > sortedM[k]) && (m > -1)) {
1471                 sortedM.insert(m, k);
1472                 sortedL.insert(l, k);
1473                 sortedO.insert(o, k);
1474                 break;
1475             }
1476             k++;
1477         }
1478         if ((k >= sortedM.size()) && (m > -1)) {
1479             sortedM.append(m);
1480             sortedL.append(l);
1481             sortedO.append(o);
1482         }
1483     }
1484     MyArray<int> sortedFaces;
1485     for (int i = 0; i < getMesh()->getNumFaces(); i++) {
1486         if (m_scene->isInSelectedHandles(i) || symFaces.contains(i)) {
1487             long k = 0;
1488             while (k < sortedFaces.size()) {
1489                 if ((i > sortedFaces[k])) {
1490                     sortedFaces.insert(i, k);
1491                     break;
1492                 }
1493                 k++;
1494             }
1495             if (k >= sortedFaces.size()) {
1496                 sortedFaces.append(i);
1497             }
1498         }
1499     }
1500     for (long i = 0; i < sortedFaces.size(); i++) {
1501         FaceData *face = getMesh()->getFace(sortedFaces[i]);
1502         int offset = face->getOffset();
1503         int numVertices = face->getNumVertices();
1504         for (int j = offset; j < offset + numVertices; j++)
1505             newCoordIndex->removeSFValue(offset);
1506         newCoordIndex->removeSFValue(offset);
1507         for (long j = 0; j < sortedM.size(); j++)
1508             if (sortedM[j] >= offset)
1509                 sortedM[j] -= (numVertices + 1);
1510     }
1511     for (long j = 0; j < sortedM.size(); j++) {
1512         newCoordIndex->insertSFValue(sortedM[j], sortedL[j]);
1513     }
1514     m_scene->backupFieldsStart();
1515     m_scene->setField(this, normal_Field(), new SFNode(NULL));
1516     m_scene->backupFieldsAppend(ncoord, ncoord->point_Field());
1517     ncoord->point(new MFVec3f(newVertices));
1518     m_scene->backupFieldsAppend(this, coordIndex_Field());
1519     coordIndex(new MFInt32(newCoordIndex));
1520     m_scene->backupFieldsDone();
1521     m_meshDirty = true;
1522 }
1523 
1524 float*
intersectVector0Plane(Vec3f endPoint,Vec3f startPoint,int direction)1525 NodeIndexedFaceSet::intersectVector0Plane(Vec3f endPoint, Vec3f startPoint,
1526                                           int direction)
1527 {
1528     static float ret[3];
1529     Vec3f normal;
1530     switch (direction) {
1531       case 0:
1532         normal.x = 1;
1533         normal.y = 0;
1534         normal.z = 0;
1535         break;
1536       case 1:
1537         normal.x = 0;
1538         normal.y = 1;
1539         normal.z = 0;
1540         break;
1541       case 2:
1542         normal.x = 0;
1543         normal.y = 0;
1544         normal.z = 1;
1545         break;
1546     }
1547     Vec3f pointOfPlane(0.0f, 0.0f, 0.0f);
1548     Vec3f direct = (endPoint - startPoint);
1549     Vec3f diff = (endPoint - pointOfPlane);
1550     float len = diff.dot(normal);
1551     float a = direct.dot(normal);
1552     if (a == 0)
1553         return NULL;
1554     Vec3f result = endPoint - direct * len / a;
1555     if ((result.x == 0) && (result.y == 0) && (result.z == 0))
1556         if ((endPoint.x != 0) || (endPoint.y != 0) || (endPoint.z != 0))
1557             return NULL;
1558     ret[0] = result.x;
1559     ret[1] = result.y;
1560     ret[2] = result.z;
1561     return ret;
1562 }
1563 
1564 void
makeSymetric(int direction,bool plus)1565 NodeIndexedFaceSet::makeSymetric(int direction, bool plus)
1566 {
1567     NodeCoordinate *ncoord = (NodeCoordinate *)coord()->getValue();
1568     if (ncoord == NULL)
1569         return;
1570     MFVec3f *vertices = new MFVec3f((MFVec3f *)ncoord->point());
1571     MyArray<float> halfVertices;
1572     MyArray<float> startVertices;
1573     MyArray<int> halfCoordIndex;
1574     int newCi = 0;
1575     for (int i = 0; i < getMesh()->getNumFaces(); i++) {
1576         FaceData *face = getMesh()->getFace(i);
1577         int offset = face->getOffset();
1578         int numVertices = face->getNumVertices();
1579         int wrongVertices = 0;
1580         for (int j = offset; j < offset + numVertices; j++) {
1581             const float *vert = vertices->getValue(coordIndex()->getValue(j));
1582             if (plus) {
1583                 if (vert[direction] < 0)
1584                     wrongVertices++;
1585             } else {
1586                 if (vert[direction] > 0)
1587                     wrongVertices++;
1588             }
1589         }
1590         if ((wrongVertices >= 0) && (wrongVertices < numVertices)) {
1591             for (int j = offset; j < offset + numVertices; j++) {
1592                 int ci = coordIndex()->getValue(j);
1593                 const float *vert = vertices->getValue(ci);
1594                 halfVertices.append(vert[0]);
1595                 halfVertices.append(vert[1]);
1596                 halfVertices.append(vert[2]);
1597                 halfCoordIndex.append(newCi++);
1598                 int j2 = j;
1599                 if (j == offset) {
1600                     j2 = offset + numVertices - 1;
1601                     int ci2 = coordIndex()->getValue(j2);
1602                     if (vertices->getValue(ci2) ==
1603                         vertices->getValue(coordIndex()->getValue(offset)))
1604                         j2--;
1605                 } else
1606                     j2--;
1607                 int ci2 = coordIndex()->getValue(j);
1608                 const float *startVert = vertices->getValue(ci2);
1609                 startVertices.append(startVert[0]);
1610                 startVertices.append(startVert[1]);
1611                 startVertices.append(startVert[2]);
1612             }
1613             halfCoordIndex.append(-1);
1614         }
1615     }
1616     int halfVerticesSize = halfVertices.size() / 3;
1617     int halfCoordIndexSize = halfCoordIndex.size();
1618     for (int i = 0; i < halfVerticesSize; i++)
1619         if (plus) {
1620             if (halfVertices[3 * i + direction] < 0) {
1621                 Vec3f endPoint(halfVertices[3 * i],
1622                                halfVertices[3 * i + 1],
1623                                halfVertices[3 * i + 2]);
1624                 Vec3f startPoint(startVertices[3 * i],
1625                                  startVertices[3 * i + 1],
1626                                  startVertices[3 * i + 2]);
1627                 float *result = intersectVector0Plane(endPoint, startPoint,
1628                                                       direction);
1629                 if (result != NULL) {
1630                     for (int j = 0; j < 3; j++)
1631                          halfVertices[3 * i + j] = result[j];
1632                 }
1633             }
1634         } else {
1635             if (halfVertices[3 * i + direction] > 0) {
1636                 Vec3f startPoint(startVertices[3 * i],
1637                                  startVertices[3 * i + 1],
1638                                  startVertices[3 * i + 2]);
1639                 Vec3f endPoint(halfVertices[3 * i],
1640                                halfVertices[3 * i + 1],
1641                                halfVertices[3 * i + 2]);
1642                 float *result = intersectVector0Plane(endPoint, startPoint,
1643                                                       direction);
1644                 if (result != NULL) {
1645                     for (int j = 0; j < 3; j++)
1646                          halfVertices[3 * i + j] = result[j];
1647                 }
1648             }
1649         }
1650     MFVec3f *newVertices = new MFVec3f();
1651     MFInt32 *newCoordIndex = new MFInt32();
1652     for (int i = 0; i < halfVerticesSize; i++) {
1653         newVertices->appendSFValue(halfVertices[3 * i + 0],
1654                                    halfVertices[3 * i + 1],
1655                                    halfVertices[3 * i + 2]);
1656     }
1657     for (int i = 0; i < halfVerticesSize; i++) {
1658         halfVertices[3 * i + direction] *= -1;
1659         newVertices->appendSFValue(halfVertices[3 * i + 0],
1660                                    halfVertices[3 * i + 1],
1661                                    halfVertices[3 * i + 2]);
1662     }
1663     for (int i = 0; i < halfCoordIndexSize; i++)
1664         newCoordIndex->appendSFValue(halfCoordIndex[i]);
1665     for (int i = halfCoordIndexSize -1; i > -1; i--) {
1666         if (halfCoordIndex[i] > -1)
1667             halfCoordIndex[i] += newCi;
1668         if ((i != 0) || (halfCoordIndex[i] > -1))
1669             newCoordIndex->appendSFValue(halfCoordIndex[i]);
1670     }
1671     newCoordIndex->appendSFValue(-1);
1672     m_scene->backupFieldsStart();
1673     m_scene->backupFieldsAppend(ncoord, ncoord->point_Field());
1674     ncoord->point(new MFVec3f(newVertices));
1675     m_scene->backupFieldsAppend(this, coordIndex_Field());
1676     coordIndex(new MFInt32(newCoordIndex));
1677     m_scene->backupFieldsAppend(this, color_Field());
1678     color(new SFNode());
1679     m_scene->backupFieldsAppend(this, normal_Field());
1680     normal(new SFNode());
1681     m_scene->backupFieldsAppend(this, texCoord_Field());
1682     texCoord(new SFNode());
1683     m_scene->backupFieldsAppend(this, colorIndex_Field());
1684     colorIndex(new MFInt32);
1685     m_scene->backupFieldsAppend(this, colorIndex_Field());
1686     normalIndex(new MFInt32);
1687     m_scene->backupFieldsAppend(this, texCoordIndex_Field());
1688     texCoordIndex(new MFInt32);
1689     m_scene->backupFieldsDone();
1690     m_meshDirty = true;
1691 }
1692 
midOffset(int count,int numCount)1693 static float midOffset(int count, int numCount)
1694 {
1695     if (count == 0)
1696         return 0;
1697     return count - 1;
1698 }
1699 
border1(int count,int numCount)1700 static float border1(int count, int numCount)
1701 {
1702     if (count == 0)
1703         return -1.0f;
1704     return (float)count - 1.0f;
1705 }
1706 
border2(int count,int numCount)1707 static float border2(int count, int numCount)
1708 {
1709     return border1(count,  numCount) + 0.25f;
1710 }
1711 
border3(int count,int numCount)1712 static float border3(int count, int numCount)
1713 {
1714     return border1(count,  numCount) + 0.75f;
1715 }
1716 
border4(int count,int numCount)1717 static float border4(int count, int numCount)
1718 {
1719     return border1(count,  numCount) + 1.0f;
1720 }
1721 
storeVertexN(MFVec3f * vertices,MFInt32 * ci,Vec3f vertex,int face,int countX,int numX,int numY)1722 static void storeVertexN(MFVec3f *vertices, MFInt32 *ci, Vec3f vertex,
1723                          int face, int countX, int numX, int numY)
1724 {
1725     Vec3f vec(vertex.x, vertex.y, vertex.z);
1726 
1727     if (numY == 2 && numX == 3) {
1728         if (face == FACE_FRONT || face == FACE_BACK) {
1729             vec.x *= 1.0f / (float)numX;
1730             vec.x += 1.0f;
1731             vec.x -= 1.0f / (float)numX;
1732         }
1733         if (face == FACE_TOP || face == FACE_BOTTOM) {
1734             vec.z /= (float)numX;
1735         }
1736     }
1737     if (numY == 3 && numX == 2) {
1738         if (face == FACE_BACK) {
1739             vec.x *= -1.0f;
1740 
1741             vec.x += 1.0f;
1742             vec.y += 1.0f;
1743         }
1744         if (face == FACE_FRONT) {
1745             vec.x += 1.0f;
1746             vec.y += 1.0f;
1747         }
1748         if (face == FACE_TOP || face == FACE_BOTTOM) {
1749             vec.z /= (float)numX;
1750         }
1751     }
1752     if (numX == 3 && numY == 3) {
1753         if (face == FACE_TOP || face == FACE_BOTTOM) {
1754            vec.z /= (float)numX;
1755         }
1756         if (face == FACE_FRONT || face == FACE_BACK) {
1757             vec.x /= (float)numX;
1758             vec.x += 1.0f - 1.0f / (float)numX;
1759         }
1760         if (face == FACE_RIGHT || face == FACE_LEFT) {
1761             vec.y /= (float)numX;
1762         }
1763     }
1764     ci->appendSFValue(vertices->getSFSize());
1765     vertices->setVec(vertices->getSFSize(), vec);
1766 }
1767 
storeVertex(MFVec3f * vertices,MFInt32 * ci,Vec3f newVertex,int face,int countX,int countY,int numX,int numY)1768 static void storeVertex(MFVec3f *vertices, MFInt32 *ci, Vec3f newVertex,
1769                         int face, int countX, int countY, int numX, int numY)
1770 {
1771     Vec3f vec(newVertex.x, newVertex.y, newVertex.z);
1772     if (numY == 1 && numX == 2) {
1773         if (face == FACE_FRONT || face == FACE_BACK) {
1774             vec.y *= 2.0;
1775             vec.x += 1.0f;
1776             vec.y -= 1.0f;
1777             if (face == FACE_BACK) {
1778                 vec.x *= -1.0f;
1779                 vec.x += 2.0f;
1780             }
1781         }
1782         if (face == FACE_TOP || face == FACE_BOTTOM) {
1783             float temp = vec.y;
1784             vec.y = vec.z;
1785             vec.z = temp;
1786 
1787             if (face == FACE_TOP) {
1788                 vec.y = 1.0f;
1789                 vec.x *= -1.0f;
1790                 vec.x -= 1.0f;
1791                 vec.z -= 1.0f;
1792             } else {
1793                 vec.y = -1.0f;
1794                 vec.x += 1.0f;
1795                 vec.z += 1.0f;
1796             }
1797             vec.z *= 2.0f;
1798             vec.z += 1.0f;
1799         }
1800         if (face == FACE_RIGHT || face == FACE_LEFT) {
1801             float temp = vec.x;
1802             vec.x = vec.z;
1803             vec.z = temp;
1804 
1805             if (face == FACE_RIGHT) {
1806                 vec.x = 1.0f;
1807                 vec.y *= -1.0f;
1808                 vec.z -= 1.0f;
1809             } else {
1810                 vec.x = -1.0f;
1811                 vec.y -= 1.0f;
1812                 vec.z += 1.0f;
1813             }
1814             vec.y *= 2.0f;
1815             vec.y += 1.0f;
1816         }
1817     }
1818     if (numY == 1 && numX == 3) {
1819         if (face == FACE_FRONT || face == FACE_BACK) {
1820             vec.y *= 2.0f;
1821             vec.y += 1.0f;
1822             vec.x *= 2.0f / (float)numX;
1823             vec.x += 1.0f / (float)numX;
1824             if (face == FACE_BACK) {
1825                 vec.x *= -1.0f;
1826                 vec.x -= -4.0f / (float)numX;
1827             }
1828         }
1829         if (face == FACE_TOP || face == FACE_BOTTOM) {
1830             float temp = vec.y;
1831             vec.y = vec.z;
1832             vec.z = temp;
1833 
1834             vec.x *= 2.0f / (float)numX;
1835             vec.z *= 2.0f;
1836             if (face == FACE_TOP)
1837                 vec.z *= -1.0f;
1838             vec.x += 1.0f;
1839             if (face == FACE_TOP)
1840                 vec.y += 2.0f;
1841             else
1842                 vec.y -= 2.0f;
1843             vec.z += 1.0f;
1844             if (face == FACE_BOTTOM)
1845                 vec.z += 2.0f;
1846 
1847         }
1848         if (face == FACE_LEFT || face == FACE_RIGHT) {
1849             float temp = vec.x;
1850             vec.x = vec.z;
1851             vec.z = temp;
1852 
1853             vec.z *= 2.0f * (float)numY / (float)numX;
1854 
1855             if (face == FACE_RIGHT) {
1856                 vec.x = 1.0f;
1857                 vec.z *= -1.0f;
1858                 vec.z += 1.0f / (float)numX;
1859             } else {
1860                 vec.x = -1.0f;
1861                 vec.z += 1.0f;
1862             }
1863             vec.y *= 2.0f;
1864             vec.y -= 1.0f;
1865         }
1866     }
1867     if (numY == 2 && numX == 1) {
1868         if (face == FACE_FRONT || face == FACE_BACK) {
1869             vec.x *= 2.0f;
1870             if (face == FACE_FRONT)
1871                 vec.x += 1.0f;
1872             else {
1873                 vec.x *= -1.0f;
1874                 vec.x += 3.0f;
1875             }
1876             vec.y -= 1.0f;
1877         }
1878         if (face == FACE_RIGHT || face == FACE_LEFT) {
1879             float temp = vec.x;
1880             vec.x = vec.z;
1881             vec.z = temp;
1882 
1883             if (face == FACE_RIGHT) {
1884                 vec.z *= -2.0f;
1885                 vec.x = 1;
1886                 vec.y -= 1.0f;
1887                 vec.z += 3.0f;
1888             } else {
1889                 vec.x = -1;
1890                 vec.z *= 2.0f;
1891                 vec.y -= 1.0f;
1892                 vec.z += 1.0f;
1893             }
1894         }
1895     }
1896     if (numY == 2 && numX == 2) {
1897         if (face == FACE_FRONT || face == FACE_BACK) {
1898             vec.x += 1.0f;
1899             vec.y -= 1.0f;
1900         }
1901         if (face == FACE_TOP || face == FACE_BOTTOM) {
1902             float temp = vec.y;
1903             vec.y = vec.z;
1904             vec.z = temp;
1905 
1906             if (face == FACE_TOP)
1907                 vec.z *= -1.0f;
1908             else
1909                 vec.z *= +1.0f;
1910             if (face == FACE_TOP)
1911                 vec.y = 1.0f;
1912             else
1913                 vec.y = -1.0f;
1914             vec.x += 1.0;
1915             vec.z += 1.0;
1916         }
1917         if (face == FACE_LEFT || face == FACE_RIGHT) {
1918             float temp = vec.x;
1919             vec.x = vec.z;
1920             vec.z = temp;
1921             if (face == FACE_LEFT) {
1922                 vec.x = -1.0f;
1923                 vec.y -= 1.0f;
1924                 vec.z += 1.0f;
1925             } else {
1926                 vec.x = 1.0f;
1927                 vec.y *= -1.0f;
1928                 vec.y += 1.0f;
1929                 vec.z -= 1.0f;
1930             }
1931         }
1932     }
1933     if (numY == 2 && numX == 3) {
1934         if (face == FACE_FRONT) {
1935             vec.x *= 2.0f;
1936             vec.x -= 1.0f - 0.025;
1937             vec.y -= 1.0f;
1938         }
1939         if (face == FACE_BACK) {
1940             vec.x *= 2.05f;
1941             vec.x -= 1.0f - 0.025;
1942             vec.x *= -1.0f;
1943             vec.y -= 1.0f;
1944         }
1945         if (face == FACE_TOP || face == FACE_BOTTOM) {
1946             float temp = vec.y;
1947             vec.y = vec.x;
1948             vec.x = temp;
1949 
1950             temp = vec.y;
1951             vec.y = vec.z;
1952             vec.z = temp;
1953 
1954             if (face == FACE_BOTTOM) {
1955                 vec.y = -1.0f;
1956                 vec.z *= -2.0f;
1957             } else
1958                 vec.y = 1.0f;
1959 
1960             vec.x += 1.0f / (float)numY;
1961             vec.z -= 1.0f / (float)numY;
1962 
1963             vec.x *= 2.0f - 2.0f / (float)numY;
1964 
1965             vec.x -= 1.5;
1966 
1967             if (face == FACE_TOP) {
1968                 vec.z *= 2.0f;
1969                 vec.z += 2.0f;
1970             } else {
1971                 vec.x += 2.0f;
1972                 vec.z -= 0.333;
1973             }
1974         }
1975         if (face == FACE_RIGHT || face == FACE_LEFT) {
1976             float temp = vec.x;
1977             vec.x = vec.z;
1978             vec.z = temp;
1979 
1980             vec.z *= -(float)numY / (float)numX;
1981             if (face == FACE_RIGHT) {
1982                 vec.x = 1.0f;
1983             } else {
1984                 vec.x = -1.0f;
1985                 vec.z *= -1.0f;
1986                 vec.z += 0.05f - 2 / (float)numX;
1987             }
1988             vec.y += - 1.27;
1989             vec.y += 0.75f / (float)numX;
1990             vec.z += 1.0f;
1991         }
1992     }
1993     if (numY == 3 && numX == 1) {
1994         if (face == FACE_FRONT || face == FACE_BACK) {
1995             vec.x *= 2.0f;
1996             vec.x += 1.0f;
1997             vec.y *= 0.6666f;
1998             vec.y -= 1.0f;
1999         }
2000         if (face == FACE_TOP) {
2001             float temp = vec.y;
2002             vec.y = vec.x;
2003             vec.x = temp;
2004 
2005             temp = vec.y;
2006             vec.y = vec.z;
2007             vec.z = temp;
2008 
2009             vec.y += 2.0f;
2010             vec.x += 1.0f / (float)numY;
2011             vec.z -= 1.0f / (float)numY;
2012 
2013             vec.x *= 2.0f; // - 2.0f / (float)numY;
2014 
2015             vec.x += -2.0f + 0.45;
2016 
2017             vec.z *= 2.0f;
2018             vec.z += 2.0f;
2019         }
2020         if (face == FACE_BOTTOM) {
2021             float temp = vec.y;
2022             vec.y = vec.x;
2023             vec.x = temp;
2024 
2025             temp = vec.y;
2026             vec.y = vec.z;
2027             vec.z = temp;
2028 
2029             vec.y -= 2.0f;
2030             vec.x += 1.0f / (float)numY;
2031             vec.z -= 1.0f / (float)numY;
2032 
2033             vec.x *= 2.0f - 2.0f / (float)numY;
2034 
2035             vec.x += 0.5;
2036 
2037             vec.z *= -2.0f;
2038             vec.z -= 2.0f;
2039         }
2040     }
2041     if (numY == 3 && numX == 2) {
2042         if (face == FACE_FRONT || face == FACE_BACK) {
2043             vec.x *= 2.0f;
2044             if (face == FACE_FRONT) {
2045                 vec.y -= 1.0f;
2046             } else {
2047                 vec.y -= 1.0f;
2048             }
2049             vec.x -= 1.0f;
2050             vec.x *= 0.5f;
2051             vec.x += 1.5f / (float)numY;
2052             vec.y *= (float)numX / (float)numY;
2053             vec.y += 0.5f / (float)numY;
2054             vec.y -= 1.5f;
2055         }
2056         if (face == FACE_TOP) {
2057             float temp = vec.y;
2058             vec.y = vec.z;
2059             vec.z = temp;
2060 
2061             vec.y = 1.0f;
2062             vec.z *= (float)numX / (float)numY;
2063 
2064             vec.x += 3.0f / (float)numY;
2065 
2066             vec.x *= -1.0f;
2067 
2068             vec.z *= 2.0f;
2069             vec.z += 2.0f - 4.0f;
2070         }
2071         if (face == FACE_BOTTOM) {
2072             float temp = vec.y;
2073             vec.y = vec.z;
2074             vec.z = temp;
2075 
2076             vec.y = -1.0f;
2077             vec.z *= (float)numX / (float)numY;
2078 
2079             vec.x += 3.0f / (float)numY;
2080             vec.z += 2.0f / (float)numY;
2081 
2082             vec.x *= -1.0f;
2083 
2084             vec.z *= 2.0f;
2085             vec.z += 2.0f - 4.0f;
2086         }
2087         if (face == FACE_RIGHT) {
2088             float temp = vec.y;
2089             vec.y = vec.z;
2090             vec.z = temp;
2091 
2092             temp = vec.y;
2093             vec.y = vec.x;
2094             vec.x = temp;
2095 
2096             vec.z *= -((float)numY - 1) / (float)numY;
2097 
2098             vec.x += 2.0f;
2099             vec.y -= 1.0f;
2100             vec.y *= 2.0f;
2101             vec.z -= 1.0f;
2102             vec.y += 1.0f;
2103         }
2104         if (face == FACE_LEFT) {
2105             float temp = vec.y;
2106             vec.y = vec.z;
2107             vec.z = temp;
2108 
2109             temp = vec.y;
2110             vec.y = vec.x;
2111             vec.x = temp;
2112 
2113             vec.x *= -1.0f;
2114             vec.z *= ((float)numY - 1) / (float)numY;
2115 
2116             vec.x += 2.0f;
2117             vec.y += 1.0f;
2118             vec.y *= 2.0f;
2119             vec.y += 1.0f;
2120             vec.z *= -1.0f;
2121         }
2122     }
2123     if (numX == numY && numX == 3) {
2124         if (face == FACE_TOP) {
2125             float temp = vec.y;
2126             vec.y = vec.x;
2127             vec.x = temp;
2128 
2129             temp = vec.y;
2130             vec.y = vec.z;
2131             vec.z = temp;
2132 
2133             vec.y += 2.0f;
2134             vec.x += 1.0f / (float)numY;
2135             vec.z -= 1.0f / (float)numY / 4.0f;
2136 
2137             vec.x *= 1.0f - 1.0f / (float)numY;
2138             vec.x -= 1.5 + 1.0f / 24.0f - 0.035f;
2139 
2140             vec.z *= 2.0f;
2141             vec.z += 3.25f - 1.0f / 24.0f - 1.0f / 48.0f;
2142         }
2143         if (face == FACE_BOTTOM) {
2144             float temp = vec.y;
2145             vec.y = vec.x;
2146             vec.x = temp;
2147 
2148             temp = vec.y;
2149             vec.y = vec.z;
2150             vec.z = temp;
2151 
2152             vec.y -= 2.0f;
2153             vec.x += 1.0f / (float)numY;
2154             vec.z -= 1.0f / (float)numY / 4.0f;
2155 
2156             vec.x *= 1.0f - 1.0f / (float)numY;
2157             vec.x -= 1.5f + 1.0f / 24.0f;
2158             vec.x += 1.0f;
2159 
2160             vec.z *= -1.0f;
2161             vec.z += 3.25f - 1.0f / 24.0f - 1.0f / 48.0f;
2162         }
2163         if (face == FACE_FRONT) {
2164             vec.x -= 0.5f;
2165             vec.x *= 2.0f;
2166             if (numY > 1)
2167                 vec.y *= ((float)numY - 1.0f) / (float)numY;
2168             vec.y -= 1.0f;
2169         }
2170         if (face == FACE_BACK) {
2171             vec.x -= 0.5f;
2172             vec.x *= -2.0f;
2173             if (numY > 1)
2174                 vec.y *= ((float)numY - 1.0f) / (float)numY;
2175             vec.y -= 1.0f;
2176         }
2177         if (face == FACE_RIGHT) {
2178             float temp = vec.y;
2179             vec.y = vec.z;
2180             vec.z = temp;
2181 
2182             temp = vec.y;
2183             vec.y = vec.x;
2184             vec.x = temp;
2185 
2186             vec.x += 2.0f;
2187             vec.y -= 1.0f;
2188             vec.y *= 2.0f;
2189             vec.z -= 1.0f;
2190             vec.y += 1.0f;
2191             vec.z *= ((float)numY - 1) / (float)numY;
2192         }
2193         if (face == FACE_LEFT) {
2194             float temp = vec.y;
2195             vec.y = vec.z;
2196             vec.z = temp;
2197 
2198             temp = vec.y;
2199             vec.y = vec.x;
2200             vec.x = temp;
2201 
2202             vec.y += 1.0f;
2203             vec.y *= 2.0f;
2204             vec.z *= ((float)numY - 1) / (float)numY;
2205             vec.y += 1.0f;
2206             vec.z *= -1.0f;
2207         }
2208     }
2209     storeVertexN(vertices, ci, vec, face, countX, numX, numY);
2210 }
2211 
storeVertexMid(MFVec3f * vertices,MFInt32 * ci,Vec3f newVertex,int face,int countX,int countY,int numX,int numY,bool first)2212 static void storeVertexMid(MFVec3f *vertices, MFInt32 *ci, Vec3f newVertex,
2213                            int face, int countX, int countY,
2214                            int numX, int numY, bool first)
2215 {
2216     Vec3f vec(newVertex.x, newVertex.y, newVertex.z);
2217     if (numY == 1 && numX == 2) {
2218         if (face == FACE_FRONT || face == FACE_BACK) {
2219             vec.x *= -1.0;
2220             vec.x += -1.0f / (float)numX;
2221         }
2222         if (face == FACE_TOP || face == FACE_BOTTOM) {
2223             if (face == FACE_TOP)
2224                 vec.y = 1.0;
2225             else {
2226                 vec.y = -1.0;
2227             }
2228             vec.x *= -1.0;
2229             vec.x += 1.0;
2230             vec.x += -1.0f / (float)numX;
2231         }
2232         if (face == FACE_RIGHT || face == FACE_LEFT) {
2233             vec.z *= -1.0f / (float)numX;
2234             if (face == FACE_LEFT) {
2235                 vec.x = -1.0f;
2236             } else {
2237                 vec.x = 1.0f;
2238             }
2239             vec.y -= 0.5f;
2240             vec.z -= 0.8f;
2241         }
2242     }
2243     if (numY == 1 && numX == 3) {
2244         if (face == FACE_FRONT || face == FACE_BACK) {
2245             vec.x *= -1.0;
2246             vec.x += -2.0f / (float)numX;
2247         }
2248         if (face == FACE_TOP || face == FACE_BOTTOM) {
2249             vec.x *= -1.0f;
2250             vec.x -= 1.0f / (float)numX - 1.0f;
2251             if (face == FACE_TOP)
2252                 vec.y = 1.0f;
2253             else
2254                 vec.y = -1.0f;
2255         }
2256         if (face == FACE_RIGHT || face == FACE_LEFT) {
2257             vec.z *= -1.0f / (float)numX;
2258             vec.z += -0.25f / (float)numX;
2259             vec.z += -0.01;
2260             vec.y -= 0.75f - 0.25f / (float)numX;
2261             if (face == FACE_LEFT) {
2262                 vec.x = -1.0f;
2263             } else {
2264                 vec.x = 1.0f;
2265             }
2266         }
2267     }
2268     if (numY == 2 && numX == 1) {
2269         if (face == FACE_FRONT || face == FACE_BACK) {
2270             vec.x *= -1.0f;
2271             vec.x += 0.75f;
2272         }
2273         if (face == FACE_TOP || face == FACE_BOTTOM) {
2274             vec.x *= -1.0f;
2275             vec.z *= 0.5f;
2276             if (face == FACE_TOP)
2277                 vec.y = 1.0f;
2278             else
2279                 vec.y = -1.0f;
2280             vec.x -= 0.75f;
2281             vec.z -= 0.25f;
2282         }
2283         if (face == FACE_RIGHT || face == FACE_LEFT) {
2284             if (face == FACE_RIGHT) {
2285                 vec.x = -1;
2286             } else {
2287                 vec.x = 1;
2288             }
2289             vec.y -= 0.5f;
2290             vec.z += 3.625f;
2291         }
2292     }
2293     if (numY == 2 && numX == 2) {
2294         if (face == FACE_FRONT || face == FACE_BACK) {
2295             vec.x *= -1.0f;
2296             vec.x += 0.25f;
2297         }
2298         if (face == FACE_TOP || face == FACE_BOTTOM) {
2299             vec.x *= -1.0f;
2300             vec.z *=  0.5f;
2301 
2302             if (face == FACE_TOP)
2303                 vec.y = 1.0f;
2304             else
2305                 vec.y = -1.0f;
2306             vec.x -= 0.25f;
2307             vec.z -= 0.25f;
2308         }
2309         if (face == FACE_LEFT || face == FACE_RIGHT) {
2310             vec.z *= 0.51f;
2311             if (face == FACE_RIGHT) {
2312                 vec.x = -1.0f;
2313                 vec.y -= 0.5f;
2314                 vec.z += 2.15;
2315             } else {
2316                 vec.x = 1.0f;
2317                 vec.y -= 0.5f;
2318                 vec.z += 2.15f;
2319             }
2320         }
2321     }
2322     if (numY == 2 && numX == 3) {
2323         if (face == FACE_FRONT || face == FACE_BACK) {
2324             vec.x *= -1.0f;
2325             vec.x += 0.08f;
2326         }
2327         if (face == FACE_TOP) {
2328             float temp = vec.x;
2329             vec.x = vec.z;
2330             vec.z = temp;
2331 
2332             vec.x *= 1.0f / (float)numY;
2333             vec.x -= 0.235f;
2334             vec.y = 1.0f;
2335             vec.z += 0.0815f;
2336         }
2337         if (face == FACE_BOTTOM) {
2338             float temp = vec.x;
2339             vec.x = vec.z;
2340             vec.z = temp;
2341 
2342             vec.x *= 1.0f / (float)numY;
2343             vec.x -= 0.235f;
2344             vec.y = -1.0f;
2345             vec.z += 0.1365f;
2346         }
2347         if (face == FACE_RIGHT || face == FACE_LEFT) {
2348             vec.z *= -1.0f / (float)numY;
2349             if (face == FACE_RIGHT) {
2350                 vec.x = 1.0f;
2351             }
2352             if (face == FACE_LEFT)
2353                 vec.x = -1.0f;
2354             vec.y -= 1.189f;
2355             vec.z -= 0.5f;
2356         }
2357     }
2358     if (numY == 3 && numX== 1) {
2359         if (face == FACE_FRONT || face == FACE_BACK) {
2360             vec.x *= -1.0f;
2361             vec.x += 1.716666f;
2362             vec.y -= 1.1f;
2363         }
2364     }
2365     if (numY == 3 && numX == 2) {
2366         if (face == FACE_FRONT || face == FACE_BACK) {
2367             vec.x *= -1.0f;
2368             vec.x += 1.0f;
2369             vec.x += 0.5f / (float)numY;
2370             vec.y -= 1.0f;
2371         }
2372         if (face == FACE_TOP) {
2373             vec.z *= -1.0f /numY;
2374             vec.z += -1.0f / numY;
2375             vec.x += 2.002f - 1.0f / numY;
2376             vec.y = 1.0f;
2377             vec.z += 1.10285f;
2378         }
2379         if (face == FACE_BOTTOM) {
2380             vec.z *= -1.0f / numY;
2381             vec.z += -1.0f / numY;
2382             vec.x += 1.972f - 1.0f / numY;;
2383             vec.y = -1.0f;
2384             vec.z += 1.12585f;
2385         }
2386         if (face == FACE_RIGHT) {
2387         }
2388     }
2389     if (numX == 3 && numY == 3) {
2390         if (face == FACE_TOP) {
2391             vec.z *= -1.0f / numY;
2392             vec.z += -1.0f / numY;
2393             vec.x += 1.05f;
2394             vec.y = 1.0f;
2395             vec.z += 1.11f;
2396         }
2397         if (face == FACE_BOTTOM) {
2398             vec.z *= -1.0f / numY;
2399             vec.z += -1.0f / numY;
2400             vec.x += 1.05f;
2401             vec.y = -1.0f;
2402             vec.z += 1.11f;
2403         }
2404         if (face == FACE_FRONT) {
2405             vec.x *= -1.0f;
2406             vec.x += 1.0f;
2407             vec.y -= 1.0f;
2408             vec.y *= 1.0f + 0.01f;
2409         }
2410         if (face == FACE_BACK) {
2411             vec.x *= -1.0f;
2412             vec.x += 1.05f;
2413             vec.y -= 1.0f;
2414             vec.y *= 1.0f + 0.01f;
2415         }
2416         if (face == FACE_RIGHT) {
2417             vec.x = 1.0f;
2418             vec.z *= -1.0f / numY;
2419             vec.z -= 0.5f / numY;
2420             vec.y -= 1.0f;
2421             vec.z += 1.0f;
2422             vec.z -= 0.05f;
2423         }
2424         if (face == FACE_LEFT) {
2425             vec.x = -1.0f;
2426             vec.z *= -1.0f / numY;
2427             vec.z -= 0.5f / numY;
2428             vec.y -= 1.0f;
2429             vec.z += 0.95f;
2430             vec.z -= 0.05f;
2431         }
2432     }
2433     ci->appendSFValue(vertices->getSFSize());
2434     vertices->setVec(vertices->getSFSize(), vec);
2435 }
2436 
2437 void
insetFaces(float factor,int numX,int numY)2438 NodeIndexedFaceSet::insetFaces(float factor, int numX, int numY)
2439 {
2440     m_faces.resize(0);
2441     if (m_mesh == NULL)
2442         return;
2443     NodeCoordinate *ncoord = (NodeCoordinate *)coord()->getValue();
2444     if (ncoord == NULL)
2445         return;
2446     MFVec3f *vertices = new MFVec3f((MFVec3f *)ncoord->point()->copy());
2447     MFVec3f *vertices2 = new MFVec3f((MFVec3f *)ncoord->point()->copy());
2448     MFInt32 *ci = (MFInt32 *)coordIndex()->copy();
2449     MyArray<int> facesToDelete;
2450     for (int i = 0; i < m_scene->getSelectedHandlesSize(); i++) {
2451          facesToDelete.append(m_scene->getSelectedHandle(i));
2452     }
2453     if (m_scene->getXSymetricMode())
2454         for (int i = 0; i < m_scene->getSelectedHandlesSize(); i++) {
2455             int iface = symetricFace(m_scene->getSelectedHandle(i));
2456             if (iface > -1)
2457                 if (!m_scene->isInSelectedHandles(iface))
2458                     facesToDelete.append(iface);
2459     }
2460     if (numX == 1  && numY == 1) {
2461         int inc = m_scene->getSelectedHandlesSize();
2462         int numFace = m_mesh->getNumFaces() - 1;
2463         for (long i = 0; i < facesToDelete.size(); i++) {
2464              FaceData *face = getMesh()->getFace(facesToDelete[i]);
2465              int offset = face->getOffset();
2466              int numVertices = face->getNumVertices();
2467              Vec3f mid(0, 0, 0);
2468              for (int j = offset; j < offset + numVertices; j++) {
2469                  mid += vertices->getVec(ci->getValue(j));
2470              }
2471              mid /= numVertices;
2472              int start = vertices->getSFSize();
2473              for (int j = offset; j < offset + numVertices; j++) {
2474                   Vec3f newVertex = mid + (vertices->getVec(ci->getValue(j)) -
2475                                           mid) *factor;
2476                   vertices->setVec(vertices->getSFSize(), newVertex);
2477             }
2478             for (int j = offset; j < offset + numVertices; j++) {
2479                  int k = j - offset;
2480                  ci->appendSFValue(ci->getValue(j));
2481                  if (j + 1 >= offset + numVertices)
2482                      ci->appendSFValue(ci->getValue(offset));
2483                  else
2484                      ci->appendSFValue(ci->getValue(j + 1));
2485                  if (k + 1 >= numVertices)
2486                      ci->appendSFValue(start);
2487                  else
2488                      ci->appendSFValue(start + k + 1);
2489                  ci->appendSFValue(start + k);
2490                  ci->appendSFValue(-1);
2491                  numFace++;
2492              }
2493              for (int j = offset; j < offset + numVertices; j++)
2494                  ci->appendSFValue(start + j - offset);
2495              ci->appendSFValue(-1);
2496              numFace++;
2497              if (inc == 1)
2498                  m_scene->addSelectedHandle(numFace - 1);
2499              else
2500                  m_scene->addSelectedHandle(numFace - 2 * inc);
2501         }
2502     } else {
2503         int inc = m_scene->getSelectedHandlesSize();
2504         Vec3f vecMax(-FLT_MAX, -FLT_MAX, -FLT_MAX);
2505         Vec3f vecMin(FLT_MAX, FLT_MAX, FLT_MAX);
2506         for (long i = 0; i < facesToDelete.size(); i++) {
2507              FaceData *face = getMesh()->getFace(facesToDelete[i]);
2508              int offset = face->getOffset();
2509              int numVertices = face->getNumVertices();
2510              int numYGreater0 = 0;
2511              int numYLess0 = 0;
2512              int numXGreater0 = 0;
2513              int numXLess0 = 0;
2514              int numZGreater0 = 0;
2515              int numZLess0 = 0;
2516              for (int j = offset; j < offset + numVertices; j++) {
2517                  Vec3f val = vertices->getVec(ci->getValue(j));
2518                  if (val.y > 0)
2519                      numYGreater0++;
2520                  if (val.y < 0)
2521                      numYLess0++;
2522                  if (val.x > 0)
2523                      numXGreater0++;
2524                  if (val.x < 0)
2525                      numXLess0++;
2526                  if (val.z > 0)
2527                      numZGreater0++;
2528                  if (val.z < 0)
2529                      numZLess0++;
2530 
2531                  if (val.x > vecMax.x)
2532                      vecMax.x = val.x;
2533                  if (val.y > vecMax.y)
2534                      vecMax.y = val.y;
2535                  if (val.z > vecMax.z)
2536                      vecMax.z = val.z;
2537                  if (val.x < vecMin.x)
2538                      vecMin.x = val.x;
2539                  if (val.y < vecMin.y)
2540                      vecMin.y = val.y;
2541                  if (val.z < vecMin.z)
2542                      vecMin.z = val.z;
2543              }
2544              if (numYGreater0 > numYLess0 &&
2545                  numYGreater0 > numXLess0 &&
2546                  numYGreater0 > numYLess0 &&
2547                  numYGreater0 > numXGreater0 &&
2548                  numYGreater0 > numZGreater0)
2549                  face->setType(FACE_TOP);
2550              if (numYLess0 > numYGreater0 &&
2551                  numYLess0 > numXGreater0 &&
2552                  numYLess0 > numZGreater0 &&
2553                  numYLess0 > numXLess0 &&
2554                  numYLess0 > numZLess0)
2555                  face->setType(FACE_BOTTOM);
2556              if (numXGreater0 > numYLess0 &&
2557                  numXGreater0 > numXLess0 &&
2558                  numXGreater0 > numYLess0 &&
2559                  numXGreater0 > numYGreater0 &&
2560                  numXGreater0 > numZGreater0)
2561                  face->setType(FACE_RIGHT);
2562              if (numXLess0 > numYGreater0 &&
2563                  numXLess0 > numXGreater0 &&
2564                  numXLess0 > numZGreater0 &&
2565                  numXLess0 > numYLess0 &&
2566                  numXLess0 > numZLess0)
2567                  face->setType(FACE_LEFT);
2568              if (numZGreater0 > numYLess0 &&
2569                  numZGreater0 > numXLess0 &&
2570                  numZGreater0 > numYLess0 &&
2571                  numZGreater0 > numXGreater0 &&
2572                  numZGreater0 > numYGreater0)
2573                  face->setType(FACE_FRONT);
2574              if (numZLess0 > numYGreater0 &&
2575                  numZLess0 > numXGreater0 &&
2576                  numZLess0 > numZGreater0 &&
2577                  numZLess0 > numXLess0 &&
2578                  numZLess0 > numYLess0)
2579                  face->setType(FACE_BACK);
2580         }
2581         float f = (1.0f - factor);
2582         Vec3f lenX((vecMax.x - vecMin.x) * f / numX, 0.0f,
2583                    (vecMax.z - vecMin.z) * f / numX);
2584         bool zDirection = false;
2585         if (lenX.z > lenX.x)
2586             zDirection = true;
2587         Vec3f lenY(0.0f, (vecMax.y - vecMin.y) * f / numY, 0.0f);
2588         for (int n = 0; n < numX; n++)
2589             for (int m = 0; m < numY; m++)
2590                 for (long i = 0; i < facesToDelete.size(); i++) {
2591                     FaceData *face = getMesh()->getFace(facesToDelete[i]);
2592                     int offset = face->getOffset();
2593                     int numVertices = face->getNumVertices();
2594                     Vec3f mid(0, 0, 0);
2595                     for (int j = offset; j < offset + numVertices; j++) {
2596                         mid += vertices2->getVec(ci->getValue(j));
2597                     }
2598                     mid /= numVertices;
2599                     int midstart = vertices->getSFSize();
2600                     for (int j = offset + numVertices - 1; j >= offset; j--) {
2601                         Vec3f newVertex = mid +
2602                                           (vertices2->getVec(ci->getValue(j))
2603                                           - mid) * factor;
2604 
2605                         newVertex.x *= lenX.x;
2606                         newVertex.y *= lenY.y;
2607                         float xoffset = 0.0f;
2608                         float yoffset = 0.0f;
2609                         if (numY == 2) {
2610                             xoffset -= 1.0f / (float)numY + 0.5f / (float)numY;
2611                             yoffset -= 1.0f / (float)numY;
2612                         }
2613                         if (numY == 3) {
2614                             xoffset = 1.0f / (float)numY - 2.0f;
2615                             yoffset = 1.0f / (float)numY;
2616                         }
2617                         if (face->getType() == FACE_FRONT ||
2618                             face->getType() == FACE_BACK) {
2619                             newVertex.x -= xoffset +
2620                                            2.0f * (float)n / (float)numX;
2621                             newVertex.y += yoffset +
2622                                             2.0f * (float)m / (float)numY;
2623                         }
2624                         if (face->getType() == FACE_TOP ||
2625                             face->getType() == FACE_BOTTOM) {
2626                              newVertex.x += xoffset +
2627                                             (2.0f * (float)n) / (float)numX;
2628                              if (numY == 2) {
2629                                  if (numX == 1) {
2630                                      newVertex.z += yoffset +
2631                                                     4.0f * (float)m /
2632                                                         (float)numY;
2633                                  } else if (numX == 2) {
2634                                      newVertex.z += yoffset +
2635                                                     4.0f * (float)m /
2636                                                         (float)numY;
2637                                  } else
2638                                      newVertex.z += yoffset +
2639                                                     4.0f * (float)m /
2640                                                         (float)numY;
2641                              }
2642                              if (numY == 3)
2643                                  newVertex.z += yoffset +
2644                                                 6.0f * (float)m / (float)numY;
2645                         }
2646                         if (face->getType() == FACE_RIGHT ||
2647                             face->getType() == FACE_LEFT) {
2648                              if (numY == 1) {
2649                                  yoffset = 1.0f;
2650                                  newVertex.z += -0.12f + 1.5f - 3.0f -
2651                                                  2.0f / (float)numX +
2652                                                  2.0f * (float)numY * (float)n;
2653                                  newVertex.y += yoffset - 1.0f / (float)numX +
2654                                                 1.0f * (float)m;
2655                              }
2656                              if (numY == 2) {
2657                                  yoffset = 1.0f;
2658                                  newVertex.z += -0.12f + 1.5f - 3.0f -
2659                                                  2.0f / (float)numX +
2660                                                  0.66f * (float)numY * (float)n;
2661                                  if (numX == 2) {
2662                                       newVertex.z += -0.12f + 1.5f - 3.0f -
2663                                                      2.0f / (float)numX +
2664                                                      0.36f * (float)numY *
2665                                                          (float)n;
2666                                       newVertex.y += yoffset
2667                                                      - 2.0f / (float)numX +
2668                                                      1.0f * (float)m;
2669                                  } else
2670                                       newVertex.y += yoffset
2671                                                      - 1.0f / (float)numX +
2672                                                      1.0f * (float)m;
2673                              }
2674                              if (numY == 3) {
2675                                  newVertex.y += 1.0f / (float)numY +
2676                                                 2.0f * (float)n / (float) numX;
2677                                  newVertex.z += yoffset +
2678                                                 6.0f * (float)m / (float)numY;
2679                             }
2680                         }
2681                         storeVertexMid(vertices, ci, newVertex, face->getType(),
2682                                        n, m, numX, numY, false);
2683                     }
2684                     ci->appendSFValue(-1);
2685                 }
2686         for (int n = 0; n < numX; n++)
2687             for (int m = 0; m < numY; m++)
2688                 for (long i = 0; i < facesToDelete.size(); i++) {
2689                     FaceData *face = getMesh()->getFace(facesToDelete[i]);
2690                     int offset = face->getOffset();
2691                     int numVertices = face->getNumVertices();
2692                     for (int j = offset; j < offset + numVertices; j++) {
2693                         if (j == offset) {
2694                             // right limiter
2695                             Vec3f startVertex =
2696                                  vertices->getVec(ci->getValue(j));
2697 
2698                             if (numY == 1 && numX == 2) {
2699                                 if (face->getType() == FACE_FRONT ||
2700                                     face->getType() == FACE_BACK) {
2701                                     startVertex.y -= 1.0;
2702                                 }
2703                                 if (face->getType() == FACE_TOP ||
2704                                     face->getType() == FACE_BOTTOM) {
2705                                     startVertex.y -= 1.0;
2706                                 }
2707                                 if (face->getType() == FACE_RIGHT ||
2708                                     face->getType() == FACE_LEFT) {
2709                                     startVertex.y -= 1.0;
2710                                 }
2711                             }
2712                             if (numY == 1 && numX == 3) {
2713                                 if (face->getType() == FACE_FRONT ||
2714                                     face->getType() == FACE_BACK) {
2715                                     startVertex.x += 3.0f / (float)numX;
2716                                     startVertex.y -= 2.0f;
2717                                 }
2718                                 if (face->getType() == FACE_TOP ||
2719                                     face->getType() == FACE_BOTTOM) {
2720                                     startVertex.y -= 1.0f;
2721                                 }
2722                                 if (face->getType() == FACE_RIGHT) {
2723                                     startVertex.y -= 1.0f;
2724                                 }
2725                                 if (face->getType() == FACE_LEFT) {
2726                                     startVertex.y -= 1.0f;
2727                                 }
2728                             }
2729                             if (numY == 2 && numX == 3) {
2730                                 if (face->getType() == FACE_FRONT ||
2731                                     face->getType() == FACE_BACK) {
2732                                     startVertex.x += 1.09f;// - 1.0f / (float)numX;
2733                                     startVertex.y += 1.0f + 2.25f / (float)numX;
2734                                 }
2735                                 if (face->getType() == FACE_TOP ||
2736                                     face->getType() == FACE_BOTTOM) {
2737                                     startVertex.x += 1.0f;
2738                                     startVertex.y += 1.0f +
2739                                                      2.25f / (float)numX;
2740                                 }
2741                                 if (face->getType() == FACE_RIGHT ||
2742                                     face->getType() == FACE_LEFT) {
2743                                     startVertex.x += 1.0f;
2744                                     startVertex.y += 2.0f - 0.5f / numX - 0.1;
2745                                 }
2746                                 startVertex.y += - 2.0f + 0.25f;
2747                             }
2748                             if (numY == 3 && numX == 1) {
2749                                 if (face->getType() == FACE_FRONT ||
2750                                     face->getType() == FACE_BACK) {
2751                                     startVertex.y += 1.0f;
2752                                 }
2753                                 if (face->getType() == FACE_TOP ||
2754                                     face->getType() == FACE_BOTTOM) {
2755                                     startVertex.y += 3.0f;
2756                                 }
2757                                 if (face->getType() == FACE_RIGHT ||
2758                                     face->getType() == FACE_LEFT) {
2759                                     startVertex.y += 1.0f;
2760                                 }
2761                             }
2762                             if (numY == 3 && numX == 2) {
2763                                 if (face->getType() == FACE_FRONT ||
2764                                     face->getType() == FACE_BACK) {
2765                                     startVertex.y += 1.0f;
2766                                 }
2767                                 if (face->getType() == FACE_TOP ||
2768                                     face->getType() == FACE_BOTTOM) {
2769                                     startVertex.y += 1.0f;
2770                                 }
2771                                 if (face->getType() == FACE_RIGHT ||
2772                                     face->getType() == FACE_LEFT) {
2773                                     startVertex.y -= 3.0f;
2774                                 }
2775                             }
2776                             if (numY == 3 && numX == 3) {
2777                                 if (face->getType() == FACE_TOP)
2778                                     startVertex.y += 1.0f +
2779                                                      1.0f / (float)numY +
2780                                                      0.5f / (float)numY;
2781 
2782                                 if (face->getType() == FACE_BOTTOM)
2783                                     startVertex.y += 1.0f +
2784                                                      1.0f / (float)numY +
2785                                                      0.5f / (float)numY;
2786 
2787                                 if (face->getType() == FACE_FRONT)
2788                                     startVertex.x += 1.0f;
2789                                 if (face->getType() == FACE_FRONT)
2790                                     startVertex.y += 2.0f / (float)numY;
2791                                 if (face->getType() == FACE_FRONT)
2792                                     startVertex.y += 1.0f / (float)numY;
2793                                 if (face->getType() == FACE_FRONT)
2794                                     startVertex.y += 0.5f / 3.0f / (float)numY -
2795                                                      0.125f / 4.0f;
2796 
2797                                 if (face->getType() == FACE_BACK)
2798                                     startVertex.x += 1.0f;
2799                                 if (face->getType() == FACE_BACK)
2800                                     startVertex.y += 2.0f / (float)numY;
2801                                 if (face->getType() == FACE_BACK)
2802                                     startVertex.y += 1.0f / (float)numY;
2803                                 if (face->getType() == FACE_BACK)
2804                                     startVertex.y += 0.5f / 3.0f / (float)numY -
2805                                                      0.125f / 4.0f;
2806 
2807                                 if (face->getType() == FACE_RIGHT)
2808                                     startVertex.y += 1.0f / (float)numY -
2809                                                      0.25f / (float)numY + 0.25;
2810                                 if (face->getType() == FACE_LEFT)
2811                                     startVertex.y -= 1.5 / (float)numY;
2812                             }
2813 
2814                             Vec3f newVertex = startVertex;
2815 
2816                             newVertex.x -= border1(n, numX);
2817                             newVertex.y -= border1(m, numY);
2818 
2819                             storeVertex(vertices, ci, newVertex,
2820                                         face->getType(), n,m, numX, numY);
2821 
2822                             newVertex = startVertex;
2823 
2824                             newVertex.x -= border2(n, numX);
2825                             newVertex.y -= border2(m, numY);
2826 
2827                             storeVertex(vertices, ci, newVertex,
2828                                         face->getType(), n, m, numX, numY);
2829 
2830                             newVertex = startVertex;
2831 
2832                             newVertex.x -= border2(n, numX);
2833                             newVertex.y -= border3(m, numY);
2834 
2835                             storeVertex(vertices, ci, newVertex,
2836                                         face->getType(), n, m, numX, numY);
2837 
2838                             newVertex = startVertex;
2839 
2840                             newVertex.x -= border1(n, numX);
2841                             newVertex.y -= border4(m, numY);
2842 
2843                             storeVertex(vertices, ci, newVertex,
2844                                         face->getType(), n ,m,numX, numY);
2845                             ci->appendSFValue(-1);
2846                         }
2847                         if (j == offset + 1) {
2848                             // top limiter
2849                             Vec3f startVertex = vertices->getVec(
2850                                  ci->getValue(j - 1));
2851 
2852                             if (numY == 1 && numX == 2) {
2853                                 if (face->getType() == FACE_FRONT ||
2854                                     face->getType() == FACE_BACK) {
2855                                     startVertex.y += 1.0;
2856                                 }
2857                                 if (face->getType() == FACE_TOP ||
2858                                     face->getType() == FACE_BOTTOM) {
2859                                     startVertex.y -= 1.0;
2860                                 }
2861                                 if (face->getType() == FACE_RIGHT ||
2862                                     face->getType() == FACE_LEFT) {
2863                                     startVertex.y -= 1.0;
2864                                 }
2865                             }
2866                             if (numY == 1 && numX == 3) {
2867                                 if (face->getType() == FACE_FRONT ||
2868                                     face->getType() == FACE_BACK) {
2869                                     startVertex.y -= 2.0f;
2870                                     startVertex.x += 3.0f / numX;
2871                                 }
2872                                 if (face->getType() == FACE_TOP ||
2873                                     face->getType() == FACE_BOTTOM) {
2874                                     startVertex.y -= 1.0f;
2875                                 }
2876                                 if (face->getType() == FACE_RIGHT ||
2877                                     face->getType() == FACE_LEFT) {
2878                                     startVertex.y -= 1.0f;
2879                                 }
2880                             }
2881                             if (numY == 2 && numX == 3) {
2882                                 startVertex.x += 1.0f;
2883                             }
2884                             if (numY == 3 && numX == 1) {
2885                                 if (face->getType() == FACE_FRONT ||
2886                                     face->getType() == FACE_BACK) {
2887                                     startVertex.y += 1.0f;
2888                                 }
2889                             }
2890                             if (numY == 3 && numX == 2) {
2891                                 startVertex.y += 1.0f;
2892                             }
2893                             if (numY == 3 && numX == 3) {
2894                                 if (face->getType() == FACE_TOP) {
2895                                     startVertex.y += 4.5f /(float)numY;
2896                                 }
2897                                 if (face->getType() == FACE_BOTTOM) {
2898                                     startVertex.y += 4.5f /(float)numY;
2899                                 }
2900 
2901                                 if (face->getType() == FACE_FRONT)
2902                                     startVertex.x += 1.0f;
2903                                 if (face->getType() == FACE_FRONT)
2904                                     startVertex.y += 1.5f;
2905                                 if (face->getType() == FACE_FRONT)
2906                                     startVertex.y -= 1.0f / (float)numY +
2907                                                      0.5f / (float)numY;
2908                                 if (face->getType() == FACE_FRONT)
2909                                     startVertex.y += 0.5f / 3.0f / (float)numY;
2910 
2911                                 if (face->getType() == FACE_BACK)
2912                                     startVertex.x += 1.0f;
2913                                 if (face->getType() == FACE_BACK)
2914                                     startVertex.y += 1.5f;
2915                                 if (face->getType() == FACE_BACK)
2916                                     startVertex.y -= 1.0f / (float)numY +
2917                                                      0.5f / (float)numY;
2918                                 if (face->getType() == FACE_BACK)
2919                                     startVertex.y += 0.5f / 3.0f / (float)numY;
2920 
2921                                 if (face->getType() == FACE_RIGHT)
2922                                     startVertex.y += 1.5f / (float)numY;
2923                                 if (face->getType() == FACE_LEFT)
2924                                     startVertex.y -= 1.5f / (float)numY;
2925                             }
2926 
2927                             Vec3f newVertex = startVertex;
2928 
2929                             newVertex.x -= border4(n, numX);
2930                             newVertex.y -= border1(m, numY);
2931 
2932                             storeVertex(vertices, ci, newVertex,
2933                                         face->getType(), n,m, numX, numY);
2934 
2935                             newVertex = startVertex;
2936 
2937                             newVertex.x -= border3(n, numX);
2938                             newVertex.y -= border2(m, numY);
2939 
2940                             storeVertex(vertices, ci, newVertex,
2941                                         face->getType(), n, m, numX, numY);
2942 
2943                             newVertex = startVertex;
2944 
2945                             newVertex.x -= border2(n, numX);
2946                             newVertex.y -= border2(m, numY);
2947 
2948                             storeVertex(vertices, ci, newVertex,
2949                                         face->getType(), n, m, numX, numY);
2950 
2951                             newVertex = startVertex;
2952 
2953                             newVertex.x -= border1(n, numX);
2954                             newVertex.y -= border1(m, numY);
2955 
2956                             storeVertex(vertices, ci, newVertex,
2957                                         face->getType(), n, m, numX, numY);
2958                              ci->appendSFValue(-1);
2959                         }
2960                         if (j == offset + 2) {
2961                             // bottom limiter
2962                             Vec3f startVertex =
2963                                  vertices->getVec(ci->getValue(j - 2));
2964 
2965                             if (numY == 1 && numX == 3) {
2966                                 if (face->getType() == FACE_FRONT ||
2967                                     face->getType() == FACE_BACK) {
2968                                     startVertex.y -= 1.0f;
2969                                     startVertex.x += 1.00f;
2970                                 }
2971                             }
2972                             if (numY == 2 && numX == 3) {
2973                                 startVertex.x += 1.0f;
2974                             }
2975                             if (numY == 3 && numX == 3) {
2976                                 if (face->getType() == FACE_TOP) {
2977                                     startVertex.y += 4.0f / (float)numY -
2978                                                      2.5f / (float)numY;
2979                                 }
2980                                 if (face->getType() == FACE_BOTTOM) {
2981                                     startVertex.y += 4.0f / (float)numY -
2982                                                      2.5f / (float)numY;
2983                                 }
2984 
2985                                 if (face->getType() == FACE_FRONT)
2986                                     startVertex.x += 1.0f;
2987                                 if (face->getType() == FACE_FRONT)
2988                                     startVertex.y -= - 0.5f / (float)numY + 0.25f;
2989                                 if (face->getType() == FACE_FRONT)
2990                                     startVertex.y += 0.125f / 4.0f;
2991                                 if (face->getType() == FACE_FRONT)
2992                                     startVertex.y += 0.5f / 3.0f / (float)numY;
2993 
2994                                 if (face->getType() == FACE_BACK)
2995                                     startVertex.x += 1.0f;
2996                                 if (face->getType() == FACE_BACK)
2997                                     startVertex.y -= - 0.5f / (float)numY + 0.25f;
2998                                 if (face->getType() == FACE_BACK)
2999                                     startVertex.y += 0.125f / 4.0f;
3000                                 if (face->getType() == FACE_BACK)
3001                                     startVertex.y += 0.5f / 3.0f / (float)numY;
3002 
3003                                 if (face->getType() == FACE_RIGHT)
3004                                     startVertex.y -= 1.0f / (float)numY +
3005                                                  0.5f / (float)numY;
3006                                 if (face->getType() == FACE_LEFT)
3007                                     startVertex.y -= 4.5f / (float)numY;
3008 
3009                             }
3010 
3011                             Vec3f newVertex = startVertex;
3012 
3013                             newVertex.x -= border1(n, numX);
3014                             newVertex.y += border1(m, numY);
3015 
3016                             storeVertex(vertices, ci, newVertex,
3017                                         face->getType(), n, m, numX, numY);
3018 
3019                             newVertex = startVertex;
3020 
3021                             newVertex.x -= border2(n, numX);
3022                             newVertex.y += border2(m, numY);
3023 
3024                             storeVertex(vertices, ci, newVertex,
3025                                         face->getType(), n, m, numX, numY);
3026 
3027                             newVertex = startVertex;
3028 
3029                             newVertex.x -= border3(n, numX);
3030                             newVertex.y += border2(m, numY);
3031 
3032                             storeVertex(vertices, ci, newVertex,
3033                                         face->getType(), n, m, numX, numY);
3034 
3035                             newVertex = startVertex;
3036 
3037                             newVertex.x -= border4(n, numX);
3038                             newVertex.y += border1(m, numY);
3039 
3040                             storeVertex(vertices, ci, newVertex,
3041                                         face->getType(), n, m, numX, numY);
3042                             ci->appendSFValue(-1);
3043                         }
3044                         if (j == offset + 3) {
3045                             // left limiter
3046                             Vec3f startVertex = vertices->getVec(
3047                                  ci->getValue(j - 3));
3048 
3049                             if (numY == 1 && numX == 3) {
3050                                 if (face->getType() == FACE_FRONT ||
3051                                     face->getType() == FACE_BACK) {
3052                                     startVertex.x += 3.0f / (float)numX;
3053                                     startVertex.y *= 2.0f;
3054                                     startVertex.y -= 2.0f;
3055                                 }
3056                             }
3057                             if (numX == 2 && numY == 2) {
3058                                 if (face->getType() == FACE_RIGHT ||
3059                                     face->getType() == FACE_LEFT) {
3060                                     startVertex.x += 2.0f / (float)numY;
3061                                 }
3062                                 if (face->getType() == FACE_RIGHT ||
3063                                     face->getType() == FACE_LEFT) {
3064                                     startVertex.x -= 1.0;
3065                                 }
3066                             }
3067                             if (numY == 2 && numX == 3) {
3068                                 startVertex.x += 1.0f;
3069                             }
3070                             if (numX == 3 && numY == 3) {
3071                                 if (face->getType() == FACE_FRONT)
3072                                     startVertex.x += 1.0f;
3073                                 if (face->getType() == FACE_FRONT)
3074                                     startVertex.y += 0.5f / 3.0f / (float)numY;
3075 
3076                                 if (face->getType() == FACE_BACK)
3077                                     startVertex.x += 1.0f;
3078                                 if (face->getType() == FACE_BACK)
3079                                     startVertex.y += 0.5f / 3.0f / (float)numY;
3080 
3081                                 if (face->getType() == FACE_TOP) {
3082                                     startVertex.y += 1.5f / numY;
3083                                 }
3084                                 if (face->getType() == FACE_BOTTOM) {
3085                                     startVertex.y += 1.5f / numY;
3086                                 }
3087                                 if (face->getType() == FACE_RIGHT)
3088                                     startVertex.y -= 1.0f / (float)numY +
3089                                                      0.5f / (float)numY;
3090                                 if (face->getType() == FACE_LEFT)
3091                                     startVertex.y -= 4.5f / (float)numY;
3092                             }
3093                             Vec3f newVertex = startVertex;
3094 
3095                             newVertex.x -= border4(n, numX);
3096                             newVertex.y += border1(m, numY);
3097 
3098                             storeVertex(vertices, ci, newVertex,
3099                                         face->getType(), n, m, numX, numY);
3100 
3101                             newVertex = startVertex;
3102 
3103                             newVertex.x -= border3(n, numX);
3104                             newVertex.y += border2(m, numY);
3105 
3106                             storeVertex(vertices, ci, newVertex,
3107                                         face->getType(), n, m, numX, numY);
3108 
3109                             newVertex = startVertex;
3110 
3111                             newVertex.x -= border3(n, numX);
3112                             newVertex.y += border3(m, numY);
3113 
3114                             storeVertex(vertices, ci, newVertex,
3115                                         face->getType(), n, m, numX, numY);
3116 
3117                             newVertex = startVertex;
3118 
3119                             newVertex.x -= border4(n, numX);
3120                             newVertex.y += border4(m, numY);
3121 
3122                             storeVertex(vertices, ci, newVertex,
3123                                         face->getType(), n, m, numX, numY);
3124 
3125                             ci->appendSFValue(-1);
3126                         }
3127                     }
3128                 }
3129     }
3130     deleteFaces(ci, &facesToDelete);
3131 
3132     m_scene->backupFieldsStart();
3133     m_scene->backupFieldsAppend(ncoord, ncoord->point_Field());
3134     m_scene->backupFieldsAppend(this, color_Field());
3135     m_scene->backupFieldsAppend(this, normal_Field());
3136     m_scene->backupFieldsAppend(this, texCoord_Field());
3137     m_scene->backupFieldsAppend(this, coordIndex_Field());
3138     m_scene->backupFieldsAppend(this, colorIndex_Field());
3139     m_scene->backupFieldsAppend(this, normalIndex_Field());
3140     m_scene->backupFieldsAppend(this, texCoordIndex_Field());
3141     m_scene->backupFieldsDone();
3142 
3143     ncoord->point(new MFVec3f(*vertices));
3144     coordIndex(new MFInt32(*ci));
3145     color(new SFNode(NULL));
3146     normal(new SFNode(NULL));
3147     texCoord(new SFNode(NULL));
3148 
3149     m_meshDirty = true;
3150 }
3151 
3152 Node *
simpleJoin(MyArray<FacesetAndMatrix> data)3153 NodeIndexedFaceSet::simpleJoin(MyArray<FacesetAndMatrix> data)
3154 {
3155     NodeIndexedFaceSet *ret = NULL;
3156     MFVec3f *vertices = new MFVec3f();
3157     MFInt32 *ci = new MFInt32();
3158     MFColorRGBA *colorRGBA = new MFColorRGBA();
3159     MFColor *color = new MFColor();
3160     Scene *scene = NULL;
3161     if (data.size() > 0) {
3162         scene = data[0].node->getScene();
3163         bool x3d = scene->isX3d();
3164         ret = (NodeIndexedFaceSet *)scene->createNode("IndexedFaceSet");
3165         ret->coord(new SFNode(scene->createNode("Coordinate")));
3166         if (x3d)
3167             ret->color(new SFNode(scene->createNode("ColorRGBA")));
3168         else
3169             ret->color(new SFNode(scene->createNode("Color")));
3170         int numCi = 0;
3171         for (long i = 0; i < data.size(); i++) {
3172             NodeIndexedFaceSet *node = data[i].node;
3173             MyMesh *mesh = node->getMesh();
3174             MFVec3f *vert = mesh->getVertices();
3175             MFFloat *colors = mesh->getColors();
3176             int offset = 3;
3177             if (mesh->hasColorRGBA())
3178                 offset = 4;
3179             MFInt32 *coordIndex = mesh->getCoordIndex();
3180             for (int j = 0; j < vert->getSFSize(); j++) {
3181                 vertices->appendVec(data[i].matrix * vert->getVec(j));
3182                 if (data[i].material != NULL) {
3183                     float *c = (float *)
3184                         data[i].material->diffuseColor()->getValue();
3185                     if (colors && colors->getSize() > 0) {
3186                         c[0] = colors->getValue(j * offset);
3187                         c[1] = colors->getValue(j * offset + 1);
3188                         c[2] = colors->getValue(j * offset + 2);
3189                     }
3190                     float t = data[i].material->transparency()->getValue();
3191                     if (colors && (colors->getSize() > 0) &&
3192                         mesh->hasColorRGBA())
3193                         t = 1 - colors->getValue(j * offset + 3);
3194                     if (x3d)
3195                         colorRGBA->appendSFValue(c[0], c[1], c[2], 1 - t);
3196                     else
3197                         color->appendSFValue(c[0], c[1], c[2]);
3198                 }
3199             }
3200             for (int j = 0; j < coordIndex->getSFSize(); j++)
3201                 if (coordIndex->getValue(j) < 0)
3202                     ci->appendSFValue(coordIndex->getValue(j));
3203                 else
3204                     ci->appendSFValue(coordIndex->getValue(j) + numCi);
3205             if (coordIndex->getValue(coordIndex->getSFSize() - 1) > -1) {
3206                 ci->appendSFValue(-1);
3207                 numCi++;
3208             }
3209             numCi += vert->getSFSize();
3210         }
3211         NodeCoordinate *ncoord = ((NodeCoordinate *)ret->coord()->getValue());
3212         ncoord->point(new MFVec3f(*vertices));
3213         if (x3d) {
3214             NodeColorRGBA *ncolor = ((NodeColorRGBA *)ret->color()->getValue());
3215             ncolor->color(new MFColorRGBA(*colorRGBA));
3216         } else {
3217             NodeColor *ncolor = ((NodeColor *)ret->color()->getValue());
3218             ncolor->color(new MFColor(*color));
3219         }
3220         ret->coordIndex(new MFInt32(*ci));
3221 
3222         return ret;
3223     }
3224 
3225     return NULL;
3226 }
3227 
3228 void
changeToColorPerVertex(void)3229 NodeIndexedFaceSet::changeToColorPerVertex(void)
3230 {
3231     if (m_alreadyInChangeColorPerVertex)
3232         return;
3233     m_alreadyInChangeColorPerVertex = true;
3234     if (hasColorRGBA()) {
3235         NodeColorRGBA *ncolor = (NodeColorRGBA *)color()->getValue();
3236         if (ncolor == NULL)
3237             return;
3238         MFColorRGBA *colors = ncolor->color();
3239         MFColorRGBA *newColors = new MFColorRGBA();
3240         if (getMesh() == NULL)
3241             return;
3242         for (int i = 0; i < getMesh()->getNumFaces(); i++) {
3243             FaceData *face = getMesh()->getFace(i);
3244             int offset = face->getOffset();
3245             int numVertices = face->getNumVertices();
3246             float r = 0;
3247             float g = 0;
3248             float b = 0;
3249             float a = 0;
3250             for (int j = offset; j < offset + numVertices; j++) {
3251                  int ci = coordIndex()->getValue(j);
3252                  r += colors->getValue(ci)[0];
3253                  g += colors->getValue(ci)[1];
3254                  b += colors->getValue(ci)[2];
3255                  a += colors->getValue(ci)[3];
3256             }
3257             newColors->appendSFValue(r / numVertices,
3258                                      g / numVertices,
3259                                      b / numVertices,
3260                                      a / numVertices);
3261         }
3262 
3263         m_scene->backupFieldsStart();
3264         m_scene->backupFieldsAppend(ncolor, ncolor->color_Field());
3265         m_scene->backupFieldsAppend(this, color_Field());
3266         m_scene->backupFieldsAppend(this, colorPerVertex_Field());
3267         m_scene->backupFieldsDone();
3268 
3269         ncolor->color(newColors);
3270         color(new SFNode(ncolor, -1));
3271         colorPerVertex(new SFBool(true));
3272     } else {
3273         NodeColor *ncolor = (NodeColor *)color()->getValue();
3274         if (ncolor == NULL)
3275             return;
3276         MFColor *colors = ncolor->color();
3277         MFColor *newColors = new MFColor();
3278         if (getMesh() == NULL)
3279             return;
3280         for (int i = 0; i < getMesh()->getNumFaces(); i++) {
3281             FaceData *face = getMesh()->getFace(i);
3282             int offset = face->getOffset();
3283             int numVertices = face->getNumVertices();
3284             float r = 0;
3285             float g = 0;
3286             float b = 0;
3287             for (int j = offset; j < offset + numVertices; j++) {
3288                 int ci = coordIndex()->getValue(j);
3289                 r += colors->getValue(ci)[0];
3290                 g += colors->getValue(ci)[1];
3291                 b += colors->getValue(ci)[2];
3292             }
3293             newColors->appendSFValue(r / numVertices,
3294                                      g / numVertices,
3295                                      b / numVertices);
3296         }
3297 
3298         m_scene->backupFieldsStart();
3299         m_scene->backupFieldsAppend(ncolor, ncolor->color_Field());
3300         m_scene->backupFieldsAppend(this, color_Field());
3301         m_scene->backupFieldsAppend(this, colorPerVertex_Field());
3302         m_scene->backupFieldsDone();
3303 
3304         ncolor->color(newColors);
3305         color(new SFNode(ncolor, -1));
3306         colorPerVertex(new SFBool(true));
3307     }
3308     m_alreadyInChangeColorPerVertex = false;
3309 }
3310 
3311 void
changeToColorPerFace(void)3312 NodeIndexedFaceSet::changeToColorPerFace(void)
3313 {
3314     if (m_alreadyInChangeColorPerVertex)
3315         return;
3316     m_alreadyInChangeColorPerVertex = true;
3317     if (hasColorRGBA()) {
3318         NodeColorRGBA *ncolor = (NodeColorRGBA *)color()->getValue();
3319         if (ncolor == NULL)
3320             return;
3321         MFColorRGBA *colors = ncolor->color();
3322         MFColorRGBA *newColors = new MFColorRGBA();
3323         if (getMesh() == NULL)
3324             return;
3325         for (int i = 0; i < getMesh()->getNumFaces(); i++) {
3326             FaceData *face = getMesh()->getFace(i);
3327             int offset = face->getOffset();
3328             int numVertices = face->getNumVertices();
3329             float r = 0.8;
3330             float g = 0.8;
3331             float b = 0.8;
3332             float a = 1;
3333             for (int j = offset; j < offset + numVertices; j++) {
3334                 if (i <= colors->getSFSize()) {
3335                     r = colors->getValue(i)[0];
3336                     g = colors->getValue(i)[1];
3337                     b = colors->getValue(i)[2];
3338                     a = colors->getValue(i)[3];
3339                 }
3340             }
3341             newColors->appendSFValue(r, g, b, a);
3342         }
3343 
3344         if (getMesh()->getNumFaces() > 0) {
3345             m_scene->backupFieldsStart();
3346             m_scene->backupFieldsAppend(ncolor, ncolor->color_Field());
3347             m_scene->backupFieldsAppend(this, color_Field());
3348             m_scene->backupFieldsAppend(this, colorPerVertex_Field());
3349             m_scene->backupFieldsDone();
3350 
3351             ncolor->color(newColors);
3352             color(new SFNode(ncolor, -1));
3353             colorPerVertex(new SFBool(false));
3354         }
3355     } else {
3356         NodeColor *ncolor = (NodeColor *)color()->getValue();
3357         if (ncolor == NULL)
3358             return;
3359         MFColor *colors = ncolor->color();
3360         MFColor *newColors = new MFColor();
3361         if (getMesh() == NULL)
3362             return;
3363         for (int i = 0; i < getMesh()->getNumFaces(); i++) {
3364             FaceData *face = getMesh()->getFace(i);
3365             int offset = face->getOffset();
3366             int numVertices = face->getNumVertices();
3367             float r = 0.8;
3368             float g = 0.8;
3369             float b = 0.8;
3370             for (int j = offset; j < offset + numVertices; j++) {
3371                 if (i <= colors->getSFSize()) {
3372                     r = colors->getValue(i)[0];
3373                     g = colors->getValue(i)[1];
3374                     b = colors->getValue(i)[2];
3375                 }
3376             }
3377             newColors->appendSFValue(r, g, b);
3378         }
3379 
3380         if (getMesh()->getNumFaces() > 0) {
3381             m_scene->backupFieldsStart();
3382             m_scene->backupFieldsAppend(ncolor, ncolor->color_Field());
3383             m_scene->backupFieldsAppend(this, color_Field());
3384             m_scene->backupFieldsAppend(this, colorPerVertex_Field());
3385             m_scene->backupFieldsDone();
3386 
3387             ncolor->color(newColors);
3388             color(new SFNode(ncolor, -1));
3389             colorPerVertex(new SFBool(false));
3390       }
3391     }
3392     m_alreadyInChangeColorPerVertex = false;
3393 }
3394 int
getProfile(void) const3395 NodeIndexedFaceSet::getProfile(void) const
3396 {
3397     // TODO:
3398     // X3D each face is terminated with coordIndex = -1, even the last
3399     // X3D check repeating coordIndex
3400 
3401     /* the following criteria are required from each IndexedFaceSet
3402        "otherwise the results are undefined" in ISO/IEt 19775:2005 13.3.6
3403 
3404        - X3D check planar polygons
3405        - X3D check 3 non-coincident vertices
3406        - X3D check self-intersection polygon
3407 
3408        In ISO/IEC 19775:2005 table B3 (incerchange profile) this criteria are
3409        repeated as requirement for the interchange profile, but they are not
3410        repeated in ISO/IEc 19775:2005 table E.3 (immersive profile) and
3411        ISO/IEC 19775:2005 table F.3 (full profile).
3412 
3413     conclusion: IndexedFaceSets in X3D files using the full or immersive
3414     profile may produce undefined results, while in the interchange
3415     profile it may not produce undefined results 8-(
3416 
3417        TODO: find out what is going on 8-(
3418     */
3419     MFInt32* coords = coordIndex();
3420     if (coords)
3421         if (coords->getSize() > 0) {
3422             if (coords->getValue(coords->getSize() - 1) != -1)
3423                 return PROFILE_IMMERSIVE;
3424             int vertexCounter = 0;
3425             for (int i = 0; i < coords->getSize(); i++)
3426                 if (coords->getValue(i) == -1) {
3427                     if (vertexCounter < 3)
3428                         return PROFILE_IMMERSIVE;
3429                     else
3430                         vertexCounter = 0;
3431                     vertexCounter++;
3432                 }
3433         }
3434     if (m_mesh != NULL)
3435         if (!(m_mesh->onlyPlanarFaces()))
3436             return PROFILE_IMMERSIVE;
3437     if (hasInput("set_colorIndex"))
3438         return PROFILE_IMMERSIVE;
3439     if (hasInput("set_normalIndex"))
3440         return PROFILE_IMMERSIVE;
3441     if (!isDefault(ccw_Field()))
3442         return PROFILE_IMMERSIVE;
3443     if (!isDefault(normal_Field()))
3444         return PROFILE_IMMERSIVE;
3445     if (!isDefault(convex_Field()))
3446         return PROFILE_IMMERSIVE;
3447     if (!isDefault(normalIndex_Field()))
3448         return PROFILE_IMMERSIVE;
3449     float fcreaseAngle = creaseAngle()->getFixedAngle(m_scene->getUnitAngle());
3450     if ((fcreaseAngle != 0) && (fcreaseAngle != M_PI))
3451         return PROFILE_IMMERSIVE;
3452     return PROFILE_INTERCHANGE;
3453 }
3454 
3455 
3456 #ifdef HAVE_LIBCGAL
3457 #undef max
3458 #include <CGAL/Simple_cartesian.h>
3459 typedef CGAL::Simple_cartesian<double> Kernel;
3460 #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
3461 #include <CGAL/Surface_mesh.h>
3462 #include <CGAL/Polygon_mesh_processing/corefinement.h>
3463 #include <CGAL/Polygon_mesh_processing/self_intersections.h>
3464 #include <CGAL/Polygon_mesh_processing/triangulate_faces.h>
3465 #include <CGAL/boost/graph/dijkstra_shortest_paths.h>
3466 #include <CGAL/exceptions.h>
3467 #include <CGAL/IO/Color.h>
3468 #include <boost/graph/prim_minimum_spanning_tree.hpp>
3469 #include <boost/foreach.hpp>
3470 typedef Kernel::Point_3 Point;
3471 typedef CGAL::Surface_mesh<Point> Surface;
3472 typedef CGAL::Surface_mesh<Point> SurfaceMesh;
3473 typedef CGAL::Color Color;
3474 typedef Surface::Vertex_index vertex_index;
3475 typedef boost::graph_traits<Surface>::vertex_descriptor vertex_descriptor;
3476 typedef boost::graph_traits<Surface>::face_descriptor face_descriptor;
3477 typedef boost::graph_traits<Surface>::halfedge_descriptor halfedge_descriptor;
3478 
3479 namespace params = CGAL::Polygon_mesh_processing::parameters;
3480 
3481 static void
build_mesh(Surface * meshOut,MyMesh * mesh,Matrix matrix)3482 build_mesh(Surface *meshOut, MyMesh *mesh, Matrix matrix)
3483 {
3484     MyArray<vertex_index> u;
3485     for (int i = 0; i < mesh->getVertices()->getSFSize(); i++) {
3486         Vec3f v = mesh->getVertices()->getVec(i);
3487         v = matrix * v;
3488         u.append(meshOut->add_vertex(Kernel::Point_3(v.x, v.y, v.z)));
3489     }
3490     MFInt32 *meshCoords = mesh->getCoordIndex();
3491     int vert = 0;
3492     vertex_index v1;
3493     vertex_index v2;
3494     vertex_index v3;
3495 
3496     for (int i = 0; i < meshCoords->getSFSize(); i++) {
3497          int face = meshCoords->getValue(i);
3498          if (face > -1) {
3499              switch (vert) {
3500                case 0:
3501                  v1 = u[face];
3502                  break;
3503                case 1:
3504                  v2 = u[face];
3505                  break;
3506                case 2:
3507                  v3 = u[face];
3508                  break;
3509              }
3510              if (vert++ == 2) {
3511                  vert = 0;
3512                  meshOut->add_face(v1, v2, v3);
3513              }
3514          }
3515     }
3516 };
3517 
3518 NodeIndexedFaceSet *
csg(NodeIndexedFaceSet * face,int operation,Matrix matrix1,Matrix matrix2)3519 NodeIndexedFaceSet::csg(NodeIndexedFaceSet *face, int operation,
3520                         Matrix matrix1, Matrix matrix2)
3521 {
3522     try {
3523         MyMesh *mesh = m_mesh;
3524         if (mesh->getVertices()->getSFSize() == 0)
3525             return NULL;
3526 
3527         Surface surface1;
3528         build_mesh(&surface1, mesh, matrix1);
3529         Surface surface2;
3530         build_mesh(&surface2, face->getMesh(), matrix2);
3531         Surface surfaceMesh;
3532 
3533         CGAL::Polygon_mesh_processing::triangulate_faces(surface1);
3534         CGAL::Polygon_mesh_processing::triangulate_faces(surface2);
3535 
3536         CGAL::Polygon_mesh_processing::parameters::all_default();
3537 
3538         switch (operation) {
3539           case UNION:
3540             if (!CGAL::Polygon_mesh_processing::corefine_and_compute_union(
3541                 surface1, surface2, surfaceMesh, params::all_default(),
3542                                                  params::all_default(),
3543                                                  params::all_default())
3544                ) return NULL;
3545             break;
3546           case INTERSECTION:
3547             if (!CGAL::Polygon_mesh_processing::corefine_and_compute_intersection(
3548                 surface1, surface2, surfaceMesh, params::all_default(),
3549                                                  params::all_default(),
3550                                                  params::all_default())
3551                ) return NULL;
3552             break;
3553           case SUBTRACT:
3554             if (!CGAL::Polygon_mesh_processing::corefine_and_compute_difference(
3555                 surface1, surface2, surfaceMesh, params::all_default(),
3556                                                  params::all_default(),
3557                                                  params::all_default())
3558                ) return NULL;
3559             break;
3560         }
3561         NodeCoordinate *ncoord = (NodeCoordinate *)
3562                                  m_scene->createNode("Coordinate");
3563         NodeIndexedFaceSet *faceSet = (NodeIndexedFaceSet *)
3564                                        m_scene->createNode("IndexedFaceSet");
3565         faceSet->coord(new SFNode(ncoord));
3566 
3567         MFVec3f *newVertices = new MFVec3f();
3568         MFInt32 *newCoordIndex = new MFInt32();
3569 
3570         BOOST_FOREACH(vertex_descriptor vd, vertices(surfaceMesh)){
3571             newVertices->appendSFValue(surfaceMesh.point(vd).x(),
3572                                        surfaceMesh.point(vd).y(),
3573                                        surfaceMesh.point(vd).z());
3574         }
3575         BOOST_FOREACH(face_descriptor fd, faces(surfaceMesh)) {
3576             Surface::Halfedge_index hf = surfaceMesh.halfedge(fd);
3577             BOOST_FOREACH(halfedge_descriptor hi,
3578                           halfedges_around_face(hf, surfaceMesh)) {
3579                 Surface::Vertex_index vi = target(hi, surfaceMesh);
3580                 newCoordIndex->appendSFValue((std::size_t)vi);
3581             }
3582             newCoordIndex->appendSFValue(-1);
3583         }
3584         ncoord->point(new MFVec3f(newVertices));
3585         faceSet->coordIndex(new MFInt32(newCoordIndex));
3586         return faceSet;
3587     } catch(CGAL::Assertion_exception e) {
3588         char str[256], title[256], message[256];
3589         swLoadString(IDS_DUNE, title, 255);
3590         swLoadString(IDS_CGAL_EXCEPTION, str, 255);
3591         mysnprintf(message, 255, str, e.expression().c_str());
3592         swMessageBox(TheApp->mainWnd(), message, title, SW_MB_OK,
3593                      SW_MB_ERROR);
3594     }
3595     return NULL;
3596 }
3597 #endif
3598 
3599 float
getOffFactor(int tabCount,MyArray<char * > strings,int beginData,int endData)3600 NodeIndexedFaceSet::getOffFactor(int tabCount, MyArray<char *> strings,
3601                                  int beginData, int endData)
3602 {
3603     // check if color data is integer or float, return factor 1.0/255.0 or 1.0
3604     for (int i = beginData; i < endData; i++) {
3605         MyArray<MyString> numbers;
3606         MyString splitString(strings[i]);
3607         splitString.split(&numbers, " ");
3608         for (int j = tabCount; j < numbers.size(); j++)
3609             if (!numbers[j].isInt())
3610                 return 1.0f;
3611     }
3612     return 1.0f/255.0f;
3613 }
3614 
3615 
3616 NodeIndexedFaceSet *
readOff(const char * filename)3617 NodeIndexedFaceSet::readOff(const char *filename)
3618 {
3619     int f = open(filename, O_RDONLY);
3620     if (f == -1)
3621         return NULL;
3622 
3623     NodeCoordinate *ncoord = (NodeCoordinate *)
3624                              m_scene->createNode("Coordinate");
3625     NodeIndexedFaceSet *faceSet = (NodeIndexedFaceSet *)
3626                                    m_scene->createNode("IndexedFaceSet");
3627     faceSet->coord(new SFNode(ncoord));
3628 
3629     MFVec3f *newVertices = new MFVec3f();
3630     MFInt32 *newCoordIndex = new MFInt32();
3631 
3632     bool isColor = false;
3633     bool isColorRGBA = false;
3634     MFColor *newColor = new MFColor();
3635     MFColorRGBA *newColorRGBA = new MFColorRGBA();
3636 
3637     int fileLen = lseek(f, SEEK_SET, SEEK_END);
3638     lseek(f, SEEK_SET, 0);
3639 
3640     char *fileData = new char[fileLen + 2];
3641     if (read(f, fileData, fileLen) == -1) {
3642         swDebugf("%s", strerror(errno));
3643         return NULL;
3644     }
3645     fileData[fileLen] = 0;
3646     fileData[fileLen + 1] = 0;
3647 
3648     MyArray<char *> lines;
3649     char *newLine = strchr(fileData, '\n');
3650     if (newLine != NULL) {
3651         if (*(newLine - 1) == '\r')
3652             *(newLine - 1) = 0;
3653         newLine[0] = 0;
3654         newLine++;
3655         if (fileData[0] != '#')
3656             lines.append(fileData);
3657     }
3658 
3659     while (newLine != NULL) {
3660         char *oldLine = newLine;
3661         newLine = strchr(newLine, '\n');
3662         if (newLine != NULL) {
3663             if (*(newLine - 1) == '\r')
3664                 *(newLine - 1) = 0;
3665             newLine[0] = 0;
3666             newLine++;
3667             if (oldLine[0] != '#')
3668                 lines.append(oldLine);
3669         }
3670     }
3671 
3672     if (lines.size() < 2) {
3673         char message[256];
3674         swLoadString(IDS_NOT_ENOUGH_LINES + swGetLang(), message, 255);
3675         swDebugf(message);
3676         return NULL;
3677     }
3678 
3679     MyString header = lines[0];
3680     if ((strcmp(header.getData(), "OFF") != 0) &&
3681         (strcmp(header.getData(), "COFF") != 0) &&
3682         (strcmp(header.getData(), "CNOFF") != 0)) {
3683         char message[256];
3684         swLoadString(IDS_WRONG_OFF_HEADER + swGetLang(), message, 255);
3685         swDebugf(message);
3686     }
3687 
3688     MyString headerData = lines[1];
3689     MyArray<MyString> intStrings;
3690     headerData.split(&intStrings, " ");
3691     if (intStrings.size() != 3) {
3692         char message[256];
3693         swLoadString(IDS_WRONG_OFF_HEADER + swGetLang(), message, 255);
3694         swDebugf(message);
3695         return NULL;
3696     }
3697 
3698     int numVertices        = atoi(intStrings[0]);
3699     int numFaces           = atoi(intStrings[1]);
3700     int numVerticesPerFace = atoi(intStrings[2]);
3701 
3702     float verticesFactor = getOffFactor(3, lines, 2, numVertices + 2);
3703 
3704     for (int i = 0; i < numVertices; i++) {
3705         MyString dataString = lines[i + 2];
3706         MyArray<MyString> floatStrings;
3707         dataString.split(&floatStrings, " ");
3708         if (floatStrings.size() < 3) {
3709             char message[256];
3710             swLoadString(IDS_WRONG_OFF_DATA + swGetLang(), message, 255);
3711             swDebugf(message);
3712             return NULL;
3713         }
3714         newVertices->appendSFValue(atof((const char *)floatStrings[0]),
3715                                    atof((const char *)floatStrings[1]),
3716                                    atof((const char *)floatStrings[2]));
3717         int numCi = 3;
3718         if ((floatStrings.size() < 3) ||
3719             ((floatStrings.size() != numCi) &&
3720             (floatStrings.size() != numCi + 3) &&  // 3 color values
3721             (floatStrings.size() != numCi + 4)) || // 4 color values
3722             (isColor && (floatStrings.size() == numCi + 4)) ||
3723             (isColorRGBA && (floatStrings.size() == numCi + 3))) {
3724             char message[256];
3725             swLoadString(IDS_WRONG_OFF_DATA + swGetLang(), message, 255);
3726             swDebugf(message);
3727             return NULL;
3728         }
3729         if (floatStrings.size() == numCi + 3) {
3730             float c[3];
3731             for (int j = numCi; j < floatStrings.size(); j++) {
3732                 c[j - (numCi)] = atof(floatStrings[j].getData()) *
3733                                       verticesFactor;
3734             }
3735             newColor->appendSFValue(c[0], c[1], c[2]);
3736             faceSet->colorPerVertex(new SFBool(true));
3737             isColor = true;
3738         } else if (floatStrings.size() == numCi + 4) {
3739             float c[4];
3740             for (int j = numCi; j < floatStrings.size(); j++) {
3741                 c[j - (numCi)] = atof(floatStrings[j].getData()) *
3742                                       verticesFactor;
3743             }
3744             isColorRGBA = true;
3745             faceSet->colorPerVertex(new SFBool(true));
3746             newColorRGBA->appendSFValue(c[0], c[1], c[2], c[3]);
3747         }
3748     }
3749 
3750     float facesFactor = getOffFactor(3, lines, numVertices + 2,
3751                                                numVertices + numFaces + 2);
3752 
3753     for (int i = numVertices; i < numVertices + numFaces; i++) {
3754         MyString dataString = lines[i + 2];
3755         MyArray<MyString> floatStrings;
3756         dataString.split(&floatStrings, " ");
3757         int numCi = atoi((const char *)floatStrings[0]);
3758         if ((floatStrings.size() < 3) ||
3759              ((floatStrings.size() != numCi + 1) &&
3760               (floatStrings.size() != numCi + 1 + 3) &&  // 3 color values
3761               (floatStrings.size() != numCi + 1 + 4)) || // 4 color values
3762              (isColor && (floatStrings.size() == numCi + 1 + 4)) ||
3763              (isColorRGBA && (floatStrings.size() == numCi + 1 + 3))) {
3764             char message[256];
3765             swLoadString(IDS_WRONG_OFF_DATA + swGetLang(), message, 255);
3766             swDebugf(message);
3767             return NULL;
3768         }
3769         for (int j = 1; j < numCi + 1; j++)
3770             newCoordIndex->appendSFValue(atoi(floatStrings[j]));
3771         newCoordIndex->appendSFValue(-1);
3772         if (floatStrings.size() == numCi + 1 + 3) {
3773             float c[3];
3774             for (int j = numCi + 1; j < floatStrings.size(); j++) {
3775                 c[j - (numCi + 1)] = atof(floatStrings[j].getData()) *
3776                                           facesFactor;
3777             }
3778             newColor->appendSFValue(c[0], c[1], c[2]);
3779             faceSet->colorPerVertex(new SFBool(false));
3780             isColor = true;
3781         } else if (floatStrings.size() == numCi + 1 + 4) {
3782             float c[4];
3783             for (int j = numCi + 1; j < floatStrings.size(); j++) {
3784                 c[j - (numCi + 1)] = atof(floatStrings[j].getData()) *
3785                                           facesFactor;
3786             }
3787             isColorRGBA = true;
3788             faceSet->colorPerVertex(new SFBool(false));
3789             newColorRGBA->appendSFValue(c[0], c[1], c[2], c[3]);
3790         }
3791     }
3792 
3793     delete [] fileData;
3794 
3795     ncoord->point(new MFVec3f(newVertices));
3796     faceSet->coordIndex(new MFInt32(newCoordIndex));
3797     if (isColor) {
3798         NodeColor *ncolor = (NodeColor *)m_scene->createNode("Color");
3799         faceSet->color(new SFNode(ncolor));
3800         ((NodeColor *)faceSet->color()->getValue())->color(
3801             new MFColor(newColor));
3802     } else
3803         delete newColor;
3804     if (isColorRGBA) {
3805         NodeColorRGBA *ncolor = (NodeColorRGBA *)
3806                                 m_scene->createNode("ColorRGBA");
3807         faceSet->color(new SFNode(ncolor));
3808         ((NodeColorRGBA *)faceSet->color()->getValue())->color(
3809             new MFColorRGBA(newColorRGBA));
3810     } else
3811         delete newColorRGBA;
3812     return faceSet;
3813 }
3814 
3815 void
accountOffData(int f)3816 NodeIndexedFaceSet::accountOffData(int f)
3817 {
3818     MFVec3f *vertices = getCoordinates();
3819     if (vertices)
3820         m_sumVertices += vertices->getSFSize();
3821     m_sumVerticesPerFaces += getMesh()->getNumFaces();
3822 }
3823 
3824 void
writeOffVerticesAndColors(int f,Node * node)3825 NodeIndexedFaceSet::writeOffVerticesAndColors(int f, Node *node)
3826 {
3827     if (node == NULL)
3828         return;
3829     static Matrix transformMatrix = Matrix::identity();
3830     Path *trans = node->getScene()->searchTransform(node->getPath());
3831     Node *transform = NULL;
3832     if (trans)
3833         transform = trans->getNode();
3834     if (transform) {
3835         transform->update();
3836         transform->transform();
3837         transform->getMatrix(transformMatrix);
3838     }
3839 
3840     MFVec3f *vertices = getCoordinates();
3841     if (vertices)
3842         for (int i = 0; i < vertices->getSFSize(); i++) {
3843             Vec3f vec = vertices->getVec(i);
3844             vec = transformMatrix * vec;
3845             mywritef(f, "  %f %f %f", vec.x, vec.y, vec.z);
3846             if (colorPerVertex()->getValue() &&
3847                 (NodeColorRGBA *)color()->getValue() &&
3848                 ((MeshBasedNode *)this)->hasColorRGBA()) {
3849                 NodeColorRGBA *colorRGBANode = (NodeColorRGBA *)
3850                                                color()->getValue();
3851                 if (color() && colorRGBANode->color()) {
3852                     const float *c =
3853                          ((NodeColorRGBA *)color()->getValue())->color()->
3854                          getValues() + i * 4;
3855                      mywritef(f, " %f %f %f %f", c[0], c[1], c[2], c[3]);
3856                 }
3857             } else if (color() && colorPerVertex()->getValue() &&
3858                        ((NodeColor *)color()->getValue()) &&
3859                        ((NodeColor *)color()->getValue())->color()) {
3860                 NodeColor *colorNode = (NodeColor *)color()->getValue();
3861                 const float *c = ((NodeColorRGBA *)
3862                                  color()->getValue())->color()->
3863                     getValues() + i * 3;
3864                  mywritef(f, " %f %f %f", c[0], c[1], c[2]);
3865             }
3866             mywritestr(f, "\n");
3867         }
3868 }
3869 
3870 void
writeOffIndicesAndColors(int f,int startIndex,Node * node)3871 NodeIndexedFaceSet::writeOffIndicesAndColors(int f, int startIndex, Node *node)
3872 {
3873     if (node == NULL)
3874         return;
3875     MFVec3f *vertices = getCoordinates();
3876     if (vertices == NULL)
3877         return;
3878     for (int i = 0; i < getMesh()->getNumFaces(); i++) {
3879         FaceData *face = getMesh()->getFace(i);
3880         int offset = face->getOffset();
3881         int numVertices = face->getNumVertices();
3882 
3883         mywritef(f, "  %d ", numVertices);
3884         for (int j = 0; j < numVertices; j++) {
3885             int ci = coordIndex()->getValue(offset + j);
3886             mywritef(f, "%d ", ci + startIndex);
3887         }
3888         if ((!colorPerVertex()->getValue()) &&
3889             (NodeColorRGBA *)color()->getValue() &&
3890             getMesh()->hasColorRGBA()) {
3891             NodeColorRGBA *colorRGBANode = (NodeColorRGBA *)
3892                 color()->getValue();
3893             if (color() && colorRGBANode->color()) {
3894                 const float *c =
3895                     ((NodeColorRGBA *)color()->getValue())->color()->
3896                     getValues() + i * 4;
3897                 mywritef(f, " %f %f %f %f", c[0], c[1], c[2], c[3]);
3898             }
3899         } else if (color() && (!colorPerVertex()->getValue()) &&
3900             ((NodeColor *)color()->getValue()) &&
3901             ((NodeColor *)color()->getValue())->color()) {
3902             NodeColor *colorNode = (NodeColor *)color()->getValue();
3903             const float *c =
3904                 ((NodeColorRGBA *)color()->getValue())->color()->
3905                 getValues() + i * 3;
3906                 mywritef(f, " %f %f %f", c[0], c[1], c[2]);
3907         }
3908         mywritestr(f, "\n");
3909     }
3910 }
3911 
3912 void
writeOffNormals(int f,Node * node)3913 NodeIndexedFaceSet::writeOffNormals(int f, Node *node)
3914 {
3915     if (node == NULL)
3916         return;
3917     if (normal() == NULL)
3918         return;
3919 
3920     MFVec3f *vertices = getVertices();
3921     if (vertices == NULL)
3922         return;
3923     MFVec3f *normals = NULL;
3924     if (normal()->getValue() == NULL) {
3925         if (getMesh())
3926             normals = getMesh()->getNormals();
3927         else
3928             return;
3929     } else
3930         normals = ((NodeNormal *)normal()->getValue())->vector();
3931     for (int i = 0; i < vertices->getSFSize(); i++) {
3932         Vec3f vec = normals->getVec(i);
3933         mywritef(f, "  N %f %f %f\n", vec.x, vec.y, vec.z);
3934     }
3935 }
3936 
3937 #ifdef HAVE_LIBVCG
3938 #undef max
3939 #undef min
3940 // stuff to define the mesh
3941 #include <vcg/complex/complex.h>
3942 #include <vcg/complex/algorithms/edge_collapse.h>
3943 
3944 using namespace vcg;
3945 using namespace tri;
3946 
3947 // local optimization
3948 #include "quadric_simp.h"
3949 
3950 typedef typename CMeshO::VertexPointer VertexPointer;
3951 typedef typename CMeshO::VertexIterator VertexIterator;
3952 typedef typename CMeshO::FaceIterator FaceIterator;
3953 typedef typename CMeshO::CoordType CoordType;
3954 
QCallBack(const int pos,const char * str)3955 static bool QCallBack(const int pos, const char * str)
3956 {
3957     return true;
3958 }
3959 
3960 NodeIndexedFaceSet *
meshReduce(float percent)3961 NodeIndexedFaceSet::meshReduce(float percent)
3962 {
3963     CMeshO m;
3964     MyMesh *trimesh = triangulateMesh();
3965     NodeIndexedFaceSet *indexedFaceSet = (NodeIndexedFaceSet *)
3966                                          m_scene->createNode("IndexedFaceSet");
3967     NodeCoordinate *ncoordinate = (NodeCoordinate *)
3968                                   m_scene->createNode("Coordinate");
3969     indexedFaceSet->coord(new SFNode(ncoordinate));
3970     ncoordinate->point(trimesh->getVertices());
3971     indexedFaceSet->coordIndex(trimesh->getCoordIndex());
3972     indexedFaceSet->optimize();
3973     MyMesh *mesh = indexedFaceSet->getMesh();
3974 
3975     if (mesh->getVertices()->getSFSize() == 0)
3976         return NULL;
3977 
3978     Allocator<CMeshO>::AddVertices(m, mesh->getVertices()->getSFSize());
3979     VertexPointer *ivp = new VertexPointer[mesh->getVertices()->getSFSize()];
3980 
3981     VertexIterator vi=m.vert.begin();
3982     for (int i = 0; i < mesh->getVertices()->getSFSize(); i++) {
3983         const float *v = mesh->getVertices()->getValue(i);
3984         ivp[i]=&*vi;
3985         (*vi).P()=CoordType(v[0], v[1], v[2]);
3986         vi++;
3987     }
3988 
3989     MFInt32 *meshCoords = mesh->getCoordIndex();
3990     for (int i = 0; i < meshCoords->getSFSize(); i += 4) {
3991          int f1 = meshCoords->getValue(i);
3992          int f2 = meshCoords->getValue(i + 1);
3993          int f3 = meshCoords->getValue(i + 2);
3994          Allocator<CMeshO>::AddFace(m, ivp[f1], ivp[f2], ivp[f3]);
3995     }
3996 
3997     delete [] ivp;
3998 
3999     int finalSize = percent * 0.01f * m.fn ;
4000 
4001     TriEdgeCollapseQuadricParameter qparams;
4002     qparams.QualityThr = 0.3;
4003     bool cleaningFlag = true;
4004     qparams.QualityCheck = true;
4005     qparams.NormalCheck = true;
4006     qparams.OptimalPlacement = true;
4007     qparams.ScaleIndependent = true;
4008     qparams.PreserveBoundary = true;
4009     qparams.PreserveTopology = true;
4010     qparams.QualityQuadric = true;
4011     qparams.QualityWeight = false;
4012 
4013     if (cleaningFlag) {
4014         tri::Clean<CMeshO>::RemoveDuplicateVertex(m);
4015         tri::Clean<CMeshO>::RemoveUnreferencedVertex(m);
4016     }
4017 
4018     vcg::tri::UpdateBounding<CMeshO>::Box(m);
4019 
4020 //    m.updateDataMask( MeshModel::MM_VERTFACETOPO | MeshModel::MM_VERTMARK);
4021 //    tri::UpdateFlags<CMeshO>::FaceBorderFromVF(m);
4022 
4023     QuadricSimplification(m, finalSize, false, qparams, QCallBack);
4024 
4025     Allocator<CMeshO>::CompactEveryVector(m);
4026 
4027     NodeCoordinate *ncoord = (NodeCoordinate *)
4028                              m_scene->createNode("Coordinate");
4029     NodeIndexedFaceSet *faceSet = (NodeIndexedFaceSet *)
4030                                    m_scene->createNode("IndexedFaceSet");
4031     faceSet->coord(new SFNode(ncoord));
4032 
4033     MFVec3f *newVertices = new MFVec3f();
4034     MFInt32 *newCoordIndex = new MFInt32();
4035 
4036     vi = m.vert.begin();
4037     for (int vertex = 0; vertex < m.vn; vertex++) {
4038         newVertices->appendSFValue((*vi).P().V(0),
4039                                    (*vi).P().V(1),
4040                                    (*vi).P().V(2));
4041         vi++;
4042     }
4043 
4044     FaceIterator fi = m.face.begin();
4045     for (int face = 0; face < m.fn; face++) {
4046          int d0 = vcg::tri::Index(m, fi->cV(0));
4047          newCoordIndex->appendSFValue(d0);
4048          int d1 = vcg::tri::Index(m, fi->cV(1));
4049          newCoordIndex->appendSFValue(d1);
4050          int d2 = vcg::tri::Index(m, fi->cV(2));
4051          newCoordIndex->appendSFValue(d2);
4052          newCoordIndex->appendSFValue(-1);
4053          fi++;
4054     }
4055 
4056     ncoord->point(new MFVec3f(newVertices));
4057     faceSet->coordIndex(new MFInt32(newCoordIndex));
4058 
4059     return faceSet;
4060 
4061 }
4062 #endif
4063 
4064