Salome HOME
47f271fa1059261e0cb0a279ac694e7026c192cb
[modules/geom.git] / src / XAO / XAO_BrepGeometry.cxx
1 // Copyright (C) 2013-2023  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Frederic Pons (OpenCascade)
20
21 #include <cassert>
22
23 #include <Standard_TypeMismatch.hxx>
24
25 #include <BRepTools.hxx>
26 #include <BRep_Builder.hxx>
27 #include <TopAbs.hxx>
28 #include <TopTools_MapOfShape.hxx>
29 #include <TopTools_ListOfShape.hxx>
30 #include <TopTools_ListIteratorOfListOfShape.hxx>
31 #include <TopTools_IndexedMapOfShape.hxx>
32 #include <TopExp.hxx>
33 #include <TopExp_Explorer.hxx>
34 #include <GProp_GProps.hxx>
35 #include <BRepGProp.hxx>
36 #include <TopoDS.hxx>
37 #include <TopoDS_Vertex.hxx>
38
39 #include "XAO_BrepGeometry.hxx"
40 #include "XAO_XaoUtils.hxx"
41
42 using namespace XAO;
43
44 BrepGeometry::BrepGeometry() : Geometry("")
45 {
46 }
47
48 BrepGeometry::BrepGeometry(const std::string& name) : Geometry(name)
49 {
50 }
51
52 const std::string BrepGeometry::getShapeString()
53 {
54     std::ostringstream streamShape;
55     BRepTools::Write(m_shape, streamShape);
56     return streamShape.str();
57 }
58
59 void BrepGeometry::setShapeString(const std::string& shape)
60 {
61     std::istringstream streamBrep(shape.c_str());
62     BRep_Builder builder;
63     BRepTools::Read(m_shape, streamBrep, builder);
64
65     initIds();
66 }
67
68 void BrepGeometry::writeShapeFile(const std::string& fileName)
69 {
70     bool res = BRepTools::Write(m_shape, fileName.c_str());
71     if (!res)
72         throw XAO_Exception(MsgBuilder() << "Cannot write BRep file: " << fileName);
73 }
74
75 void BrepGeometry::readShapeFile(const std::string& fileName)
76  {
77     BRep_Builder builder;
78     bool res = BRepTools::Read(m_shape, fileName.c_str(), builder);
79     if (!res)
80         throw XAO_Exception(MsgBuilder() << "Cannot read BRep file: " << fileName);
81
82     initIds();
83 }
84
85 TopoDS_Shape BrepGeometry::getTopoDS_Shape()
86 {
87     return m_shape;
88 }
89
90 void BrepGeometry::setTopoDS_Shape(const TopoDS_Shape& shape)
91 {
92     m_shape = shape;
93     initIds();
94 }
95
96 void BrepGeometry::initIds()
97 {
98     // initialization of Ids
99     initListIds(TopAbs_VERTEX, m_vertices);
100     initListIds(TopAbs_EDGE, m_edges);
101     initListIds(TopAbs_FACE, m_faces);
102     initListIds(TopAbs_SOLID, m_solids);
103 }
104
105 void BrepGeometry::initListIds(const TopAbs_ShapeEnum& shapeType, GeometricElementList& eltList)
106 {
107     TopTools_MapOfShape mapShape;
108     TopTools_ListOfShape listShape;
109
110     int nbElt = 0;
111     TopExp_Explorer exp(m_shape, shapeType);
112     for (; exp.More(); exp.Next())
113     {
114         if (mapShape.Add(exp.Current()))
115         {
116             listShape.Append(exp.Current());
117             nbElt++;
118         }
119     }
120
121     if (listShape.IsEmpty())
122         return;
123
124     TopTools_IndexedMapOfShape indices;
125     TopExp::MapShapes(m_shape, indices);
126
127     eltList.setSize(nbElt);
128     TopTools_ListIteratorOfListOfShape itSub(listShape);
129     for (int index = 0; itSub.More(); itSub.Next(), ++index)
130     {
131         TopoDS_Shape value = itSub.Value();
132         int ref = indices.FindIndex(value);
133         eltList.setReference(index, XaoUtils::intToString(ref));
134     }
135 }
136
137 TopoDS_Shape BrepGeometry::getSubShape(const TopoDS_Shape& mainShape, const TopAbs_ShapeEnum& shapeType, int shapeIndex)
138 {
139     TopTools_MapOfShape mapShape;
140     TopTools_ListOfShape listShape;
141
142     TopExp_Explorer exp(mainShape, shapeType);
143     for (; exp.More(); exp.Next())
144     {
145         if (mapShape.Add(exp.Current()))
146             listShape.Append(exp.Current());
147     }
148
149     if (!listShape.IsEmpty())
150     {
151         TopTools_ListIteratorOfListOfShape itSub(listShape);
152         for (int index = 0; itSub.More(); itSub.Next(), ++index)
153         {
154             if (shapeIndex == index)
155             {
156                 TopoDS_Shape value = itSub.Value();
157                 return value;
158             }
159         }
160     }
161
162     throw XAO_Exception(MsgBuilder() << "Shape with reference [" << shapeIndex << "]  not found.");
163 }
164
165 // -----------------------------
166 int BrepGeometry::countGeometricalElements(const TopoDS_Shape& shape, const TopAbs_ShapeEnum& shapeType)
167 {
168     int res = 0;
169     TopExp_Explorer exp(shape, shapeType);
170     for (; exp.More(); exp.Next())
171         res++;
172
173     return res;
174 }
175
176 std::vector<int> BrepGeometry::getGeometricalElements(const TopoDS_Shape& shape, const TopAbs_ShapeEnum& shapeType, XAO::Dimension dim)
177 {
178     std::vector<int> indexList;
179
180     TopTools_MapOfShape mapShape;
181     TopTools_ListOfShape listShape;
182
183     TopExp_Explorer exp(shape, shapeType);
184     for (; exp.More(); exp.Next())
185     {
186         if (mapShape.Add(exp.Current()))
187             listShape.Append(exp.Current());
188     }
189
190     if (!listShape.IsEmpty())
191     {
192         // use the shape of the geometry for the indices
193         TopTools_IndexedMapOfShape indices;
194         TopExp::MapShapes(m_shape, indices);
195
196         TopTools_ListIteratorOfListOfShape itSub(listShape);
197         for (int index = 0; itSub.More(); itSub.Next(), ++index)
198         {
199             TopoDS_Shape value = itSub.Value();
200             int id = indices.FindIndex(value);
201             indexList.push_back(findElement(dim, id));
202         }
203     }
204
205     return indexList;
206 }
207
208 void BrepGeometry::getEdgeVertices(int edgeIndex, int& vertexA, int& vertexB)
209 {
210     TopoDS_Shape edge = getSubShape(m_shape, TopAbs_EDGE, edgeIndex);
211     std::vector<int> vertices = getGeometricalElements(edge, TopAbs_VERTEX, XAO::VERTEX);
212     assert(vertices.size() == 2);
213
214     vertexA = vertices[0];
215     vertexB = vertices[1];
216 }
217
218 int BrepGeometry::countFaceWires(int faceIndex)
219 {
220     TopoDS_Shape face = getSubShape(m_shape, TopAbs_FACE, faceIndex);
221     return countGeometricalElements(face, TopAbs_WIRE);
222 }
223
224 std::vector<int> BrepGeometry::getFaceEdges(int faceIndex, int wireIndex)
225 {
226     // get the face
227     TopoDS_Shape face = getSubShape(m_shape, TopAbs_FACE, faceIndex);
228     // get the wire
229     TopoDS_Shape wire = getSubShape(face, TopAbs_WIRE, wireIndex);
230     return getGeometricalElements(wire, TopAbs_EDGE, XAO::EDGE);
231 }
232
233 int BrepGeometry::countSolidShells(int solidIndex)
234 {
235     TopoDS_Shape solid = getSubShape(m_shape, TopAbs_SOLID, solidIndex);
236     return countGeometricalElements(solid, TopAbs_SHELL);
237 }
238
239 std::vector<int> BrepGeometry::getSolidFaces(int solidIndex, int shellIndex)
240 {
241     TopoDS_Shape solid = getSubShape(m_shape, TopAbs_SOLID, solidIndex);
242     TopoDS_Shape shell = getSubShape(solid, TopAbs_SHELL, shellIndex);
243     return getGeometricalElements(shell, TopAbs_FACE, XAO::FACE);
244 }
245
246 void BrepGeometry::getVertexXYZ(int vertexIndex, double& xCoord, double& yCoord, double& zCoord)
247 {
248     xCoord = 0.;
249     yCoord = 0.;
250     zCoord = 0.;
251
252     TopoDS_Shape vertex = getSubShape(m_shape, TopAbs_VERTEX, vertexIndex);
253     if (vertex.ShapeType() != TopAbs_VERTEX)
254         throw XAO_Exception(MsgBuilder() << "Shape " << vertexIndex<< " is not a point.");
255
256     TopoDS_Vertex point = TopoDS::Vertex(vertex);
257     if (!point.IsNull())
258     {
259         gp_Pnt aPnt = BRep_Tool::Pnt(point);
260         xCoord = aPnt.X();
261         yCoord = aPnt.Y();
262         zCoord = aPnt.Z();
263     }
264 }
265
266 // -----------------------------
267 double BrepGeometry::getEdgeLength(int edgeIndex)
268 {
269     TopoDS_Shape edge = getSubShape(m_shape, TopAbs_EDGE, edgeIndex);
270     GProp_GProps system;
271     BRepGProp::LinearProperties(edge, system);
272     return system.Mass();
273 }
274
275 double BrepGeometry::getFaceArea(int faceIndex)
276 {
277     TopoDS_Shape face = getSubShape(m_shape, TopAbs_FACE, faceIndex);
278     GProp_GProps system;
279     BRepGProp::SurfaceProperties(face, system);
280     return system.Mass();
281 }
282
283 double BrepGeometry::getSolidVolume(int solidIndex)
284 {
285     TopoDS_Shape solid = getSubShape(m_shape, TopAbs_SOLID, solidIndex);
286     GProp_GProps system;
287     BRepGProp::VolumeProperties(solid, system);
288     return system.Mass();
289 }
290
291 // -----------------------------
292 int BrepGeometry::getVertexID(int index)
293 {
294     return XaoUtils::stringToInt(getVertexReference(index));
295 }
296
297 int BrepGeometry::getEdgeID(int index)
298 {
299     return XaoUtils::stringToInt(getEdgeReference(index));
300 }
301
302 int BrepGeometry::getFaceID(int index)
303 {
304     return XaoUtils::stringToInt(getFaceReference(index));
305 }
306
307 int BrepGeometry::getSolidID(int index)
308 {
309     return XaoUtils::stringToInt(getSolidReference(index));
310 }
311
312 // -----------------------------
313 void BrepGeometry::setVertexID(int index, int id)
314 {
315     setVertexReference(index, XaoUtils::intToString(id));
316 }
317
318 void BrepGeometry::setEdgeID(int index, int id)
319 {
320     setEdgeReference(index, XaoUtils::intToString(id));
321 }
322
323 void BrepGeometry::setFaceID(int index, int id)
324 {
325     setEdgeReference(index, XaoUtils::intToString(id));
326 }
327
328 void BrepGeometry::setSolidID(int index, int id)
329 {
330     setEdgeReference(index, XaoUtils::intToString(id));
331 }
332
333 // -----------------------------
334 int BrepGeometry::findElement(XAO::Dimension dim, int id)
335 {
336     if (dim == XAO::VERTEX)
337         return findVertex(id);
338     if (dim == XAO::EDGE)
339         return findEdge(id);
340     if (dim == XAO::FACE)
341         return findFace(id);
342     if (dim == XAO::SOLID)
343         return findSolid(id);
344
345     throw XAO_Exception(MsgBuilder() << "Unknown Dimension: " << dim);
346 }
347
348 int BrepGeometry::findVertex(int id)
349 {
350     return getVertexIndexByReference(XaoUtils::intToString(id));
351 }
352
353 int BrepGeometry::findEdge(int id)
354 {
355     return getEdgeIndexByReference(XaoUtils::intToString(id));
356 }
357
358 int BrepGeometry::findFace(int id)
359 {
360     return getFaceIndexByReference(XaoUtils::intToString(id));
361 }
362
363 int BrepGeometry::findSolid(int id)
364 {
365     return getSolidIndexByReference(XaoUtils::intToString(id));
366 }
367
368 // -----------------------------
369 const std::string BrepGeometry::findVertexName(int id)
370 {
371     return getVertexName(findVertex(id));
372 }
373
374 const std::string BrepGeometry::findEdgeName(int id)
375 {
376     return getEdgeName(findEdge(id));
377 }
378
379 const std::string BrepGeometry::findFaceName(int id)
380 {
381     return getFaceName(findFace(id));
382 }
383
384 const std::string BrepGeometry::findSolidName(int id)
385 {
386     return getSolidName(findSolid(id));
387 }
388
389 // -----------------------------
390 void BrepGeometry::changeVertexName(int id, const std::string& name)
391 {
392     setVertexName(findVertex(id), name);
393 }
394
395 void BrepGeometry::changeEdgeName(int id, const std::string& name)
396 {
397     setEdgeName(findEdge(id), name);
398 }
399
400 void BrepGeometry::changeFaceName(int id, const std::string& name)
401 {
402     setFaceName(findFace(id), name);
403 }
404
405 void BrepGeometry::changeSolidName(int id, const std::string& name)
406 {
407     setSolidName(findSolid(id), name);
408 }