Salome HOME
Clean-up deprecated OCCT-related code
[modules/hexablock.git] / src / HEXABLOCKGUI / HEXABLOCKGUI_SalomeTools.cxx
1 // Copyright (C) 2009-2016  CEA/DEN, EDF R&D
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
20 #include <set>
21
22
23 #include <BRepTools.hxx>
24
25
26 // VTK includes
27 #include <vtkRenderer.h>
28 #include <vtkActorCollection.h>
29 #include <vtkUnstructuredGrid.h>
30
31 #include <SUIT_Session.h>
32
33 #include <SalomeApp_Study.h>
34 #include <SalomeApp_Application.h>
35
36 #include <OCCViewer_ViewWindow.h>
37
38 #include <SVTK_ViewManager.h>
39 #include <SVTK_ViewModel.h>
40 #include <SVTK_ViewWindow.h>
41 #include <SVTK_Prs.h>
42 #include <SALOME_Actor.h>
43 #include <VTKViewer_Algorithm.h>
44
45 #include <SelectMgr_Selection.hxx>
46 #include <TColStd_ListIteratorOfListOfInteger.hxx>
47 #include <SelectBasics_SensitiveEntity.hxx>
48 #include <TColStd_IndexedMapOfInteger.hxx>
49 #include <TopTools_IndexedMapOfShape.hxx>
50 #include <TopExp.hxx>
51 #include <StdSelect_BRepOwner.hxx>
52
53 #include <TopoDS.hxx>
54 #include <TopoDS_Face.hxx>
55 #include <BRepBuilderAPI_MakeVertex.hxx>
56 #include <Geom_Surface.hxx>
57 #include <ShapeAnalysis.hxx>
58 #include <BRep_Tool.hxx>
59 #include <BRep_Builder.hxx>
60 #include <Geom_Curve.hxx>
61 #include <BRepExtrema_DistShapeShape.hxx>
62 #include <BRepAdaptor_Curve.hxx>
63 #include <GCPnts_AbscissaPoint.hxx>
64 #include <TopoDS_Compound.hxx>
65
66 #include "HEXABLOCKGUI.hxx"
67 #include "HEXABLOCKGUI_SalomeTools.hxx"
68 #include "HEXABLOCKGUI_OccGraphicView.hxx"
69
70
71
72 //#define _DEVDEBUG_
73 using namespace std;
74
75 namespace HEXABLOCK
76 {
77 namespace GUI
78 {
79
80         SUIT_Study* GetActiveStudy()
81         {
82                 SUIT_Application* app = SUIT_Session::session()->activeApplication();
83                 if (app)
84                         return app->activeStudy();
85                 else
86                         return NULL;
87         }
88
89
90         _PTR(Study) GetActiveStudyDocument()
91         {
92                 SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(GetActiveStudy());
93                 if (aStudy)
94                         return aStudy->studyDS();
95                 else
96                         return _PTR(Study)();
97         }
98
99
100         SALOME_Actor* findActorByEntry( SVTK_ViewWindow *theVtkViewWindow, const char* theEntry)
101         {
102                 SALOME_Actor *foundActor = NULL;
103                 vtkActor     *aVTKActor  = NULL;
104                 Handle(SALOME_InteractiveObject) anIO;
105
106                 vtkRenderer *aRenderer = theVtkViewWindow->getRenderer();
107                 VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
108                 vtkActorCollection *aCollection = aCopy.GetActors();
109                 aCollection->InitTraversal();
110                 while( aVTKActor = aCollection->GetNextActor() ){
111                         foundActor = dynamic_cast<SALOME_Actor*>( aVTKActor );
112                         if ( foundActor && foundActor->hasIO() ){
113                                 anIO = foundActor->getIO();
114                                 if( anIO->hasEntry() && strcmp(anIO->getEntry(), theEntry) == 0 )
115                                         return foundActor;
116                         }
117                 }
118
119                 return NULL; // no actor found
120         }
121
122
123         int GetNameOfSelectedElements( SVTK_ViewWindow *theWindow,
124                         const Handle(SALOME_InteractiveObject)& theIO,
125                         QString& theName )
126         {
127                 SVTK_Selector* theSelector = theWindow->GetSelector();
128
129                 theName = "";
130
131                 TColStd_IndexedMapOfInteger aMapIndex;
132                 theSelector->GetIndex(theIO,aMapIndex);
133
134                 typedef std::set<int> TIdContainer;
135
136                 std::set<int> anIdContainer;
137
138                 for( int i = 1; i <= aMapIndex.Extent(); i++)
139                         anIdContainer.insert(aMapIndex(i));
140
141                 std::set<int>::const_iterator anIter = anIdContainer.begin();
142
143                 for( ; anIter != anIdContainer.end(); anIter++)
144                         theName += QString(" %1").arg(*anIter);
145
146                 return aMapIndex.Extent();
147         }
148
149         string shape2string( const TopoDS_Shape& aShape )
150         {
151                 ostringstream streamShape;
152                 BRepTools::Write(aShape, streamShape);
153
154                 return streamShape.str();
155         }
156
157         void getEntityOwners( const Handle(AIS_InteractiveObject)& theObj,
158                         const Handle(AIS_InteractiveContext)& theIC,
159                         SelectMgr_IndexedMapOfOwner& theMap )
160         {
161                 if ( theObj.IsNull() || theIC.IsNull() )
162                         return;
163
164                 TColStd_ListOfInteger modes;
165                 theIC->ActivatedModes( theObj, modes );
166
167                 TColStd_ListIteratorOfListOfInteger itr( modes );
168                 for (; itr.More(); itr.Next() ) {
169                         int m = itr.Value();
170                         if ( !theObj->HasSelection( m ) )
171                                 continue;
172
173                         Handle(SelectMgr_Selection) sel = theObj->Selection( m );
174
175                         for ( sel->Init(); sel->More(); sel->Next() ) {
176                                 const Handle(SelectMgr_SensitiveEntity) aHSenEntity = sel->Sensitive();
177                                 if ( aHSenEntity.IsNull() )
178                                         continue;
179                                 Handle(SelectBasics_SensitiveEntity) entity = aHSenEntity->BaseSensitive();
180                                 if ( entity.IsNull() )
181                                         continue;
182
183                                 Handle(SelectMgr_EntityOwner) owner =
184                                                 Handle(SelectMgr_EntityOwner)::DownCast(entity->OwnerId());
185                                 if ( !owner.IsNull() )
186                                         theMap.Add( owner );
187                         }
188                 }
189         }
190
191         void indicesToOwners( const TColStd_IndexedMapOfInteger& aIndexMap,
192                         const TopoDS_Shape& aMainShape,
193                         const SelectMgr_IndexedMapOfOwner& anAllMap,
194                         SelectMgr_IndexedMapOfOwner& aToHiliteMap )
195         {
196                 TopTools_IndexedMapOfShape aMapOfShapes;
197                 TopExp::MapShapes(aMainShape, aMapOfShapes);
198
199                 for  ( Standard_Integer i = 1, n = anAllMap.Extent(); i <= n; i++ )
200                 {
201                         Handle(StdSelect_BRepOwner) anOwner = Handle(StdSelect_BRepOwner)::DownCast(anAllMap( i ));
202                         if ( anOwner.IsNull() || !anOwner->HasShape() )
203                                 continue;
204
205                         const TopoDS_Shape& aSubShape = anOwner->Shape();
206                         Standard_Integer aSubShapeId = aMapOfShapes.FindIndex( aSubShape );
207                         if ( !aSubShapeId || !aIndexMap.Contains( aSubShapeId ) )
208                                 continue;
209
210                         if ( !aToHiliteMap.Contains( anOwner ) )
211                                 aToHiliteMap.Add( anOwner );
212                 }
213         }
214
215         TopoDS_Shape getSubShape(const TopoDS_Shape& theShape, const int theIndex)
216         {
217                 TopoDS_Shape theSubShape;
218
219                 if (theShape.IsNull() || theIndex < 1)
220                         return theSubShape;
221
222                 TopTools_IndexedMapOfShape anIndices;
223                 TopExp::MapShapes(theShape, anIndices);
224                 if (theIndex > anIndices.Extent())
225                         return theSubShape;
226                 theSubShape = anIndices.FindKey(theIndex);
227
228                 return theSubShape;
229         }
230
231         int getSubId(const TopoDS_Shape& theShape, const TopoDS_Shape& theSubShape)
232         {
233             if (theShape.IsNull() || theSubShape.IsNull())
234                 return -1;
235
236             TopTools_IndexedMapOfShape anIndices;
237             TopExp::MapShapes(theShape, anIndices);
238
239             return anIndices.FindIndex(theSubShape);
240         }
241
242         Standard_Boolean getExtremaSolution(const gp_Pnt&       theInitPnt,
243                                                                                 const TopoDS_Shape& theRefShape,
244                                                                                 gp_Pnt& thePnt)
245         {
246           BRepBuilderAPI_MakeVertex mkVertex (theInitPnt);
247           TopoDS_Vertex anInitV = TopoDS::Vertex(mkVertex.Shape());
248
249           BRepExtrema_DistShapeShape anExt (anInitV, theRefShape);
250           if ( !anExt.IsDone() || anExt.NbSolution() < 1 )
251                 return Standard_False;
252           thePnt = anExt.PointOnShape2(1);
253           Standard_Real aMinDist2 = theInitPnt.SquareDistance( thePnt );
254           for ( Standard_Integer j = 2, jn = anExt.NbSolution(); j <= jn; j++ )
255           {
256                 gp_Pnt aPnt = anExt.PointOnShape2(j);
257                 Standard_Real aDist2 = theInitPnt.SquareDistance( aPnt );
258                 if ( aDist2 > aMinDist2)
259                   continue;
260                 aMinDist2 = aDist2;
261                 thePnt = aPnt;
262           }
263           return Standard_True;
264         }
265
266         TopoDS_Vertex makePoint(const double x, const double y, const double z)
267         {
268                 gp_Pnt thePoint(x, y, z);
269                 return BRepBuilderAPI_MakeVertex(thePoint);
270         }
271
272         TopoDS_Vertex makePointWithReference(const TopoDS_Shape& point, const double dx,
273                                                                                                                          const double dy,
274                                                                                                                          const double dz)
275         {
276             TopoDS_Vertex res;
277                 gp_Pnt thePoint;
278
279                 if (point.ShapeType() != TopAbs_VERTEX) {
280                         Standard_TypeMismatch::Raise("Aborted: referenced shape is not a vertex");
281                         return res;
282                 }
283                 gp_Pnt refPoint = BRep_Tool::Pnt(TopoDS::Vertex(point));
284                 thePoint = gp_Pnt(refPoint.X() + dx, refPoint.Y() + dy, refPoint.Z() + dz);
285
286                 return BRepBuilderAPI_MakeVertex(thePoint);
287         }
288
289         TopoDS_Vertex makePointOnCurve(const TopoDS_Shape& edge, const double param)
290         {
291             TopoDS_Vertex res;
292                 gp_Pnt thePoint;
293
294                 if (edge.ShapeType() != TopAbs_EDGE) {
295                         Standard_TypeMismatch::Raise("Aborted: curve shape is not an edge");
296                         return res;
297                 }
298                 Standard_Real aFP, aLP, aP;
299                 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(edge), aFP, aLP);
300                 aP = aFP + (aLP - aFP) * param;
301                 thePoint = aCurve->Value(aP);
302
303                 return BRepBuilderAPI_MakeVertex(thePoint);
304         }
305
306         TopoDS_Vertex makePointOnCurveByLength(const TopoDS_Shape& edge, const TopoDS_Shape& point, const double length)
307         {
308             TopoDS_Vertex res;
309                 gp_Pnt thePoint;
310
311                 // RefCurve
312                 if (edge.ShapeType() != TopAbs_EDGE)
313                 {
314                         Standard_TypeMismatch::Raise("Aborted: curve shape is not an edge");
315                         return res;
316                 }
317                 TopoDS_Edge aRefEdge = TopoDS::Edge(edge);
318                 TopoDS_Vertex V1, V2;
319                 TopExp::Vertices(aRefEdge, V1, V2, Standard_True);
320
321                 // RefPoint
322                 TopoDS_Vertex aRefVertex;
323                 if (point.IsNull())
324                         aRefVertex = V1;
325                 else
326                 {
327                         if (point.ShapeType() != TopAbs_VERTEX)
328                         {
329                                 Standard_TypeMismatch::Raise("Aborted: shape is not a vertex");
330                                 return res;
331                         }
332                         aRefVertex = TopoDS::Vertex(point);
333                 }
334                 gp_Pnt aRefPnt = BRep_Tool::Pnt(aRefVertex);
335
336                 // Check orientation
337                 Standard_Real UFirst, ULast;
338                 Handle(Geom_Curve) EdgeCurve = BRep_Tool::Curve(aRefEdge, UFirst, ULast);
339                 Handle(Geom_Curve) ReOrientedCurve = EdgeCurve;
340
341                 Standard_Real dU = ULast - UFirst;
342                 Standard_Real par1 = UFirst + 0.1 * dU;
343                 Standard_Real par2 = ULast  - 0.1 * dU;
344
345                 gp_Pnt P1 = EdgeCurve->Value(par1);
346                 gp_Pnt P2 = EdgeCurve->Value(par2);
347
348                 if (aRefPnt.SquareDistance(P2) < aRefPnt.SquareDistance(P1)) {
349                         ReOrientedCurve = EdgeCurve->Reversed();
350                         UFirst = EdgeCurve->ReversedParameter(ULast);
351                 }
352
353                 // Get the point by length
354                 GeomAdaptor_Curve AdapCurve = GeomAdaptor_Curve(ReOrientedCurve);
355                 GCPnts_AbscissaPoint anAbsPnt (AdapCurve, length, UFirst);
356                 Standard_Real aParam = anAbsPnt.Parameter();
357                 thePoint = AdapCurve.Value(aParam);
358
359                 return BRepBuilderAPI_MakeVertex(thePoint);
360         }
361
362         TopoDS_Vertex makePointOnCurveByCoord(const TopoDS_Shape& edge, const double x, const double y, const double z)
363         {
364             TopoDS_Vertex res;
365                 gp_Pnt thePoint;
366
367                 if (edge.ShapeType() != TopAbs_EDGE) {
368                         Standard_TypeMismatch::Raise("Aborted: curve shape is not an edge");
369                         return res;
370                 }
371                 gp_Pnt anInitPnt (x, y, z);
372                 if (!getExtremaSolution(anInitPnt, edge, thePoint)) {
373                         Standard_ConstructionError::Raise
374                         ("Point On Surface creation aborted : cannot project point");
375                         return res;
376                 }
377
378                 return BRepBuilderAPI_MakeVertex(thePoint);
379         }
380
381         TopoDS_Vertex makePointOnLinesIntersection(const TopoDS_Shape& line1, const TopoDS_Shape& line2)
382         {
383             TopoDS_Vertex res;
384                 gp_Pnt thePoint;
385
386                 if ( (line1.ShapeType() != TopAbs_EDGE && line1.ShapeType() != TopAbs_WIRE)
387                                 || (line2.ShapeType() != TopAbs_EDGE && line2.ShapeType() != TopAbs_WIRE) ) {
388                         Standard_TypeMismatch::Raise("Aborted: Line shape is not an edge or wire");
389                         return res;
390                 }
391
392                 if (line1.IsSame(line2))
393                 {
394                         Standard_ConstructionError::Raise("The lines to make intersection must be different");
395                         return res;
396                 }
397
398                 TopoDS_Compound aCompound;
399                 bool retCompound = false;
400
401                 //Calculate Lines Intersection Point
402                 BRepExtrema_DistShapeShape dst (line1, line2);
403                 if (dst.IsDone()) {
404                         gp_Pnt P1, P2;
405                         BRep_Builder B;
406                         B.MakeCompound( aCompound );
407                         for (int i = 1, nbSols = dst.NbSolution(); i <= nbSols; i++) {
408                                 P1 = dst.PointOnShape1(i);
409                                 P2 = dst.PointOnShape2(i);
410                                 Standard_Real Dist = P1.Distance(P2);
411                                 if ( Dist <= Precision::Confusion() && dst.NbSolution() > 1) {
412                                         BRepBuilderAPI_MakeVertex mkVertex (P1);
413                                         B.Add(aCompound, mkVertex.Shape());
414                                         retCompound = true;
415                                 } else if ( Dist <= Precision::Confusion() ) {
416                                         thePoint = P1;
417                                 } else {
418                                         Standard_TypeMismatch::Raise ("Shapes have not an Intersection Point");
419                                 }
420                         }
421                 }
422                 //    TopoDS_Shape aShape;
423                 if ( retCompound ) {
424                         Standard_TypeMismatch::Raise
425                         ("Aborted: Intersection is a compound of vertices (Not supported)");
426                         //aShape = aCompound;
427                         return res;
428                 }/* else {
429                         BRepBuilderAPI_MakeVertex mkVertex (thePoint);
430                         aShape = mkVertex.Shape();
431                 }
432                 return aShape;*/
433
434                 return BRepBuilderAPI_MakeVertex(thePoint);
435         }
436
437         TopoDS_Vertex makePointOnSurface(const TopoDS_Shape& face, const double param_u, const double param_v)
438         {
439             TopoDS_Vertex res;
440                 gp_Pnt thePoint;
441
442                 if (face.ShapeType() != TopAbs_FACE) {
443                         Standard_TypeMismatch::Raise("Aborted: surface shape is not a face");
444                         return res;
445                 }
446
447                 TopoDS_Face F = TopoDS::Face(face);
448                 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F);
449                 Standard_Real U1,U2,V1,V2;
450                 ShapeAnalysis::GetFaceUVBounds(F,U1,U2,V1,V2);
451                 Standard_Real U = U1 + (U2-U1) * param_u;
452                 Standard_Real V = V1 + (V2-V1) * param_v;
453                 thePoint = aSurf->Value(U,V);
454
455                 return BRepBuilderAPI_MakeVertex(thePoint);
456         }
457
458         TopoDS_Vertex makePointOnSurfaceByCoord(const TopoDS_Shape& face, const double x, const double y, const double z)
459         {
460             TopoDS_Vertex res;
461                 gp_Pnt thePoint;
462
463                 if (face.ShapeType() != TopAbs_FACE) {
464                         Standard_TypeMismatch::Raise
465                         ("Point On Surface creation aborted : surface shape is not a face");
466                         return res;
467                 }
468                 gp_Pnt anInitPnt (x, y, z);
469                 if (!getExtremaSolution(anInitPnt, face, thePoint)) {
470                         Standard_ConstructionError::Raise
471                         ("Point On Surface creation aborted : cannot project point");
472                 }
473
474                 return BRepBuilderAPI_MakeVertex(thePoint);
475         }
476
477 }
478
479 }