mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-06-25 12:04:07 +03:00
Select3D_SensitiveCircle now inherits directly from Select3D_SensitiveEntity. The sensitive circle sector is created using the Select3D_SensitivePoly class directly. Added appropriate methods for selecting sensitive circles. Added parameter myIsHollow to Select3D_SensitiveCylinder class. It allows you to search for intersections with cylinders without covers. The Draw vcircle command has been extended with UStart and UEnd parameters to create a sector of a circle. Added tests: vselect/cone_cylinder/circle_sector vselect/cone_cylinder/circle_wire vselect/cone_cylinder/filled_circle vselect/cone_cylinder/transformed vselect/cone_cylinder/hollow_cone_cyl
313 lines
12 KiB
C++
313 lines
12 KiB
C++
// Copyright (c) 2020 OPEN CASCADE SAS
|
|
//
|
|
// This file is part of Open CASCADE Technology software library.
|
|
//
|
|
// This library is free software; you can redistribute it and/or modify it under
|
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
|
// by the Free Software Foundation, with special exception defined in the file
|
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
// distribution for complete text of the license and disclaimer of any warranty.
|
|
//
|
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
// commercial license or contractual agreement.
|
|
|
|
#include <SelectMgr.hxx>
|
|
|
|
#include <Geom_Circle.hxx>
|
|
#include <Graphic3d_ArrayOfPoints.hxx>
|
|
#include <Graphic3d_AspectMarker3d.hxx>
|
|
#include <Poly_Triangulation.hxx>
|
|
#include <Prs3d.hxx>
|
|
#include <Prs3d_LineAspect.hxx>
|
|
#include <Prs3d_NListOfSequenceOfPnt.hxx>
|
|
#include <TColgp_HArray1OfPnt.hxx>
|
|
#include <TColgp_SequenceOfPnt.hxx>
|
|
#include <Select3D_SensitiveBox.hxx>
|
|
#include <Select3D_SensitiveCircle.hxx>
|
|
#include <Select3D_SensitiveCylinder.hxx>
|
|
#include <Select3D_SensitiveEntity.hxx>
|
|
#include <Select3D_SensitiveFace.hxx>
|
|
#include <Select3D_SensitivePoint.hxx>
|
|
#include <Select3D_SensitiveSegment.hxx>
|
|
#include <Select3D_SensitiveTriangle.hxx>
|
|
#include <Select3D_SensitiveTriangulation.hxx>
|
|
#include <Select3D_SensitiveWire.hxx>
|
|
#include <SelectMgr_Selection.hxx>
|
|
|
|
namespace
|
|
{
|
|
//! Compute polyline of shrunk triangle.
|
|
static Handle(TColgp_HSequenceOfPnt) shrunkTriangle (const gp_Pnt* thePnts,
|
|
const gp_XYZ& theCenter)
|
|
{
|
|
const gp_XYZ aV1 = theCenter + (thePnts[0].XYZ() - theCenter) * 0.9;
|
|
const gp_XYZ aV2 = theCenter + (thePnts[1].XYZ() - theCenter) * 0.9;
|
|
const gp_XYZ aV3 = theCenter + (thePnts[2].XYZ() - theCenter) * 0.9;
|
|
Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt();
|
|
aPoints->Append (aV1);
|
|
aPoints->Append (aV2);
|
|
aPoints->Append (aV3);
|
|
aPoints->Append (aV1);
|
|
return aPoints;
|
|
}
|
|
|
|
//! Fill in triangulation polylines.
|
|
static void addTriangulation (Prs3d_NListOfSequenceOfPnt& theSeqLines,
|
|
Prs3d_NListOfSequenceOfPnt& theSeqFree,
|
|
const Handle(Select3D_SensitiveTriangulation)& theTri,
|
|
const gp_Trsf& theLoc)
|
|
{
|
|
gp_Trsf aTrsf = theLoc;
|
|
if (theTri->HasInitLocation())
|
|
{
|
|
aTrsf = theLoc * theTri->GetInitLocation();
|
|
}
|
|
const Handle(Poly_Triangulation)& aPolyTri = theTri->Triangulation();
|
|
for (Standard_Integer aTriIter = 1; aTriIter <= aPolyTri->NbTriangles(); ++aTriIter)
|
|
{
|
|
const Poly_Triangle& aTri = aPolyTri->Triangle (aTriIter);
|
|
const gp_Pnt aPnts[3] =
|
|
{
|
|
aPolyTri->Node (aTri (1)).Transformed (aTrsf),
|
|
aPolyTri->Node (aTri (2)).Transformed (aTrsf),
|
|
aPolyTri->Node (aTri (3)).Transformed (aTrsf)
|
|
};
|
|
const gp_XYZ aCenter = (aPnts[0].XYZ() + aPnts[1].XYZ() + aPnts[2].XYZ()) / 3.0;
|
|
theSeqLines.Append (shrunkTriangle (aPnts, aCenter));
|
|
}
|
|
|
|
Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt();
|
|
Prs3d::AddFreeEdges (*aPoints, aPolyTri, aTrsf);
|
|
if (!aPoints->IsEmpty())
|
|
{
|
|
theSeqFree.Append (aPoints);
|
|
}
|
|
}
|
|
|
|
//! Fill in bounding box polylines.
|
|
static void addBoundingBox (Prs3d_NListOfSequenceOfPnt& theSeqLines,
|
|
const Handle(Select3D_SensitiveBox)& theSensBox,
|
|
const gp_Trsf& theLoc)
|
|
{
|
|
Graphic3d_Vec3d aMin, aMax;
|
|
theSensBox->Box().Get (aMin.x(), aMin.y(), aMin.z(), aMax.x(), aMax.y(), aMax.z());
|
|
gp_Pnt aPnts[8] =
|
|
{
|
|
gp_Pnt(aMin.x(), aMin.y(), aMin.z()),
|
|
gp_Pnt(aMax.x(), aMin.y(), aMin.z()),
|
|
gp_Pnt(aMax.x(), aMax.y(), aMin.z()),
|
|
gp_Pnt(aMin.x(), aMax.y(), aMin.z()),
|
|
gp_Pnt(aMin.x(), aMin.y(), aMax.z()),
|
|
gp_Pnt(aMax.x(), aMin.y(), aMax.z()),
|
|
gp_Pnt(aMax.x(), aMax.y(), aMax.z()),
|
|
gp_Pnt(aMin.x(), aMax.y(), aMax.z())
|
|
};
|
|
for (Standard_Integer aPntIter = 0; aPntIter <= 7; ++aPntIter)
|
|
{
|
|
aPnts[aPntIter].Transform (theLoc);
|
|
}
|
|
|
|
{
|
|
Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt();
|
|
for (Standard_Integer i = 0; i < 4; ++i)
|
|
{
|
|
aPoints->Append (aPnts[i]);
|
|
}
|
|
aPoints->Append (aPnts[0]);
|
|
theSeqLines.Append (aPoints);
|
|
}
|
|
{
|
|
Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt();
|
|
for (Standard_Integer i = 4; i < 8; i++)
|
|
{
|
|
aPoints->Append (aPnts[i]);
|
|
}
|
|
aPoints->Append (aPnts[4]);
|
|
theSeqLines.Append (aPoints);
|
|
}
|
|
for (Standard_Integer i = 0; i < 4; i++)
|
|
{
|
|
Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt();
|
|
aPoints->Append (aPnts[i]);
|
|
aPoints->Append (aPnts[i+4]);
|
|
theSeqLines.Append (aPoints);
|
|
}
|
|
}
|
|
|
|
//! Fill in circle polylines.
|
|
static void addCircle (Prs3d_NListOfSequenceOfPnt& theSeqLines,
|
|
const Standard_Real theRadius,
|
|
const gp_Trsf& theTrsf,
|
|
const Standard_Real theHeight = 0)
|
|
{
|
|
const Standard_Real anUStep = 0.1;
|
|
gp_XYZ aVec (0, 0, theHeight);
|
|
|
|
Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt();
|
|
Geom_Circle aGeom (gp_Ax2(), theRadius);
|
|
for (Standard_Real anU = 0.0f; anU < (2.0 * M_PI + anUStep); anU += anUStep)
|
|
{
|
|
gp_Pnt aCircPnt = aGeom.Value (anU).Coord() + aVec;
|
|
aCircPnt.Transform (theTrsf);
|
|
aPoints->Append (aCircPnt);
|
|
}
|
|
theSeqLines.Append (aPoints);
|
|
}
|
|
|
|
//! Fill in cylinder polylines.
|
|
static void addCylinder (Prs3d_NListOfSequenceOfPnt& theSeqLines,
|
|
const Handle(Select3D_SensitiveCylinder)& theSensCyl,
|
|
const gp_Trsf& theLoc)
|
|
{
|
|
Handle(TColgp_HSequenceOfPnt) aVertLine1 = new TColgp_HSequenceOfPnt();
|
|
Handle(TColgp_HSequenceOfPnt) aVertLine2 = new TColgp_HSequenceOfPnt();
|
|
|
|
const gp_Trsf& aTrsf = theLoc.Multiplied (theSensCyl->Transformation());
|
|
const Standard_Real aHeight = theSensCyl->Height();
|
|
|
|
for (int aCircNum = 0; aCircNum < 3; aCircNum++)
|
|
{
|
|
Standard_Real aRadius = 0.5 * (2 - aCircNum) * theSensCyl->BottomRadius()
|
|
+ 0.5 * aCircNum * theSensCyl->TopRadius();
|
|
const gp_XYZ aVec (0, 0, aHeight * 0.5 * aCircNum);
|
|
|
|
if (aCircNum != 1)
|
|
{
|
|
aVertLine1->Append (gp_Pnt (gp_XYZ (aRadius, 0, 0) + aVec).Transformed (aTrsf));
|
|
aVertLine2->Append (gp_Pnt (gp_XYZ (-aRadius, 0, 0) + aVec).Transformed (aTrsf));
|
|
}
|
|
|
|
if (aRadius > Precision::Confusion())
|
|
{
|
|
addCircle (theSeqLines, aRadius, aTrsf, aVec.Z());
|
|
}
|
|
}
|
|
theSeqLines.Append (aVertLine1);
|
|
theSeqLines.Append (aVertLine2);
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : ComputeSensitivePrs
|
|
//purpose :
|
|
//=======================================================================
|
|
void SelectMgr::ComputeSensitivePrs (const Handle(Graphic3d_Structure)& thePrs,
|
|
const Handle(SelectMgr_Selection)& theSel,
|
|
const gp_Trsf& theLoc,
|
|
const Handle(Graphic3d_TransformPers)& theTrsfPers)
|
|
{
|
|
thePrs->SetTransformPersistence (theTrsfPers);
|
|
|
|
Prs3d_NListOfSequenceOfPnt aSeqLines, aSeqFree;
|
|
TColgp_SequenceOfPnt aSeqPoints;
|
|
for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (theSel->Entities()); aSelEntIter.More(); aSelEntIter.Next())
|
|
{
|
|
const Handle(Select3D_SensitiveEntity)& anEnt = aSelEntIter.Value()->BaseSensitive();
|
|
if (Handle(Select3D_SensitiveBox) aSensBox = Handle(Select3D_SensitiveBox)::DownCast (anEnt))
|
|
{
|
|
addBoundingBox (aSeqLines, aSensBox, theLoc);
|
|
}
|
|
else if (Handle(Select3D_SensitiveCylinder) aSensCyl = Handle(Select3D_SensitiveCylinder)::DownCast (anEnt))
|
|
{
|
|
addCylinder (aSeqLines, aSensCyl, theLoc);
|
|
}
|
|
else if (Handle(Select3D_SensitiveCircle) aSensCircle = Handle(Select3D_SensitiveCircle)::DownCast (anEnt))
|
|
{
|
|
addCircle (aSeqLines, aSensCircle->Radius(), theLoc.Multiplied (aSensCircle->Transformation()));
|
|
}
|
|
else if (Handle(Select3D_SensitiveFace) aFace = Handle(Select3D_SensitiveFace)::DownCast(anEnt))
|
|
{
|
|
Handle(TColgp_HArray1OfPnt) aSensPnts;
|
|
aFace->GetPoints (aSensPnts);
|
|
Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt();
|
|
for (TColgp_HArray1OfPnt::Iterator aPntIter (*aSensPnts); aPntIter.More(); aPntIter.Next())
|
|
{
|
|
aPoints->Append (aPntIter.Value().Transformed (theLoc));
|
|
}
|
|
aSeqLines.Append (aPoints);
|
|
}
|
|
else if (Handle(Select3D_SensitivePoly) aSensPoly = Handle(Select3D_SensitivePoly)::DownCast (anEnt))
|
|
{
|
|
Standard_Integer aFrom = 0, aTo = 0;
|
|
aSensPoly->ArrayBounds (aFrom, aTo);
|
|
Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt();
|
|
for (Standard_Integer aPntIter = aFrom; aPntIter <= aTo; ++aPntIter)
|
|
{
|
|
aPoints->Append (aSensPoly->GetPoint3d (aPntIter).Transformed (theLoc));
|
|
}
|
|
aSeqLines.Append (aPoints);
|
|
}
|
|
else if (Handle(Select3D_SensitiveWire) aWire = Handle(Select3D_SensitiveWire)::DownCast(anEnt))
|
|
{
|
|
const NCollection_Vector<Handle(Select3D_SensitiveEntity)>& anEntities = aWire->GetEdges();
|
|
for (NCollection_Vector<Handle(Select3D_SensitiveEntity)>::Iterator aSubIter (anEntities); aSubIter.More(); aSubIter.Next())
|
|
{
|
|
const Handle(Select3D_SensitiveEntity)& aSubEnt = aSubIter.Value();
|
|
if (Handle(Select3D_SensitiveSegment) aSensSeg = Handle(Select3D_SensitiveSegment)::DownCast (aSubEnt))
|
|
{
|
|
Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt();
|
|
aPoints->Append (aSensSeg->StartPoint().Transformed (theLoc));
|
|
aPoints->Append (aSensSeg->EndPoint() .Transformed (theLoc));
|
|
aSeqLines.Append (aPoints);
|
|
}
|
|
else if (Handle(Select3D_SensitivePoly) aSubSensPoly = Handle(Select3D_SensitivePoly)::DownCast (aSubEnt))
|
|
{
|
|
Standard_Integer aFrom = 0, aTo = 0;
|
|
aSubSensPoly->ArrayBounds (aFrom, aTo);
|
|
Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt();
|
|
for (Standard_Integer aPntIter = aFrom; aPntIter <= aTo; ++aPntIter)
|
|
{
|
|
aPoints->Append (aSubSensPoly->GetPoint3d (aPntIter).Transformed (theLoc));
|
|
}
|
|
aSeqLines.Append (aPoints);
|
|
}
|
|
}
|
|
}
|
|
else if (Handle(Select3D_SensitiveSegment) aSensSeg = Handle(Select3D_SensitiveSegment)::DownCast(anEnt))
|
|
{
|
|
Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt();
|
|
aPoints->Append (aSensSeg->StartPoint().Transformed (theLoc));
|
|
aPoints->Append (aSensSeg->EndPoint() .Transformed (theLoc));
|
|
aSeqLines.Append (aPoints);
|
|
}
|
|
else if (Handle(Select3D_SensitivePoint) aSensPnt = Handle(Select3D_SensitivePoint)::DownCast(anEnt))
|
|
{
|
|
aSeqPoints.Append (aSensPnt->Point().Transformed (theLoc));
|
|
}
|
|
else if (Handle(Select3D_SensitiveTriangulation) aSensTri = Handle(Select3D_SensitiveTriangulation)::DownCast (anEnt))
|
|
{
|
|
addTriangulation (aSeqLines, aSeqFree, aSensTri, theLoc);
|
|
}
|
|
else if (Handle(Select3D_SensitiveTriangle) aSensTri1 = Handle(Select3D_SensitiveTriangle)::DownCast(anEnt))
|
|
{
|
|
gp_Pnt aPnts[3];
|
|
aSensTri1->Points3D (aPnts[0], aPnts[1], aPnts[2]);
|
|
aPnts[0].Transform (theLoc);
|
|
aPnts[1].Transform (theLoc);
|
|
aPnts[2].Transform (theLoc);
|
|
aSeqLines.Append (shrunkTriangle (aPnts, aSensTri1->Center3D().XYZ()));
|
|
}
|
|
}
|
|
|
|
if (!aSeqPoints.IsEmpty())
|
|
{
|
|
Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints = new Graphic3d_ArrayOfPoints (aSeqPoints.Size());
|
|
for (TColgp_SequenceOfPnt::Iterator aPntIter (aSeqPoints); aPntIter.More(); aPntIter.Next())
|
|
{
|
|
anArrayOfPoints->AddVertex (aPntIter.Value());
|
|
}
|
|
|
|
Handle(Graphic3d_Group) aSensPntGroup = thePrs->NewGroup();
|
|
aSensPntGroup->SetPrimitivesAspect (new Graphic3d_AspectMarker3d (Aspect_TOM_O_PLUS, Quantity_NOC_INDIANRED3, 2.0));
|
|
aSensPntGroup->AddPrimitiveArray (anArrayOfPoints);
|
|
}
|
|
if (!aSeqLines.IsEmpty())
|
|
{
|
|
Prs3d::AddPrimitivesGroup (thePrs, new Prs3d_LineAspect (Quantity_NOC_AQUAMARINE1, Aspect_TOL_DASH, 1.0), aSeqLines);
|
|
}
|
|
if (!aSeqFree.IsEmpty())
|
|
{
|
|
Prs3d::AddPrimitivesGroup (thePrs, new Prs3d_LineAspect (Quantity_NOC_GREEN, Aspect_TOL_SOLID, 2.0), aSeqFree);
|
|
}
|
|
}
|