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