1 // Copyright (C) 2009-2015 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include <BRepTools.hxx>
27 #include <vtkRenderer.h>
28 #include <vtkActorCollection.h>
29 #include <vtkUnstructuredGrid.h>
31 #include <Basics_OCCTVersion.hxx>
33 #include <SUIT_Session.h>
35 #include <SalomeApp_Study.h>
36 #include <SalomeApp_Application.h>
38 #include <OCCViewer_ViewWindow.h>
40 #include <SVTK_ViewManager.h>
41 #include <SVTK_ViewModel.h>
42 #include <SVTK_ViewWindow.h>
44 #include <SALOME_Actor.h>
45 #include <VTKViewer_Algorithm.h>
47 #include <SelectMgr_Selection.hxx>
48 #include <TColStd_ListIteratorOfListOfInteger.hxx>
49 #include <SelectBasics_SensitiveEntity.hxx>
50 #include <TColStd_IndexedMapOfInteger.hxx>
51 #include <TopTools_IndexedMapOfShape.hxx>
53 #include <StdSelect_BRepOwner.hxx>
56 #include <TopoDS_Face.hxx>
57 #include <BRepBuilderAPI_MakeVertex.hxx>
58 #include <Geom_Surface.hxx>
59 #include <ShapeAnalysis.hxx>
60 #include <BRep_Tool.hxx>
61 #include <BRep_Builder.hxx>
62 #include <Geom_Curve.hxx>
63 #include <BRepExtrema_DistShapeShape.hxx>
64 #include <BRepAdaptor_Curve.hxx>
65 #include <GCPnts_AbscissaPoint.hxx>
66 #include <TopoDS_Compound.hxx>
68 #include "HEXABLOCKGUI.hxx"
69 #include "HEXABLOCKGUI_SalomeTools.hxx"
70 #include "HEXABLOCKGUI_OccGraphicView.hxx"
82 SUIT_Study* GetActiveStudy()
84 SUIT_Application* app = SUIT_Session::session()->activeApplication();
86 return app->activeStudy();
92 _PTR(Study) GetActiveStudyDocument()
94 SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(GetActiveStudy());
96 return aStudy->studyDS();
102 SALOME_Actor* findActorByEntry( SVTK_ViewWindow *theVtkViewWindow, const char* theEntry)
104 SALOME_Actor *foundActor = NULL;
105 vtkActor *aVTKActor = NULL;
106 Handle(SALOME_InteractiveObject) anIO;
108 vtkRenderer *aRenderer = theVtkViewWindow->getRenderer();
109 VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
110 vtkActorCollection *aCollection = aCopy.GetActors();
111 aCollection->InitTraversal();
112 while( aVTKActor = aCollection->GetNextActor() ){
113 foundActor = dynamic_cast<SALOME_Actor*>( aVTKActor );
114 if ( foundActor && foundActor->hasIO() ){
115 anIO = foundActor->getIO();
116 if( anIO->hasEntry() && strcmp(anIO->getEntry(), theEntry) == 0 )
121 return NULL; // no actor found
125 int GetNameOfSelectedElements( SVTK_ViewWindow *theWindow,
126 const Handle(SALOME_InteractiveObject)& theIO,
129 SVTK_Selector* theSelector = theWindow->GetSelector();
133 TColStd_IndexedMapOfInteger aMapIndex;
134 theSelector->GetIndex(theIO,aMapIndex);
136 typedef std::set<int> TIdContainer;
138 std::set<int> anIdContainer;
140 for( int i = 1; i <= aMapIndex.Extent(); i++)
141 anIdContainer.insert(aMapIndex(i));
143 std::set<int>::const_iterator anIter = anIdContainer.begin();
145 for( ; anIter != anIdContainer.end(); anIter++)
146 theName += QString(" %1").arg(*anIter);
148 return aMapIndex.Extent();
151 string shape2string( const TopoDS_Shape& aShape )
153 ostringstream streamShape;
154 BRepTools::Write(aShape, streamShape);
156 return streamShape.str();
159 void getEntityOwners( const Handle(AIS_InteractiveObject)& theObj,
160 const Handle(AIS_InteractiveContext)& theIC,
161 SelectMgr_IndexedMapOfOwner& theMap )
163 if ( theObj.IsNull() || theIC.IsNull() )
166 TColStd_ListOfInteger modes;
167 theIC->ActivatedModes( theObj, modes );
169 TColStd_ListIteratorOfListOfInteger itr( modes );
170 for (; itr.More(); itr.Next() ) {
172 if ( !theObj->HasSelection( m ) )
175 Handle(SelectMgr_Selection) sel = theObj->Selection( m );
177 for ( sel->Init(); sel->More(); sel->Next() ) {
178 #if OCC_VERSION_LARGE > 0x06080100
179 const Handle(SelectMgr_SensitiveEntity) aHSenEntity = sel->Sensitive();
180 if ( aHSenEntity.IsNull() )
182 Handle(SelectBasics_SensitiveEntity) entity = aHSenEntity->BaseSensitive();
184 Handle(SelectBasics_SensitiveEntity) entity = sel->Sensitive();
186 if ( entity.IsNull() )
189 Handle(SelectMgr_EntityOwner) owner =
190 Handle(SelectMgr_EntityOwner)::DownCast(entity->OwnerId());
191 if ( !owner.IsNull() )
197 void indicesToOwners( const TColStd_IndexedMapOfInteger& aIndexMap,
198 const TopoDS_Shape& aMainShape,
199 const SelectMgr_IndexedMapOfOwner& anAllMap,
200 SelectMgr_IndexedMapOfOwner& aToHiliteMap )
202 TopTools_IndexedMapOfShape aMapOfShapes;
203 TopExp::MapShapes(aMainShape, aMapOfShapes);
205 for ( Standard_Integer i = 1, n = anAllMap.Extent(); i <= n; i++ )
207 Handle(StdSelect_BRepOwner) anOwner = Handle(StdSelect_BRepOwner)::DownCast(anAllMap( i ));
208 if ( anOwner.IsNull() || !anOwner->HasShape() )
211 const TopoDS_Shape& aSubShape = anOwner->Shape();
212 Standard_Integer aSubShapeId = aMapOfShapes.FindIndex( aSubShape );
213 if ( !aSubShapeId || !aIndexMap.Contains( aSubShapeId ) )
216 if ( !aToHiliteMap.Contains( anOwner ) )
217 aToHiliteMap.Add( anOwner );
221 TopoDS_Shape getSubShape(const TopoDS_Shape& theShape, const int theIndex)
223 TopoDS_Shape theSubShape;
225 if (theShape.IsNull() || theIndex < 1)
228 TopTools_IndexedMapOfShape anIndices;
229 TopExp::MapShapes(theShape, anIndices);
230 if (theIndex > anIndices.Extent())
232 theSubShape = anIndices.FindKey(theIndex);
237 int getSubId(const TopoDS_Shape& theShape, const TopoDS_Shape& theSubShape)
239 if (theShape.IsNull() || theSubShape.IsNull())
242 TopTools_IndexedMapOfShape anIndices;
243 TopExp::MapShapes(theShape, anIndices);
245 return anIndices.FindIndex(theSubShape);
248 Standard_Boolean getExtremaSolution(const gp_Pnt& theInitPnt,
249 const TopoDS_Shape& theRefShape,
252 BRepBuilderAPI_MakeVertex mkVertex (theInitPnt);
253 TopoDS_Vertex anInitV = TopoDS::Vertex(mkVertex.Shape());
255 BRepExtrema_DistShapeShape anExt (anInitV, theRefShape);
256 if ( !anExt.IsDone() || anExt.NbSolution() < 1 )
257 return Standard_False;
258 thePnt = anExt.PointOnShape2(1);
259 Standard_Real aMinDist2 = theInitPnt.SquareDistance( thePnt );
260 for ( Standard_Integer j = 2, jn = anExt.NbSolution(); j <= jn; j++ )
262 gp_Pnt aPnt = anExt.PointOnShape2(j);
263 Standard_Real aDist2 = theInitPnt.SquareDistance( aPnt );
264 if ( aDist2 > aMinDist2)
269 return Standard_True;
272 TopoDS_Vertex makePoint(const double x, const double y, const double z)
274 gp_Pnt thePoint(x, y, z);
275 return BRepBuilderAPI_MakeVertex(thePoint);
278 TopoDS_Vertex makePointWithReference(const TopoDS_Shape& point, const double dx,
285 if (point.ShapeType() != TopAbs_VERTEX) {
286 Standard_TypeMismatch::Raise("Aborted: referenced shape is not a vertex");
289 gp_Pnt refPoint = BRep_Tool::Pnt(TopoDS::Vertex(point));
290 thePoint = gp_Pnt(refPoint.X() + dx, refPoint.Y() + dy, refPoint.Z() + dz);
292 return BRepBuilderAPI_MakeVertex(thePoint);
295 TopoDS_Vertex makePointOnCurve(const TopoDS_Shape& edge, const double param)
300 if (edge.ShapeType() != TopAbs_EDGE) {
301 Standard_TypeMismatch::Raise("Aborted: curve shape is not an edge");
304 Standard_Real aFP, aLP, aP;
305 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(edge), aFP, aLP);
306 aP = aFP + (aLP - aFP) * param;
307 thePoint = aCurve->Value(aP);
309 return BRepBuilderAPI_MakeVertex(thePoint);
312 TopoDS_Vertex makePointOnCurveByLength(const TopoDS_Shape& edge, const TopoDS_Shape& point, const double length)
318 if (edge.ShapeType() != TopAbs_EDGE)
320 Standard_TypeMismatch::Raise("Aborted: curve shape is not an edge");
323 TopoDS_Edge aRefEdge = TopoDS::Edge(edge);
324 TopoDS_Vertex V1, V2;
325 TopExp::Vertices(aRefEdge, V1, V2, Standard_True);
328 TopoDS_Vertex aRefVertex;
333 if (point.ShapeType() != TopAbs_VERTEX)
335 Standard_TypeMismatch::Raise("Aborted: shape is not a vertex");
338 aRefVertex = TopoDS::Vertex(point);
340 gp_Pnt aRefPnt = BRep_Tool::Pnt(aRefVertex);
343 Standard_Real UFirst, ULast;
344 Handle(Geom_Curve) EdgeCurve = BRep_Tool::Curve(aRefEdge, UFirst, ULast);
345 Handle(Geom_Curve) ReOrientedCurve = EdgeCurve;
347 Standard_Real dU = ULast - UFirst;
348 Standard_Real par1 = UFirst + 0.1 * dU;
349 Standard_Real par2 = ULast - 0.1 * dU;
351 gp_Pnt P1 = EdgeCurve->Value(par1);
352 gp_Pnt P2 = EdgeCurve->Value(par2);
354 if (aRefPnt.SquareDistance(P2) < aRefPnt.SquareDistance(P1)) {
355 ReOrientedCurve = EdgeCurve->Reversed();
356 UFirst = EdgeCurve->ReversedParameter(ULast);
359 // Get the point by length
360 GeomAdaptor_Curve AdapCurve = GeomAdaptor_Curve(ReOrientedCurve);
361 GCPnts_AbscissaPoint anAbsPnt (AdapCurve, length, UFirst);
362 Standard_Real aParam = anAbsPnt.Parameter();
363 thePoint = AdapCurve.Value(aParam);
365 return BRepBuilderAPI_MakeVertex(thePoint);
368 TopoDS_Vertex makePointOnCurveByCoord(const TopoDS_Shape& edge, const double x, const double y, const double z)
373 if (edge.ShapeType() != TopAbs_EDGE) {
374 Standard_TypeMismatch::Raise("Aborted: curve shape is not an edge");
377 gp_Pnt anInitPnt (x, y, z);
378 if (!getExtremaSolution(anInitPnt, edge, thePoint)) {
379 Standard_ConstructionError::Raise
380 ("Point On Surface creation aborted : cannot project point");
384 return BRepBuilderAPI_MakeVertex(thePoint);
387 TopoDS_Vertex makePointOnLinesIntersection(const TopoDS_Shape& line1, const TopoDS_Shape& line2)
392 if ( (line1.ShapeType() != TopAbs_EDGE && line1.ShapeType() != TopAbs_WIRE)
393 || (line2.ShapeType() != TopAbs_EDGE && line2.ShapeType() != TopAbs_WIRE) ) {
394 Standard_TypeMismatch::Raise("Aborted: Line shape is not an edge or wire");
398 if (line1.IsSame(line2))
400 Standard_ConstructionError::Raise("The lines to make intersection must be different");
404 TopoDS_Compound aCompound;
405 bool retCompound = false;
407 //Calculate Lines Intersection Point
408 BRepExtrema_DistShapeShape dst (line1, line2);
412 B.MakeCompound( aCompound );
413 for (int i = 1, nbSols = dst.NbSolution(); i <= nbSols; i++) {
414 P1 = dst.PointOnShape1(i);
415 P2 = dst.PointOnShape2(i);
416 Standard_Real Dist = P1.Distance(P2);
417 if ( Dist <= Precision::Confusion() && dst.NbSolution() > 1) {
418 BRepBuilderAPI_MakeVertex mkVertex (P1);
419 B.Add(aCompound, mkVertex.Shape());
421 } else if ( Dist <= Precision::Confusion() ) {
424 Standard_TypeMismatch::Raise ("Shapes have not an Intersection Point");
428 // TopoDS_Shape aShape;
430 Standard_TypeMismatch::Raise
431 ("Aborted: Intersection is a compound of vertices (Not supported)");
432 //aShape = aCompound;
435 BRepBuilderAPI_MakeVertex mkVertex (thePoint);
436 aShape = mkVertex.Shape();
440 return BRepBuilderAPI_MakeVertex(thePoint);
443 TopoDS_Vertex makePointOnSurface(const TopoDS_Shape& face, const double param_u, const double param_v)
448 if (face.ShapeType() != TopAbs_FACE) {
449 Standard_TypeMismatch::Raise("Aborted: surface shape is not a face");
453 TopoDS_Face F = TopoDS::Face(face);
454 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F);
455 Standard_Real U1,U2,V1,V2;
456 ShapeAnalysis::GetFaceUVBounds(F,U1,U2,V1,V2);
457 Standard_Real U = U1 + (U2-U1) * param_u;
458 Standard_Real V = V1 + (V2-V1) * param_v;
459 thePoint = aSurf->Value(U,V);
461 return BRepBuilderAPI_MakeVertex(thePoint);
464 TopoDS_Vertex makePointOnSurfaceByCoord(const TopoDS_Shape& face, const double x, const double y, const double z)
469 if (face.ShapeType() != TopAbs_FACE) {
470 Standard_TypeMismatch::Raise
471 ("Point On Surface creation aborted : surface shape is not a face");
474 gp_Pnt anInitPnt (x, y, z);
475 if (!getExtremaSolution(anInitPnt, face, thePoint)) {
476 Standard_ConstructionError::Raise
477 ("Point On Surface creation aborted : cannot project point");
480 return BRepBuilderAPI_MakeVertex(thePoint);