1 /*
2  * NodeIndexedFaceSet.h
3  *
4  * Copyright (C) 1999 Stephen F. White
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 #pragma once
23 
24 #include "MeshBasedNode.h"
25 #include "ProtoMacros.h"
26 #include "Proto.h"
27 #include "DuneApp.h"
28 #include "Vec3f.h"
29 #include "NodeCoordinate.h"
30 #include "Colored.h"
31 #include "SFMFTypes.h"
32 #include "ComposedGeometryMacros.h"
33 
34 class Matrix;
35 
36 enum {
37     UNION,
38     INTERSECTION,
39     SUBTRACT
40 };
41 
42 class ProtoIndexedFaceSet : public GeometryProto {
43 public:
44                     ProtoIndexedFaceSet(Scene *scene);
45     virtual Node   *create(Scene *scene);
46 
getType()47     virtual int     getType() const { return VRML_INDEXED_FACE_SET; }
48 
isMesh(void)49     virtual bool    isMesh(void) { return true; }
isExportTargetMesh(void)50     virtual bool    isExportTargetMesh(void) { return true; }
51 
isDeclaredInRwd_h()52     virtual bool    isDeclaredInRwd_h() { return true; }
53 
54     FieldIndex color;
55     FieldIndex coord;
56     FieldIndex normal;
57     FieldIndex texCoord;
58     FieldIndex texCoord2;
59     FieldIndex texCoord3;
60     FieldIndex texCoord4;
61     FieldIndex ccw;
62     FieldIndex colorIndex;
63     FieldIndex colorPerVertex;
64     FieldIndex convex;
65     FieldIndex coordIndex;
66     FieldIndex creaseAngle;
67     FieldIndex normalIndex;
68     FieldIndex normalPerVertex;
69     FieldIndex solid;
70     FieldIndex texCoordIndex;
71     FieldIndex texCoordIndex2;
72     FieldIndex texCoordIndex3;
73     FieldIndex texCoordIndex4;
74     ComposedGeometryProtoMacro()
75     x3domGeometryCommonFieldIndex()
76     FieldIndex normalUpdateMode;
77 };
78 
79 class FacesetAndMatrix {
80 public:
81     NodeIndexedFaceSet *node;
82     NodeMaterial *material;
83     Matrix matrix;
84 };
85 
86 class NodeIndexedFaceSet : public MeshBasedNode, Colored {
87 public:
88                     NodeIndexedFaceSet(Scene *scene, Proto *proto);
89 
90 protected:
91     virtual        ~NodeIndexedFaceSet();
92 
93 public:
94     virtual int     getProfile(void) const;
getX3dVersion(void)95     virtual int     getX3dVersion(void) const { return 0; }
96     virtual void    setField(int index, FieldValue *value, int cf = -1);
copy()97     virtual Node   *copy() const { return new NodeIndexedFaceSet(*this); }
98 
99     virtual void    draw();
100 
shouldConvertToIndexedFaceSet(void)101     virtual bool    shouldConvertToIndexedFaceSet(void) { return false; }
102 
103     virtual void    addToConvertedNodes(int writeFlags);
104 
105     virtual void    flip(int index);
106     virtual void    swap(int fromTo);
107 
getNormalField()108     virtual int     getNormalField() { return normal_Field(); }
getTexCoordField()109     virtual int     getTexCoordField() { return texCoord_Field(); }
110 
111     virtual void    setNormalFromMesh(Node *nnormal);
112     virtual void    setTexCoordFromMesh(Node *ntexCoord);
113 
hasCoverFields(void)114     virtual bool    hasCoverFields(void) { return true; }
115 
hasTwoSides(void)116     virtual bool    hasTwoSides(void) { return true; }
isDoubleSided(void)117     virtual bool    isDoubleSided(void) { return !solid()->getValue(); }
toggleDoubleSided(void)118     virtual void    toggleDoubleSided(void)
119                        { solid(new SFBool(!solid()->getValue())); }
getConvexField()120     virtual int     getConvexField() { return convex_Field(); }
getSolidField()121     virtual int     getSolidField() { return solid_Field(); }
flipSide(void)122     virtual void    flipSide(void) { ccw(new SFBool(!ccw()->getValue())); }
123 
maySetDefault(void)124     virtual bool    maySetDefault(void) { return false; }
125 
getColorNode()126     virtual NodeColor *getColorNode()
127                     { return (NodeColor *)color()->getValue(); }
getColorRGBANode()128     virtual NodeColorRGBA *getColorRGBANode()
129                     { return (NodeColorRGBA *)color()->getValue(); }
getCoordinateNode(void)130     virtual NodeCoordinate *getCoordinateNode(void)
131                     { return (NodeCoordinate *)coord()->getValue(); }
getColored()132     virtual Colored *getColored() { return this; }
133 
colorPerVertexField()134     virtual int     colorPerVertexField() const
135                        { return colorPerVertex_Field(); }
colorIndexField()136     virtual int     colorIndexField() const
137                        { return colorIndex_Field(); }
138 
139     MFVec3f        *getCoordinates();
140     MFInt32        *getColorIndex();
141     MFInt32        *getCoordIndex();
142     MFInt32        *getNormalIndex();
143     MFVec2f        *getTextureCoordinates();
144     MFInt32        *getTexCoordIndex();
145 
146     Node           *toIndexedLineSet(void);
147 
showFields()148     virtual bool    showFields() { return true; }
149 
150     NodeIndexedFaceSet *splitSelectedFaces(void);
151     void            extrudeFaces(float dist);
152     void            insetFaces(float factor, int numX, int numY);
153     int             symetricPointIndex(int ci, int iface);
154     int             symetricFace(int iface);
155     bool            isSymetricFace(int iface);
156     bool            checkBorderMidPoint(int icoordIndex, MyArray<int> symFaces);
157     bool            checkBorderFace(MyArray<int> innerBorder,
158                                     MyArray<int> outerBorder,
159                                     MFInt32 *coordIndex,
160                                     int borderIndex1, int borderIndex2,
161                                     MyArray<int> symFaces, bool sym);
162     void            optimize(void);
163     void            optimizeCoordIndex(void);
164 
165     bool            buildQuad(void);
166     bool            canSplitFace(int face);
167     bool            canSplitFaces(void);
168 
169     static Node    *simpleJoin(MyArray<FacesetAndMatrix> data);
170 
171     bool            checkMidpoint(Vec3f midPoint, int jLoop, int nLoop,
172                                   int point1, int point2,
173                                   int uPieces, int vPieces);
174     int             getEgdeCoordIndex(int iface, Vec3f midPoint,
175                                       int jLoop, int nLoop,
176                                       int uPieces, int vPieces);
177     void            splitIntoPieces(int piecesU, int piecesV);
178 #ifdef HAVE_LIBCGAL
179     NodeIndexedFaceSet *csg(NodeIndexedFaceSet *face, int operation,
180                             Matrix matrix1, Matrix matrix2);
181 #endif
182     float               getOffFactor(int tabCount, MyArray<char *> strings,
183                                      int beginData, int endData);
184     NodeIndexedFaceSet *readOff(const char *filename);
185     void                accountOffData(int f);
writeOffInit(void)186     void                writeOffInit(void)
187                             {
188                             m_sumVertices = 0;
189                             m_sumVerticesPerFaces = 0;
190                             }
191     void                writeOffVerticesAndColors(int f, Node *node);
192     void                writeOffIndicesAndColors(int f, int startIndex,
193                                                  Node *node);
194     void                writeOffNormals(int f, Node *node);
getSumVertices(void)195     int                 getSumVertices(void)
196                             { return m_sumVertices; }
getSumVerticesPerFaces(void)197     int                 getSumVerticesPerFaces(void)
198                             { return m_sumVerticesPerFaces; }
199 
200 #ifdef HAVE_LIBVCG
201     NodeIndexedFaceSet *meshReduce(float percent);
202 #endif
203     float          *intersectVector0Plane(Vec3f endPoint, Vec3f startPoint,
204                                           int direction);
205     void            makeSymetric(int direction, bool plus);
206     void            deleteFaces(MFInt32 *coordIndex, MyArray<int> *faces);
207     void            snapTogether(void);
208 
209     void            changeToColorPerVertex(void);
210     void            changeToColorPerFace(void);
getColorPerVertex(void)211     bool            getColorPerVertex(void)
212                         { return colorPerVertex()->getValue(); }
213 
214     fieldMacros(SFNode,   color,            ProtoIndexedFaceSet)
215     fieldMacros(SFNode,   coord,            ProtoIndexedFaceSet)
216     fieldMacros(SFNode,   normal,           ProtoIndexedFaceSet)
217     fieldMacros(SFNode,   texCoord,         ProtoIndexedFaceSet)
218     fieldMacros(SFNode,   texCoord2,        ProtoIndexedFaceSet)
219     fieldMacros(SFNode,   texCoord3,        ProtoIndexedFaceSet)
220     fieldMacros(SFNode,   texCoord4,        ProtoIndexedFaceSet)
221     fieldMacros(SFBool,   ccw,              ProtoIndexedFaceSet)
222     fieldMacros(MFInt32,  colorIndex,       ProtoIndexedFaceSet)
223     fieldMacros(SFBool,   colorPerVertex,   ProtoIndexedFaceSet)
224     fieldMacros(SFBool,   convex,           ProtoIndexedFaceSet)
225     fieldMacros(MFInt32,  coordIndex,       ProtoIndexedFaceSet)
226     fieldMacros(SFFloat,  creaseAngle,      ProtoIndexedFaceSet)
227     fieldMacros(MFInt32,  normalIndex,      ProtoIndexedFaceSet)
228     fieldMacros(SFBool,   normalPerVertex,  ProtoIndexedFaceSet)
229     fieldMacros(SFBool,   solid,            ProtoIndexedFaceSet)
230     fieldMacros(MFInt32,  texCoordIndex,    ProtoIndexedFaceSet)
231     fieldMacros(MFInt32,  texCoordIndex2,   ProtoIndexedFaceSet)
232     fieldMacros(MFInt32,  texCoordIndex3,   ProtoIndexedFaceSet)
233     fieldMacros(MFInt32,  texCoordIndex4,   ProtoIndexedFaceSet)
234     ComposedGeometryFieldMacros(ProtoIndexedFaceSet)
235     x3domGeometryCommonFieldMacros(ProtoIndexedFaceSet)
236     fieldMacros(SFString, normalUpdateMode, ProtoIndexedFaceSet)
237 
238 protected:
239     void            createMesh(bool cleanDoubleVertices = true,
240                                bool triangulate = true);
241 
242 protected:
243     bool m_alreadyInChangeColorPerVertex;
244     int m_sumVertices;
245     int m_sumVerticesPerFaces ;
246 };
247 
248