1 // Created on: 1995-03-15
2 // Created by: Robert COUBLANC
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <StdSelect_ViewerSelector3d.ixx>
18 #include <StdSelect.hxx>
19 #include <SelectBasics_SensitiveEntity.hxx>
20 #include <Graphic3d_AspectLine3d.hxx>
23 #include <gp_Pnt2d.hxx>
26 #include <gp_GTrsf.hxx>
28 #include <Select3D_SensitiveEntity.hxx>
29 #include <Graphic3d_ArrayOfPolylines.hxx>
30 #include <Graphic3d_SequenceOfHClipPlane.hxx>
31 #include <SelectMgr_SelectableObject.hxx>
32 #include <SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive.hxx>
33 #include <SelectBasics_ListOfBox2d.hxx>
34 #include <Visual3d_TransientManager.hxx>
35 #include <TColgp_HArray1OfPnt.hxx>
36 #include <TColgp_Array1OfPnt.hxx>
37 #include <TColgp_HArray1OfPnt2d.hxx>
38 #include <Select3D_SensitiveCurve.hxx>
39 #include <Select3D_SensitiveSegment.hxx>
40 #include <Select3D_SensitiveFace.hxx>
41 #include <Select3D_SensitiveCircle.hxx>
42 #include <Select3D_SensitivePoint.hxx>
43 #include <Select3D_SensitiveTriangulation.hxx>
44 #include <Select3D_SensitiveTriangle.hxx>
45 #include <Select3D_SensitiveWire.hxx>
46 #include <Select3D_SensitiveEntitySequence.hxx>
47 #include <Select3D_ListOfSensitiveTriangle.hxx>
48 #include <Select3D_SensitiveBox.hxx>
49 #include <Select3D_ListIteratorOfListOfSensitiveTriangle.hxx>
51 #include <SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation.hxx>
52 #include <Aspect_TypeOfMarker.hxx>
53 #include <Graphic3d_AspectMarker3d.hxx>
54 #include <Graphic3d_ArrayOfPoints.hxx>
55 #include <SelectBasics_ListIteratorOfListOfBox2d.hxx>
56 #include <Poly_Connect.hxx>
57 #include <TColStd_HArray1OfInteger.hxx>
59 #include <Poly_Array1OfTriangle.hxx>
60 #include <Poly_Triangulation.hxx>
61 #include <OSD_Environment.hxx>
63 #include <V3d_View.hxx>
64 #include <TColgp_SequenceOfPnt.hxx>
67 static Standard_Integer StdSel_NumberOfFreeEdges (const Handle(Poly_Triangulation)& Trg)
69 Standard_Integer nFree = 0;
71 Standard_Integer t[3];
72 Standard_Integer i, j;
73 for (i = 1; i <= Trg->NbTriangles(); i++)
75 pc.Triangles (i, t[0], t[1], t[2]);
76 for (j = 0; j < 3; j++)
77 if (t[j] == 0) nFree++;
82 //=======================================================================
83 // Function : Constructor
85 //=======================================================================
86 StdSelect_ViewerSelector3d::StdSelect_ViewerSelector3d()
87 : myProjector (new Select3D_Projector()),
90 myPrevOrthographic (Standard_True),
91 mySensMode (StdSelect_SM_WINDOW),
93 myToUpdateTolerance (Standard_True)
104 myPrevAxialScale[0] = 0.0;
105 myPrevAxialScale[1] = 0.0;
106 myPrevAxialScale[2] = 0.0;
109 //=======================================================================
110 // Function : Constructor
112 //=======================================================================
113 StdSelect_ViewerSelector3d::StdSelect_ViewerSelector3d (const Handle(Select3D_Projector)& theProj)
114 : myProjector (theProj),
117 myPrevOrthographic (Standard_True),
118 mySensMode (StdSelect_SM_WINDOW),
119 myPixelTolerance (2),
120 myToUpdateTolerance (Standard_True)
131 myPrevAxialScale[0] = 0.0;
132 myPrevAxialScale[1] = 0.0;
133 myPrevAxialScale[2] = 0.0;
136 //=======================================================================
139 //=======================================================================
140 void StdSelect_ViewerSelector3d::Convert (const Handle(SelectMgr_Selection)& theSel)
142 for (theSel->Init(); theSel->More(); theSel->Next())
144 if (theSel->Sensitive()->NeedsConversion())
146 Handle(Select3D_SensitiveEntity) aSE = *((Handle(Select3D_SensitiveEntity)*) &(theSel->Sensitive()));
147 aSE->Project (myProjector);
150 tosort = Standard_True;
156 //=======================================================================
159 //=======================================================================
160 void StdSelect_ViewerSelector3d::Set (const Handle(Select3D_Projector)& theProj)
162 myProjector = theProj;
163 toupdate = Standard_True;
166 //=======================================================================
167 // Function: SetSensitivityMode
169 //=======================================================================
170 void StdSelect_ViewerSelector3d::SetSensitivityMode (const StdSelect_SensitivityMode theMode)
172 mySensMode = theMode;
173 toupdate = Standard_True;
176 //=======================================================================
177 // Function: SetPixelTolerance
179 //=======================================================================
180 void StdSelect_ViewerSelector3d::SetPixelTolerance (const Standard_Integer theTolerance)
182 if (myPixelTolerance != theTolerance)
184 myPixelTolerance = theTolerance;
185 myToUpdateTolerance = Standard_True;
189 //=======================================================================
192 //=======================================================================
193 void StdSelect_ViewerSelector3d::Pick (const Standard_Integer theXPix,
194 const Standard_Integer theYPix,
195 const Handle(V3d_View)& theView)
197 SetClipping (theView->GetClipPlanes());
198 UpdateProj (theView);
200 Standard_Real aXr3d = 0.0;
201 Standard_Real aYr3d = 0.0;
202 Standard_Real aZr3d = 0.0;
204 theView->Convert (theXPix, theYPix, aXr3d, aYr3d, aZr3d);
205 myProjector->Project (gp_Pnt (aXr3d, aYr3d, aZr3d), aP2d);
207 InitSelect (aP2d.X(), aP2d.Y());
210 //=======================================================================
213 //=======================================================================
214 void StdSelect_ViewerSelector3d::Pick (const Standard_Integer theXPMin,
215 const Standard_Integer theYPMin,
216 const Standard_Integer theXPMax,
217 const Standard_Integer theYPMax,
218 const Handle(V3d_View)& theView)
220 if (myToUpdateTolerance && SensitivityMode() == StdSelect_SM_WINDOW)
222 SetSensitivity (theView->Convert (myPixelTolerance));
223 myToUpdateTolerance = Standard_False;
226 UpdateProj (theView);
228 Standard_Real aX1 = 0.0;
229 Standard_Real aY1 = 0.0;
230 Standard_Real aZ1 = 0.0;
231 Standard_Real aX2 = 0.0;
232 Standard_Real aY2 = 0.0;
233 Standard_Real aZ2 = 0.0;
237 theView->Convert (theXPMin, theYPMin, aX1, aY1, aZ1);
238 theView->Convert (theXPMax, theYPMax, aX2, aY2, aZ2);
239 myProjector->Project (gp_Pnt (aX1, aY1, aZ1), aP2d1);
240 myProjector->Project (gp_Pnt (aX2, aY2, aZ2), aP2d2);
242 InitSelect (Min (aP2d1.X(), aP2d2.X()),
243 Min (aP2d1.Y(), aP2d2.Y()),
244 Max (aP2d1.X(), aP2d2.X()),
245 Max (aP2d1.Y(), aP2d2.Y()));
248 //=======================================================================
250 // Purpose : Selection using a polyline
251 //=======================================================================
252 void StdSelect_ViewerSelector3d::Pick (const TColgp_Array1OfPnt2d& thePolyline,
253 const Handle(V3d_View)& theView)
255 if (myToUpdateTolerance && SensitivityMode() == StdSelect_SM_WINDOW)
257 SetSensitivity (theView->Convert (myPixelTolerance));
258 myToUpdateTolerance = Standard_False;
261 UpdateProj (theView);
263 Standard_Integer aNbPix = thePolyline.Length();
266 Handle(TColgp_HArray1OfPnt2d) aP2d = new TColgp_HArray1OfPnt2d (1, aNbPix);
268 for (Standard_Integer aPntIt = 1; aPntIt <= aNbPix; ++aPntIt)
270 Standard_Integer aXP = (Standard_Integer)(thePolyline (aPntIt).X());
271 Standard_Integer aYP = (Standard_Integer)(thePolyline (aPntIt).Y());
273 Standard_Real aX = 0.0;
274 Standard_Real aY = 0.0;
275 Standard_Real aZ = 0.0;
278 theView->Convert (aXP, aYP, aX, aY, aZ);
279 myProjector->Project (gp_Pnt (aX, aY, aZ), aPnt2d);
281 aP2d->SetValue (aPntIt, aPnt2d);
284 const TColgp_Array1OfPnt2d& aPolyConvert = aP2d->Array1();
286 InitSelect (aPolyConvert);
289 //=======================================================================
290 // Function: DisplayAreas
291 // Purpose : display the activated areas...
292 //=======================================================================
293 void StdSelect_ViewerSelector3d::DisplayAreas (const Handle(V3d_View)& theView)
295 if (myToUpdateTolerance && SensitivityMode() == StdSelect_SM_WINDOW)
297 SetSensitivity (theView->Convert (myPixelTolerance));
298 myToUpdateTolerance = Standard_False;
301 UpdateProj (theView);
302 UpdateSort(); // Updates the activated areas
304 if (mystruct.IsNull())
306 mystruct = new Graphic3d_Structure (theView->Viewer()->Viewer());
309 if (myareagroup.IsNull())
311 myareagroup = new Graphic3d_Group (mystruct);
314 SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive anIt (myentities);
315 Handle(Select3D_Projector) aProjector = StdSelect::GetProjector (theView);
316 aProjector->SetView (theView);
318 Standard_Real aXmin = 0.0;
319 Standard_Real aYmin = 0.0;
320 Standard_Real aXmax = 0.0;
321 Standard_Real aYmax = 0.0;
323 SelectBasics_ListOfBox2d aBoxList;
325 TColgp_SequenceOfPnt aSeqLines;
326 for (; anIt.More(); anIt.Next())
328 anIt.Value()->Areas (aBoxList);
330 for (SelectBasics_ListIteratorOfListOfBox2d aBoxIt (aBoxList); aBoxIt.More(); aBoxIt.Next())
332 aBoxIt.Value().Get (aXmin, aYmin, aXmax, aYmax);
334 aPbid.SetCoord (aXmin - mytolerance, aYmin - mytolerance, 0.0);
335 aProjector->Transform (aPbid, aProjector->InvertedTransformation());
336 aSeqLines.Append (aPbid);
338 aPbid.SetCoord (aXmax + mytolerance, aYmin - mytolerance, 0.0);
339 aProjector->Transform (aPbid, aProjector->InvertedTransformation());
340 aSeqLines.Append (aPbid);
342 aPbid.SetCoord (aXmax + mytolerance, aYmax + mytolerance, 0.0);
343 aProjector->Transform (aPbid, aProjector->InvertedTransformation());
344 aSeqLines.Append (aPbid);
346 aPbid.SetCoord (aXmin - mytolerance, aYmax + mytolerance, 0.0);
347 aProjector->Transform (aPbid, aProjector->InvertedTransformation());
348 aSeqLines.Append (aPbid);
352 if (aSeqLines.Length())
354 Standard_Integer aN = 0;
355 Standard_Integer aNp = 0;
356 const Standard_Integer aNbl = aSeqLines.Length() / 4;
358 Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines (5 * aNbl, aNbl);
359 for (aNp = 1, aN = 0; aN < aNbl; aN++)
361 aPrims->AddBound (5);
362 const gp_Pnt &aPnt1 = aSeqLines (aNp++);
363 aPrims->AddVertex (aPnt1);
364 aPrims->AddVertex (aSeqLines (aNp++));
365 aPrims->AddVertex (aSeqLines (aNp++));
366 aPrims->AddVertex (aSeqLines (aNp++));
367 aPrims->AddVertex (aPnt1);
369 myareagroup->AddPrimitiveArray (aPrims);
372 myareagroup->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_AQUAMARINE1, Aspect_TOL_DASH, 1.0));
373 myareagroup->Structure()->SetDisplayPriority (10);
374 myareagroup->Structure()->Display();
376 if (theView->TransientManagerBeginDraw())
378 Visual3d_TransientManager::DrawStructure (mystruct);
379 Visual3d_TransientManager::EndDraw();
387 //=======================================================================
388 // Function: ClearAreas
390 //=======================================================================
391 void StdSelect_ViewerSelector3d::ClearAreas (const Handle(V3d_View)& theView)
393 if (myareagroup.IsNull())
398 myareagroup->Clear();
400 if (theView.IsNull())
405 if (theView->TransientManagerBeginDraw())
407 Visual3d_TransientManager::EndDraw();
415 //=======================================================================
416 // Function: UpdateProj
418 //=======================================================================
419 Standard_Boolean StdSelect_ViewerSelector3d::UpdateProj (const Handle(V3d_View)& theView)
421 // Check common properties of camera
422 Standard_Real anUp[3];
423 Standard_Real aProj[3];
424 Standard_Real anAxialScale[3];
425 theView->Up (anUp[0], anUp[1], anUp[2]);
426 theView->Proj (aProj[0], aProj[1], aProj[2]);
427 theView->AxialScale (anAxialScale[0], anAxialScale[1], anAxialScale[2]);
429 Standard_Boolean isOrthographic = theView->Type() == V3d_ORTHOGRAPHIC;
430 Standard_Boolean toUpdateProjector = myPrevOrthographic != isOrthographic
431 || myPrevUp[0] != anUp[0]
432 || myPrevUp[1] != anUp[1]
433 || myPrevUp[2] != anUp[2]
434 || myPrevProj[0] != aProj[0]
435 || myPrevProj[1] != aProj[1]
436 || myPrevProj[2] != aProj[2]
437 || myPrevAxialScale[0] != anAxialScale[0]
438 || myPrevAxialScale[1] != anAxialScale[1]
439 || myPrevAxialScale[2] != anAxialScale[2];
441 // Check properties of perspective camera
442 Standard_Real anAt[3];
443 Standard_Real aScale = theView->Scale();
444 Standard_Real aFOV = theView->Camera()->FOVy();
445 theView->At (anAt[0], anAt[1], anAt[2]);
446 if (!isOrthographic && !toUpdateProjector)
448 toUpdateProjector = myPrevAt[0] != anAt[0]
449 || myPrevAt[1] != anAt[1]
450 || myPrevAt[2] != anAt[2]
451 || myPrevScale != aScale
452 || myPrevFOV != aFOV;
455 myToUpdateTolerance = aScale != myPrevScale;
457 // Update projector if anything changed
458 if (toUpdateProjector)
460 toupdate = Standard_True;
462 myToUpdateTolerance = Standard_True;
466 // For orthographic view use only direction of projection and up vector
467 // Panning, and zooming has no effect on 2D selection sensitives.
468 Handle (Graphic3d_Camera) aCamera = new Graphic3d_Camera();
470 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Orthographic);
471 aCamera->SetCenter (gp::Origin());
472 aCamera->SetDirection (gp_Dir (-aProj[0], -aProj[1], -aProj[2]));
473 aCamera->SetUp (gp_Dir (anUp[0], anUp[1], anUp[2]));
474 aCamera->SetDistance (1.0);
475 aCamera->SetAxialScale (gp_XYZ (anAxialScale[0], anAxialScale[1], anAxialScale[2]));
477 myProjector = new Select3D_Projector (aCamera->OrientationMatrix(), Graphic3d_Mat4d());
481 // For perspective projection panning, zooming and location of view
482 // has effect. Thus, use current view and projection matrices from
483 // view camera. Exception is that the projection transformation
484 // is scaled from NDC to size of displaying frame of view space in order
485 // to maintain consistence with pixel tolerance conversion.
486 const Graphic3d_Mat4d& aMVMatrix = theView->Camera()->OrientationMatrix();
487 const Graphic3d_Mat4d& aProjMatrix = theView->Camera()->ProjectionMatrix();
488 gp_XYZ aViewDimensions = theView->Camera()->ViewDimensions();
490 Graphic3d_Mat4d aScaledProj;
491 aScaledProj.ChangeValue (0, 0) = aViewDimensions.X();
492 aScaledProj.ChangeValue (1, 1) = aViewDimensions.Y();
493 aScaledProj.ChangeValue (2, 2) = aViewDimensions.Z();
494 Graphic3d_Mat4d aScaledProjMatrix = aScaledProj * aProjMatrix;
496 myProjector = new Select3D_Projector (aMVMatrix, aScaledProjMatrix);
500 myPrevAt[0] = anAt[0];
501 myPrevAt[1] = anAt[1];
502 myPrevAt[2] = anAt[2];
503 myPrevUp[0] = anUp[0];
504 myPrevUp[1] = anUp[1];
505 myPrevUp[2] = anUp[2];
506 myPrevProj[0] = aProj[0];
507 myPrevProj[1] = aProj[1];
508 myPrevProj[2] = aProj[2];
509 myPrevAxialScale[0] = anAxialScale[0];
510 myPrevAxialScale[1] = anAxialScale[1];
511 myPrevAxialScale[2] = anAxialScale[2];
513 myPrevScale = aScale;
514 myPrevOrthographic = isOrthographic;
516 if (myToUpdateTolerance && SensitivityMode() == StdSelect_SM_WINDOW)
518 SetSensitivity (theView->Convert (myPixelTolerance));
519 myToUpdateTolerance = Standard_False;
532 return Standard_True;
536 //=======================================================================
537 // Function: DisplaySensitive.
538 // Purpose : Display active primitives.
539 //=======================================================================
540 void StdSelect_ViewerSelector3d::DisplaySensitive (const Handle(V3d_View)& theView)
542 if (myToUpdateTolerance && SensitivityMode() == StdSelect_SM_WINDOW)
544 SetSensitivity (theView->Convert (myPixelTolerance));
545 myToUpdateTolerance = Standard_False;
550 UpdateProj (theView);
555 UpdateSort(); // Updates the activated areas
558 // Preparation des structures
559 if (mystruct.IsNull())
561 mystruct = new Graphic3d_Structure (theView->Viewer()->Viewer());
564 if (mysensgroup.IsNull())
566 mysensgroup = new Graphic3d_Group (mystruct);
569 Quantity_Color aColor (Quantity_NOC_INDIANRED3);
570 Handle(Graphic3d_AspectMarker3d) aMarkerAspect =
571 new Graphic3d_AspectMarker3d (Aspect_TOM_O_PLUS, aColor, 2.0);
573 mysensgroup->SetPrimitivesAspect (aMarkerAspect);
574 mysensgroup->SetPrimitivesAspect (
575 new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
577 SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation anIt (myselections);
579 for (; anIt.More(); anIt.Next())
583 const Handle(SelectMgr_Selection)& aSel = anIt.Key();
584 ComputeSensitivePrs (aSel);
588 mysensgroup->Structure()->SetDisplayPriority (10);
591 if (theView->TransientManagerBeginDraw())
593 Visual3d_TransientManager::DrawStructure (mystruct);
594 Visual3d_TransientManager::EndDraw();
596 else if (!theView.IsNull())
602 //=======================================================================
603 // Function: ClearSensitive
605 //=======================================================================
606 void StdSelect_ViewerSelector3d::ClearSensitive (const Handle(V3d_View)& theView)
608 if (mysensgroup.IsNull())
613 mysensgroup->Clear();
615 if (theView.IsNull())
620 if (theView->TransientManagerBeginDraw())
622 Visual3d_TransientManager::EndDraw();
630 //=======================================================================
631 //function : DisplaySenstive
633 //=======================================================================
634 void StdSelect_ViewerSelector3d::DisplaySensitive (const Handle(SelectMgr_Selection)& theSel,
635 const Handle(V3d_View)& theView,
636 const Standard_Boolean theToClearOthers)
638 if (mystruct.IsNull())
640 mystruct = new Graphic3d_Structure (theView->Viewer()->Viewer());
643 if (mysensgroup.IsNull())
645 mysensgroup = new Graphic3d_Group (mystruct);
646 Quantity_Color aColor (Quantity_NOC_INDIANRED3);
647 Handle(Graphic3d_AspectMarker3d) aMarkerAspect =
648 new Graphic3d_AspectMarker3d (Aspect_TOM_O_PLUS, aColor, 2.0);
650 mysensgroup-> SetPrimitivesAspect (aMarkerAspect);
651 mysensgroup->SetPrimitivesAspect (
652 new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
655 if (theToClearOthers)
657 mysensgroup->Clear();
660 ComputeSensitivePrs (theSel);
662 mystruct->SetDisplayPriority (10);
664 if (theView->TransientManagerBeginDraw())
666 Visual3d_TransientManager::DrawStructure (mystruct);
667 Visual3d_TransientManager::EndDraw();
669 else if(!theView.IsNull())
675 //=======================================================================
676 //function : DisplayAreas
678 //=======================================================================
679 void StdSelect_ViewerSelector3d::DisplayAreas (const Handle(SelectMgr_Selection)& theSel,
680 const Handle(V3d_View)& theView,
681 const Standard_Boolean theToClearOthers)
683 if (mystruct.IsNull())
685 mystruct = new Graphic3d_Structure (theView->Viewer()->Viewer());
688 if (mysensgroup.IsNull())
690 myareagroup = new Graphic3d_Group (mystruct);
691 myareagroup->SetGroupPrimitivesAspect (
692 new Graphic3d_AspectLine3d (Quantity_NOC_AQUAMARINE1, Aspect_TOL_DASH, 1.0));
695 if (theToClearOthers)
697 myareagroup->Clear();
700 ComputeAreasPrs (theSel);
702 mystruct->SetDisplayPriority (10);
705 if(theView->TransientManagerBeginDraw())
707 Visual3d_TransientManager::DrawStructure (mystruct);
708 Visual3d_TransientManager::EndDraw();
716 //=======================================================================
717 //function : ComputeSensitivePrs
719 //=======================================================================
720 void StdSelect_ViewerSelector3d::ComputeSensitivePrs (const Handle(SelectMgr_Selection)& theSel)
722 TColgp_SequenceOfPnt aSeqLines, aSeqFree;
723 TColStd_SequenceOfInteger aSeqBnds;
725 for (theSel->Init(); theSel->More(); theSel->Next())
727 Handle(Select3D_SensitiveEntity) Ent = Handle(Select3D_SensitiveEntity)::DownCast(theSel->Sensitive());
728 const Standard_Boolean hasloc = (Ent.IsNull()? Standard_False : Ent->HasLocation());
730 TopLoc_Location theloc;
732 theloc = Ent->Location();
738 if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveBox))
740 const Bnd_Box& B = Handle(Select3D_SensitiveBox)::DownCast (Ent)->Box();
741 Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
742 B.Get (xmin, ymin, zmin, xmax, ymax, zmax);
744 gp_Pnt theboxpoint[8] =
746 gp_Pnt(xmin,ymin,zmin),
747 gp_Pnt(xmax,ymin,zmin),
748 gp_Pnt(xmax,ymax,zmin),
749 gp_Pnt(xmin,ymax,zmin),
750 gp_Pnt(xmin,ymin,zmax),
751 gp_Pnt(xmax,ymin,zmax),
752 gp_Pnt(xmax,ymax,zmax),
753 gp_Pnt(xmin,ymax,zmax)
757 for (i = 0; i <= 7; i++)
758 theboxpoint[i].Transform (theloc.Transformation());
762 for (i = 0; i < 4; i++)
763 aSeqLines.Append(theboxpoint[i]);
764 aSeqLines.Append(theboxpoint[0]);
767 for (i = 4; i < 8; i++)
768 aSeqLines.Append(theboxpoint[i]);
769 aSeqLines.Append(theboxpoint[4]);
771 for (i = 0; i < 4; i++)
774 aSeqLines.Append(theboxpoint[i]);
775 aSeqLines.Append(theboxpoint[i+4]);
781 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveFace))
783 Handle(Select3D_SensitiveFace) aFace = Handle(Select3D_SensitiveFace)::DownCast(Ent);
784 Handle(TColgp_HArray1OfPnt) TheHPts;
785 aFace->Points3D(TheHPts);
786 const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
788 aSeqBnds.Append(ThePts.Length());
789 for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
792 aSeqLines.Append(ThePts(I).Transformed (theloc.Transformation()));
794 aSeqLines.Append(ThePts(I));
800 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCurve))
802 Handle(Select3D_SensitiveCurve) aCurve = Handle(Select3D_SensitiveCurve)::DownCast(Ent);
803 Handle(TColgp_HArray1OfPnt) TheHPts;
804 aCurve->Points3D(TheHPts);
805 const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
807 aSeqBnds.Append(ThePts.Length());
808 for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
811 aSeqLines.Append(ThePts(I).Transformed (theloc.Transformation()));
813 aSeqLines.Append(ThePts(I));
819 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveWire))
821 Handle(Select3D_SensitiveWire) aWire = Handle(Select3D_SensitiveWire)::DownCast(Ent);
822 Select3D_SensitiveEntitySequence EntitySeq;
823 aWire->GetEdges (EntitySeq);
825 for (int i = 1; i <= EntitySeq.Length(); i++)
827 Handle(Select3D_SensitiveEntity) SubEnt = Handle(Select3D_SensitiveEntity)::DownCast(EntitySeq.Value(i));
830 if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveSegment))
832 gp_Pnt P1 (Handle(Select3D_SensitiveSegment)::DownCast(SubEnt)->StartPoint().XYZ());
833 gp_Pnt P2 (Handle(Select3D_SensitiveSegment)::DownCast(SubEnt)->EndPoint().XYZ());
836 P1.Transform(theloc.Transformation());
837 P2.Transform(theloc.Transformation());
840 aSeqLines.Append(P1);
841 aSeqLines.Append(P2);
845 if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCircle))
847 Handle(Select3D_SensitiveCircle) C = Handle(Select3D_SensitiveCircle)::DownCast(SubEnt);
848 Standard_Integer Lo, Up;
849 C->ArrayBounds (Lo, Up);
850 Standard_Integer II = Lo;
855 gp_Pnt (C->GetPoint3d (II).XYZ()),
856 gp_Pnt (C->GetPoint3d (++II).XYZ()),
857 gp_Pnt (C->GetPoint3d (++II).XYZ())
862 for (Standard_Integer jj = 0; jj <= 2; jj++)
863 ThePts[jj].Transform (theloc.Transformation());
867 aSeqLines.Append(ThePts[0]);
868 aSeqLines.Append(ThePts[1]);
869 aSeqLines.Append(ThePts[2]);
870 aSeqLines.Append(ThePts[0]);
875 if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCurve))
877 Handle(Select3D_SensitiveCurve) aCurve = Handle(Select3D_SensitiveCurve)::DownCast(SubEnt);
878 Handle(TColgp_HArray1OfPnt) TheHPts;
879 aCurve->Points3D (TheHPts);
880 const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
882 aSeqBnds.Append(ThePts.Length());
883 for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
886 aSeqLines.Append(ThePts(I).Transformed (theloc.Transformation()));
888 aSeqLines.Append(ThePts(I));
896 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveSegment))
898 gp_Pnt P1 (Handle(Select3D_SensitiveSegment)::DownCast(Ent)->StartPoint().XYZ());
899 gp_Pnt P2 (Handle(Select3D_SensitiveSegment)::DownCast(Ent)->EndPoint().XYZ());
902 P1.Transform (theloc.Transformation());
903 P2.Transform (theloc.Transformation());
906 aSeqLines.Append(P1);
907 aSeqLines.Append(P2);
912 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCircle))
914 Handle(Select3D_SensitiveCircle) C = Handle(Select3D_SensitiveCircle)::DownCast(Ent);
915 Standard_Integer Lo, Up;
916 C->ArrayBounds (Lo, Up);
917 Standard_Integer II = Lo;
922 gp_Pnt (C->GetPoint3d (II).XYZ()),
923 gp_Pnt (C->GetPoint3d (++II).XYZ()),
924 gp_Pnt (C->GetPoint3d (++II).XYZ())
929 for (Standard_Integer jj = 0; jj <= 2; jj++)
930 ThePts[jj].Transform (theloc.Transformation());
934 aSeqLines.Append(ThePts[0]);
935 aSeqLines.Append(ThePts[1]);
936 aSeqLines.Append(ThePts[2]);
937 aSeqLines.Append(ThePts[0]);
943 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitivePoint))
946 Handle(Select3D_SensitivePoint)::DownCast(Ent)->Point() :
947 Handle(Select3D_SensitivePoint)::DownCast(Ent)->Point().Transformed (theloc.Transformation());
948 Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints = new Graphic3d_ArrayOfPoints (1);
949 anArrayOfPoints->AddVertex (P.X(), P.Y(), P.Z());
950 mysensgroup->AddPrimitiveArray (anArrayOfPoints);
952 //============================================================
953 // Triangulation : On met un petit offset ves l'interieur...
954 //==========================================================
955 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveTriangulation))
957 const Handle(Poly_Triangulation)& PT =
958 (*((Handle(Select3D_SensitiveTriangulation)*) &Ent))->Triangulation();
960 const Poly_Array1OfTriangle& triangles = PT->Triangles();
961 const TColgp_Array1OfPnt& Nodes = PT->Nodes();
962 Standard_Integer n[3];
964 TopLoc_Location iloc, bidloc;
965 if ((*((Handle(Select3D_SensitiveTriangulation)*) &Ent))->HasInitLocation())
966 bidloc = (*((Handle(Select3D_SensitiveTriangulation)*) &Ent))->GetInitLocation();
968 if (bidloc.IsIdentity())
971 iloc = theloc * bidloc;
974 for (i = 1; i <= PT->NbTriangles(); i++)
976 triangles (i).Get (n[0], n[1], n[2]);
977 gp_Pnt P1 (Nodes (n[0]).Transformed (iloc));
978 gp_Pnt P2 (Nodes (n[1]).Transformed (iloc));
979 gp_Pnt P3 (Nodes (n[2]).Transformed (iloc));
980 gp_XYZ V1 (P1.XYZ());
981 gp_XYZ V2 (P2.XYZ());
982 gp_XYZ V3 (P3.XYZ());
983 gp_XYZ CDG (P1.XYZ()); CDG += (P2.XYZ()); CDG += (P3.XYZ()); CDG /= 3.0;
984 V1 -= CDG; V2 -= CDG; V3 -= CDG;
985 V1 *= 0.9; V2 *= 0.9; V3 *= 0.9;
986 V1 += CDG; V2 += CDG; V3 += CDG;
989 aSeqLines.Append(gp_Pnt(V1));
990 aSeqLines.Append(gp_Pnt(V2));
991 aSeqLines.Append(gp_Pnt(V3));
992 aSeqLines.Append(gp_Pnt(V1));
995 // recherche des bords libres...
997 Handle(TColStd_HArray1OfInteger) FreeEdges = new TColStd_HArray1OfInteger (1, 2 * StdSel_NumberOfFreeEdges (PT));
998 TColStd_Array1OfInteger& FreeE = FreeEdges->ChangeArray1();
999 Poly_Connect pc (PT);
1000 Standard_Integer t[3];
1002 Standard_Integer fr (1);
1003 for (i = 1; i <= PT->NbTriangles(); i++)
1005 pc.Triangles (i, t[0], t[1], t[2]);
1006 triangles (i).Get (n[0], n[1], n[2]);
1007 for (j = 0; j < 3; j++)
1009 Standard_Integer k = (j + 1) % 3;
1013 FreeE (fr + 1)= n[k];
1018 for (Standard_Integer ifri = 1; ifri <= FreeE.Length(); ifri += 2)
1020 gp_Pnt pe1 (Nodes (FreeE (ifri)).Transformed (iloc)), pe2 (Nodes (FreeE (ifri + 1)).Transformed (iloc));
1021 aSeqFree.Append(pe1);
1022 aSeqFree.Append(pe2);
1025 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveTriangle))
1027 Handle(Select3D_SensitiveTriangle) Str = Handle(Select3D_SensitiveTriangle)::DownCast(Ent);
1029 Str->Points3D (P1, P2, P3);
1030 gp_Pnt CDG = Str->Center3D();
1032 gp_XYZ V1 (P1.XYZ()); V1 -= (CDG.XYZ());
1033 gp_XYZ V2 (P2.XYZ()); V2 -= (CDG.XYZ());
1034 gp_XYZ V3 (P3.XYZ()); V3 -= (CDG.XYZ());
1035 V1 *= 0.9; V2 *= 0.9; V3 *= 0.9;
1036 V1 += CDG.XYZ(); V2 += CDG.XYZ(); V3 += CDG.XYZ();
1039 aSeqLines.Append(gp_Pnt(V1));
1040 aSeqLines.Append(gp_Pnt(V2));
1041 aSeqLines.Append(gp_Pnt(V3));
1042 aSeqLines.Append(gp_Pnt(V1));
1048 if (aSeqLines.Length())
1050 Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(aSeqLines.Length(),aSeqBnds.Length());
1051 for (i = 1; i <= aSeqLines.Length(); i++)
1052 aPrims->AddVertex(aSeqLines(i));
1053 for (i = 1; i <= aSeqBnds.Length(); i++)
1054 aPrims->AddBound(aSeqBnds(i));
1055 myareagroup->AddPrimitiveArray(aPrims);
1058 if (aSeqFree.Length())
1060 mysensgroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_GREEN, Aspect_TOL_SOLID, 2.0));
1061 Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(aSeqFree.Length(),aSeqFree.Length()/2);
1062 for (i = 1; i <= aSeqFree.Length(); i++)
1064 aPrims->AddBound(2);
1065 aPrims->AddVertex(aSeqLines(i++));
1066 aPrims->AddVertex(aSeqLines(i));
1068 mysensgroup->AddPrimitiveArray(aPrims);
1069 mysensgroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
1073 //=======================================================================
1074 //function : ComputeAreaPrs
1076 //=======================================================================
1077 void StdSelect_ViewerSelector3d::ComputeAreasPrs (const Handle(SelectMgr_Selection)& theSel)
1079 Standard_Real aXmin = 0.0;
1080 Standard_Real aYmin = 0.0;
1081 Standard_Real aXmax = 0.0;
1082 Standard_Real aYmax = 0.0;
1085 SelectBasics_ListOfBox2d aBoxList;
1087 TColgp_SequenceOfPnt aSeqLines;
1088 for (theSel->Init(); theSel->More(); theSel->Next())
1090 theSel->Sensitive()->Areas (aBoxList);
1091 for (SelectBasics_ListIteratorOfListOfBox2d aBoxIt (aBoxList); aBoxIt.More(); aBoxIt.Next())
1093 aBoxIt.Value().Get (aXmin, aYmin, aXmax, aYmax);
1095 aPbid.SetCoord (aXmin - mytolerance, aYmin - mytolerance, 0.0);
1096 myProjector->Transform (aPbid, myProjector->InvertedTransformation());
1097 aSeqLines.Append (aPbid);
1099 aPbid.SetCoord (aXmax + mytolerance, aYmin - mytolerance, 0.0);
1100 myProjector->Transform (aPbid, myProjector->InvertedTransformation());
1101 aSeqLines.Append (aPbid);
1103 aPbid.SetCoord (aXmax + mytolerance, aYmax + mytolerance, 0.0);
1104 myProjector->Transform (aPbid, myProjector->InvertedTransformation());
1105 aSeqLines.Append (aPbid);
1107 aPbid.SetCoord (aXmin - mytolerance, aYmax + mytolerance, 0.0);
1108 myProjector->Transform (aPbid, myProjector->InvertedTransformation());
1109 aSeqLines.Append (aPbid);
1113 if (aSeqLines.Length())
1115 Standard_Integer aN = 0;
1116 Standard_Integer aNP = 0;
1117 const Standard_Integer aNBL = aSeqLines.Length() / 4;
1118 Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines (5 * aNBL, aNBL);
1119 for (aNP = 1, aN = 0; aN < aNBL; aN++)
1121 aPrims->AddBound (5);
1122 const gp_Pnt &aP1 = aSeqLines (aNP++);
1123 aPrims->AddVertex (aP1);
1124 aPrims->AddVertex (aSeqLines (aNP++));
1125 aPrims->AddVertex (aSeqLines (aNP++));
1126 aPrims->AddVertex (aSeqLines (aNP++));
1127 aPrims->AddVertex (aP1);
1129 myareagroup->AddPrimitiveArray (aPrims);
1133 //=======================================================================
1134 //function : SetClipping
1136 //=======================================================================
1137 void StdSelect_ViewerSelector3d::SetClipping (const Graphic3d_SequenceOfHClipPlane& thePlanes)
1139 myClipPlanes = thePlanes;
1142 //=======================================================================
1143 //function : ComputeClipRange
1145 //=======================================================================
1146 void StdSelect_ViewerSelector3d::ComputeClipRange (const Graphic3d_SequenceOfHClipPlane& thePlanes,
1147 const gp_Lin& thePickLine,
1148 Standard_Real& theDepthMin,
1149 Standard_Real& theDepthMax) const
1151 theDepthMin = RealFirst();
1152 theDepthMax = RealLast();
1153 Standard_Real aPlaneA, aPlaneB, aPlaneC, aPlaneD;
1155 Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (thePlanes);
1156 for (; aPlaneIt.More(); aPlaneIt.Next())
1158 const Handle(Graphic3d_ClipPlane)& aClipPlane = aPlaneIt.Value();
1159 if (!aClipPlane->IsOn())
1162 gp_Pln aGeomPlane = aClipPlane->ToPlane();
1164 aGeomPlane.Coefficients (aPlaneA, aPlaneB, aPlaneC, aPlaneD);
1166 const gp_Dir& aPlaneDir = aGeomPlane.Axis().Direction();
1167 const gp_Dir& aPickDir = thePickLine.Direction();
1168 const gp_XYZ& aPntOnLine = thePickLine.Location().XYZ();
1169 const gp_XYZ& aPlaneDirXYZ = aPlaneDir.XYZ();
1171 Standard_Real aDotProduct = aPickDir.Dot (aPlaneDir);
1172 Standard_Real aDistance = -(aPntOnLine.Dot (aPlaneDirXYZ) + aPlaneD);
1174 // check whether the pick line is parallel to clip plane
1175 if (Abs (aDotProduct) < Precision::Angular())
1177 if (aDistance > 0.0)
1179 // line lies above the plane, thus no selection is possible
1185 // line lies below the plane and is not clipped, skip
1189 // compute distance to point of pick line intersection with the plane
1190 Standard_Real aIntDist = aDistance / aDotProduct;
1192 // change depth limits for case of opposite and directed planes
1193 if (aDotProduct < 0.0)
1195 theDepthMax = Min (aIntDist, theDepthMax);
1197 else if (aIntDist > theDepthMin)
1199 theDepthMin = Max (aIntDist, theDepthMin);
1204 //=======================================================================
1205 //function : PickingLine
1207 //=======================================================================
1208 gp_Lin StdSelect_ViewerSelector3d::PickingLine(const Standard_Real theX, const Standard_Real theY) const
1210 return myProjector->Shoot (theX, theY);
1213 //=======================================================================
1214 //function : DepthClipping
1216 //=======================================================================
1217 void StdSelect_ViewerSelector3d::DepthClipping (const Standard_Real theX,
1218 const Standard_Real theY,
1219 Standard_Real& theDepthMin,
1220 Standard_Real& theDepthMax) const
1222 return ComputeClipRange (myClipPlanes, PickingLine (theX, theY), theDepthMin, theDepthMax);
1225 //=======================================================================
1226 //function : DepthClipping
1228 //=======================================================================
1229 void StdSelect_ViewerSelector3d::DepthClipping (const Standard_Real theX,
1230 const Standard_Real theY,
1231 const Handle(SelectMgr_EntityOwner)& theOwner,
1232 Standard_Real& theDepthMin,
1233 Standard_Real& theDepthMax) const
1235 return ComputeClipRange (theOwner->Selectable()->GetClipPlanes(),
1236 PickingLine (theX, theY),
1237 theDepthMin, theDepthMax);
1240 //=======================================================================
1241 //function : HasDepthClipping
1243 //=======================================================================
1244 Standard_Boolean StdSelect_ViewerSelector3d::HasDepthClipping (const Handle(SelectMgr_EntityOwner)& theOwner) const
1246 if (!theOwner->HasSelectable())
1248 return Standard_False;
1251 const Handle(SelectMgr_SelectableObject)& aSelectable = theOwner->Selectable();
1252 return (aSelectable->GetClipPlanes().Size() > 0);