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