mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-02 17:46:22 +03:00
Added Qt sample OCCTOverview providing examples of use of OCCT API with relevant code and demonstration of results in the viewer. Off-topic: some unused images are removed from dox/introduction/images/
487 lines
16 KiB
C++
487 lines
16 KiB
C++
// Copyright (c) 2020 OPEN CASCADE SAS
|
|
//
|
|
// This file is part of the examples of the Open CASCADE Technology software library.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
// in the Software without restriction, including without limitation the rights
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in all
|
|
// copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
|
|
|
|
#include "Sample2D_Face.h"
|
|
|
|
#include <BRep_Tool.hxx>
|
|
#include <BRepAdaptor_Curve2d.hxx>
|
|
#include <GCPnts_QuasiUniformDeflection.hxx>
|
|
#include <GeomLib.hxx>
|
|
#include <Select3D_SensitiveGroup.hxx>
|
|
#include <Select3D_SensitiveCurve.hxx>
|
|
#include <SelectMgr_EntityOwner.hxx>
|
|
#include <TopExp_Explorer.hxx>
|
|
#include <TopoDS.hxx>
|
|
|
|
Sample2D_Face::Sample2D_Face (const TopoDS_Shape& theFace)
|
|
: myFORWARDColor (Quantity_NOC_BLUE1),
|
|
myREVERSEDColor (Quantity_NOC_YELLOW),
|
|
myINTERNALColor (Quantity_NOC_RED1),
|
|
myEXTERNALColor (Quantity_NOC_MAGENTA1),
|
|
myWidthIndex (1),
|
|
myTypeIndex (1),
|
|
//
|
|
myshape (theFace),
|
|
myForwardNum (0),
|
|
myReversedNum (0),
|
|
myInternalNum (0),
|
|
myExternalNum (0),
|
|
//
|
|
myForwardBounds (0),
|
|
myReversedBounds (0),
|
|
myInternalBounds (0),
|
|
myExternalBounds (0)
|
|
{
|
|
SetAutoHilight(Standard_False);
|
|
FillData(Standard_True);
|
|
}
|
|
|
|
void Sample2D_Face::DrawMarker (const Handle(Geom2d_TrimmedCurve)& theCurve,
|
|
const Handle(Prs3d_Presentation)& thePresentation)
|
|
{
|
|
Standard_Real aCenterParam = (theCurve->FirstParameter() + theCurve->LastParameter()) / 2;
|
|
gp_Pnt2d p;
|
|
gp_Vec2d v;
|
|
theCurve->D1(aCenterParam, p, v);
|
|
if (v.Magnitude() > gp::Resolution())
|
|
{
|
|
gp_Vec aDir(v.X(), v.Y(), 0.);
|
|
gp_Pnt aPoint(p.X(), p.Y(), 0.);
|
|
aDir.Normalize();
|
|
aDir.Reverse();
|
|
gp_Dir aZ(0, 0, 1);
|
|
gp_Pnt aLeft (aPoint.Translated(aDir.Rotated(gp_Ax1(aPoint, aZ), M_PI / 6) * 5));
|
|
gp_Pnt aRight(aPoint.Translated(aDir.Rotated(gp_Ax1(aPoint, aZ), M_PI * 11 / 6) * 5));
|
|
|
|
Handle(Graphic3d_ArrayOfPolylines) anArrow = new Graphic3d_ArrayOfPolylines(3);
|
|
anArrow->AddVertex(aLeft);
|
|
anArrow->AddVertex(aPoint);
|
|
anArrow->AddVertex(aRight);
|
|
|
|
thePresentation->CurrentGroup()->AddPrimitiveArray(anArrow);
|
|
}
|
|
}
|
|
|
|
void Sample2D_Face::FillData(Standard_Boolean isSizesRecompute)
|
|
{
|
|
if (myshape.IsNull() || myshape.ShapeType() != TopAbs_FACE)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Standard_Real f, l;
|
|
TopoDS_Face aFace = TopoDS::Face(myshape);
|
|
|
|
// count number of vertices and bounds in primitive arrays
|
|
if (isSizesRecompute)
|
|
{
|
|
mySeq_FORWARD.Clear();
|
|
mySeq_REVERSED.Clear();
|
|
mySeq_INTERNAL.Clear();
|
|
mySeq_EXTERNAL.Clear();
|
|
|
|
myshape.Orientation(TopAbs_FORWARD);
|
|
for (TopExp_Explorer anEdgeIter (myshape, TopAbs_EDGE); anEdgeIter.More(); anEdgeIter.Next())
|
|
{
|
|
const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Current());
|
|
BRepAdaptor_Curve2d aCurveOnEdge (anEdge, aFace);
|
|
GCPnts_QuasiUniformDeflection anEdgeDistrib(aCurveOnEdge, 1.e-2);
|
|
if (!anEdgeDistrib.IsDone())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
switch (anEdge.Orientation())
|
|
{
|
|
case TopAbs_FORWARD:
|
|
{
|
|
myForwardNum += anEdgeDistrib.NbPoints();
|
|
myForwardBounds++;
|
|
break;
|
|
}
|
|
case TopAbs_REVERSED:
|
|
{
|
|
myReversedNum += anEdgeDistrib.NbPoints();
|
|
myReversedBounds++;
|
|
break;
|
|
}
|
|
case TopAbs_INTERNAL:
|
|
{
|
|
myInternalNum += anEdgeDistrib.NbPoints();
|
|
myInternalBounds++;
|
|
break;
|
|
}
|
|
case TopAbs_EXTERNAL:
|
|
{
|
|
myExternalNum += anEdgeDistrib.NbPoints();
|
|
myExternalBounds++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
myForwardArray = new Graphic3d_ArrayOfPolylines(myForwardNum, myForwardBounds);
|
|
myReversedArray = new Graphic3d_ArrayOfPolylines(myReversedNum, myReversedBounds);
|
|
myInternalArray = new Graphic3d_ArrayOfPolylines(myInternalNum, myInternalBounds);
|
|
myExternalArray = new Graphic3d_ArrayOfPolylines(myExternalNum, myExternalBounds);
|
|
|
|
// fill primitive arrays
|
|
for (TopExp_Explorer anEdgeIter (myshape, TopAbs_EDGE); anEdgeIter.More(); anEdgeIter.Next())
|
|
{
|
|
const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Current());
|
|
const Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface (anEdge, aFace, f, l);
|
|
Handle(Geom2d_TrimmedCurve) aTrimmedCurve = new Geom2d_TrimmedCurve(aCurve, f, l);
|
|
if (!aTrimmedCurve.IsNull())
|
|
{
|
|
Handle(Geom_Curve) aCurve3d = GeomLib::To3d(gp_Ax2(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1)), aTrimmedCurve);
|
|
BRepAdaptor_Curve2d aCurveOnEdge (anEdge, aFace);
|
|
GCPnts_QuasiUniformDeflection anEdgeDistrib (aCurveOnEdge, 1.e-2);
|
|
if (!anEdgeDistrib.IsDone())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
switch (anEdge.Orientation())
|
|
{
|
|
case TopAbs_FORWARD:
|
|
{
|
|
myForwardArray->AddBound(anEdgeDistrib.NbPoints());
|
|
for (Standard_Integer i = 1; i <= anEdgeDistrib.NbPoints(); ++i)
|
|
{
|
|
myForwardArray->AddVertex(anEdgeDistrib.Value(i));
|
|
}
|
|
if (isSizesRecompute)
|
|
{
|
|
mySeq_FORWARD.Append(aCurve3d);
|
|
}
|
|
break;
|
|
}
|
|
case TopAbs_REVERSED:
|
|
{
|
|
myReversedArray->AddBound(anEdgeDistrib.NbPoints());
|
|
for (Standard_Integer i = 1; i <= anEdgeDistrib.NbPoints(); ++i)
|
|
{
|
|
myReversedArray->AddVertex(anEdgeDistrib.Value(i));
|
|
}
|
|
if (isSizesRecompute)
|
|
{
|
|
mySeq_REVERSED.Append(aCurve3d);
|
|
}
|
|
break;
|
|
}
|
|
case TopAbs_INTERNAL:
|
|
{
|
|
myInternalArray->AddBound(anEdgeDistrib.NbPoints());
|
|
for (Standard_Integer i = 1; i <= anEdgeDistrib.NbPoints(); ++i)
|
|
{
|
|
myInternalArray->AddVertex(anEdgeDistrib.Value(i));
|
|
}
|
|
if (isSizesRecompute)
|
|
{
|
|
mySeq_INTERNAL.Append(aCurve3d);
|
|
}
|
|
break;
|
|
}
|
|
case TopAbs_EXTERNAL:
|
|
{
|
|
myExternalArray->AddBound(anEdgeDistrib.NbPoints());
|
|
for (Standard_Integer i = 1; i <= anEdgeDistrib.NbPoints(); ++i)
|
|
{
|
|
myExternalArray->AddVertex(anEdgeDistrib.Value(i));
|
|
}
|
|
if (isSizesRecompute)
|
|
{
|
|
mySeq_EXTERNAL.Append(aCurve3d);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Sample2D_Face::Compute (const Handle(PrsMgr_PresentationManager3d)& ,
|
|
const Handle(Prs3d_Presentation)& thePresentation,
|
|
const Standard_Integer theMode)
|
|
{
|
|
if (theMode != 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
thePresentation->Clear();
|
|
myDrawer->SetWireDraw(1);
|
|
|
|
if (myshape.IsNull() || myshape.ShapeType() != TopAbs_FACE)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Handle(Graphic3d_AspectLine3d) aLineAspect_FORWARD = new Graphic3d_AspectLine3d(myFORWARDColor, Aspect_TOL_SOLID, 1);
|
|
Handle(Graphic3d_AspectLine3d) aLineAspect_REVERSED = new Graphic3d_AspectLine3d(myREVERSEDColor, Aspect_TOL_SOLID, 1);
|
|
Handle(Graphic3d_AspectLine3d) aLineAspect_INTERNAL = new Graphic3d_AspectLine3d(myINTERNALColor, Aspect_TOL_SOLID, 1);
|
|
Handle(Graphic3d_AspectLine3d) aLineAspect_EXTERNAL = new Graphic3d_AspectLine3d(myEXTERNALColor, Aspect_TOL_SOLID, 1);
|
|
|
|
Standard_Real f, l;
|
|
TopoDS_Face aFace = TopoDS::Face(myshape);
|
|
// estimating number of vertices in primitive arrays
|
|
for (TopExp_Explorer anEdgeIter (myshape, TopAbs_EDGE); anEdgeIter.More(); anEdgeIter.Next())
|
|
{
|
|
const TopoDS_Edge& anEdge = TopoDS::Edge(anEdgeIter.Current());
|
|
const Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface (anEdge, aFace, f, l);
|
|
|
|
Handle(Geom2d_TrimmedCurve) aTrimmedCurve = new Geom2d_TrimmedCurve(aCurve, f, l);
|
|
// make a 3D curve from 2D trimmed curve to display it
|
|
Handle(Geom_Curve) aCurve3d = GeomLib::To3d(gp_Ax2(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1)), aTrimmedCurve);
|
|
// make distribution of points
|
|
BRepAdaptor_Curve2d aCurveOnEdge (anEdge, aFace);
|
|
GCPnts_QuasiUniformDeflection anEdgeDistrib(aCurveOnEdge, 1.e-2);
|
|
if (anEdgeDistrib.IsDone())
|
|
{
|
|
switch (anEdge.Orientation())
|
|
{
|
|
case TopAbs_FORWARD:
|
|
{
|
|
thePresentation->CurrentGroup()->SetPrimitivesAspect(aLineAspect_FORWARD);
|
|
DrawMarker(aTrimmedCurve, thePresentation);
|
|
break;
|
|
}
|
|
case TopAbs_REVERSED:
|
|
{
|
|
thePresentation->CurrentGroup()->SetPrimitivesAspect(aLineAspect_REVERSED);
|
|
DrawMarker(aTrimmedCurve, thePresentation);
|
|
break;
|
|
}
|
|
case TopAbs_INTERNAL:
|
|
{
|
|
thePresentation->CurrentGroup()->SetPrimitivesAspect(aLineAspect_INTERNAL);
|
|
DrawMarker(aTrimmedCurve, thePresentation);
|
|
|
|
mySeq_INTERNAL.Append(aCurve3d);
|
|
break;
|
|
}
|
|
case TopAbs_EXTERNAL:
|
|
{
|
|
thePresentation->CurrentGroup()->SetPrimitivesAspect(aLineAspect_EXTERNAL);
|
|
DrawMarker(aTrimmedCurve, thePresentation);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// add all primitives to the presentation
|
|
thePresentation->CurrentGroup()->SetPrimitivesAspect(aLineAspect_FORWARD);
|
|
thePresentation->CurrentGroup()->AddPrimitiveArray(myForwardArray);
|
|
|
|
thePresentation->CurrentGroup()->SetPrimitivesAspect(aLineAspect_REVERSED);
|
|
thePresentation->CurrentGroup()->AddPrimitiveArray(myReversedArray);
|
|
|
|
thePresentation->CurrentGroup()->SetPrimitivesAspect(aLineAspect_INTERNAL);
|
|
thePresentation->CurrentGroup()->AddPrimitiveArray(myInternalArray);
|
|
|
|
thePresentation->CurrentGroup()->SetPrimitivesAspect(aLineAspect_EXTERNAL);
|
|
thePresentation->CurrentGroup()->AddPrimitiveArray(myExternalArray);
|
|
}
|
|
|
|
void Sample2D_Face::HilightSelected (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
|
|
const SelectMgr_SequenceOfOwner& theOwners)
|
|
{
|
|
Handle(Prs3d_Presentation) aSelectionPrs = GetSelectPresentation (thePrsMgr);
|
|
|
|
Handle(Graphic3d_AspectLine3d) aLineAspect = new Graphic3d_AspectLine3d(Quantity_NOC_ANTIQUEWHITE, Aspect_TOL_SOLID, 2);
|
|
if (HasPresentation())
|
|
{
|
|
aSelectionPrs->SetTransformPersistence(Presentation()->TransformPersistence());
|
|
}
|
|
|
|
const Standard_Integer aLength = theOwners.Length();
|
|
aSelectionPrs->Clear();
|
|
FillData();
|
|
|
|
Handle(Graphic3d_Group) aSelectGroup = aSelectionPrs->NewGroup();
|
|
|
|
for (Standard_Integer i = 1; i <= aLength; ++i)
|
|
{
|
|
Handle(SelectMgr_EntityOwner) anOwner = theOwners.Value(i);
|
|
// check priority of owner to add primitives in one of array
|
|
// containing primitives with certain type of orientation
|
|
switch (anOwner->Priority())
|
|
{
|
|
case 7:
|
|
{
|
|
// add to objects with forward orientation
|
|
aSelectGroup->SetGroupPrimitivesAspect(aLineAspect);
|
|
aSelectGroup->AddPrimitiveArray(myForwardArray);
|
|
break;
|
|
}
|
|
case 6:
|
|
{
|
|
// add to objects with reversed orientation
|
|
aSelectGroup->SetGroupPrimitivesAspect(aLineAspect);
|
|
aSelectGroup->AddPrimitiveArray(myReversedArray);
|
|
break;
|
|
}
|
|
case 5:
|
|
{
|
|
// add to objects with internal orientation
|
|
aSelectGroup->SetGroupPrimitivesAspect(aLineAspect);
|
|
aSelectGroup->AddPrimitiveArray(myInternalArray);
|
|
break;
|
|
}
|
|
case 4:
|
|
{
|
|
// add to objects with external orientation
|
|
aSelectGroup->SetGroupPrimitivesAspect(aLineAspect);
|
|
aSelectGroup->AddPrimitiveArray(myExternalArray);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
aSelectionPrs->Display();
|
|
}
|
|
|
|
void Sample2D_Face::ClearSelected()
|
|
{
|
|
if (Handle(Prs3d_Presentation) aSelectionPrs = GetSelectPresentation(NULL))
|
|
{
|
|
aSelectionPrs->Clear();
|
|
}
|
|
}
|
|
|
|
void Sample2D_Face::HilightOwnerWithColor (const Handle(PrsMgr_PresentationManager3d)& thePM,
|
|
const Handle(Prs3d_Drawer)& theStyle,
|
|
const Handle(SelectMgr_EntityOwner)& theOwner)
|
|
{
|
|
Handle(Prs3d_Presentation) aHighlightPrs = GetHilightPresentation(thePM);
|
|
if (HasPresentation())
|
|
{
|
|
aHighlightPrs->SetTransformPersistence(Presentation()->TransformPersistence());
|
|
}
|
|
if (theOwner.IsNull())
|
|
{
|
|
return;
|
|
}
|
|
|
|
aHighlightPrs->Clear();
|
|
FillData();
|
|
|
|
// Direct highlighting
|
|
aHighlightPrs->NewGroup();
|
|
Handle(Graphic3d_Group) aHilightGroup = aHighlightPrs->CurrentGroup();
|
|
Handle(Graphic3d_AspectLine3d) aLineAspect = new Graphic3d_AspectLine3d(theStyle->Color(), Aspect_TOL_SOLID, 2);
|
|
switch (theOwner->Priority())
|
|
{
|
|
case 7:
|
|
{
|
|
aHilightGroup->SetGroupPrimitivesAspect(aLineAspect);
|
|
aHilightGroup->AddPrimitiveArray(myForwardArray);
|
|
break;
|
|
}
|
|
case 6:
|
|
{
|
|
aHilightGroup->SetGroupPrimitivesAspect(aLineAspect);
|
|
aHilightGroup->AddPrimitiveArray(myReversedArray);
|
|
break;
|
|
}
|
|
case 5:
|
|
{
|
|
aHilightGroup->SetGroupPrimitivesAspect(aLineAspect);
|
|
aHilightGroup->AddPrimitiveArray(myInternalArray);
|
|
break;
|
|
}
|
|
case 4:
|
|
{
|
|
aHilightGroup->SetGroupPrimitivesAspect(aLineAspect);
|
|
aHilightGroup->AddPrimitiveArray(myExternalArray);
|
|
break;
|
|
}
|
|
}
|
|
if (thePM->IsImmediateModeOn())
|
|
{
|
|
thePM->AddToImmediateList(aHighlightPrs);
|
|
}
|
|
}
|
|
|
|
void Sample2D_Face::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
|
|
const Standard_Integer theMode)
|
|
{
|
|
if (myshape.IsNull()
|
|
|| theMode != 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (mySeq_FORWARD.IsEmpty()
|
|
&& mySeq_REVERSED.IsEmpty()
|
|
&& mySeq_INTERNAL.IsEmpty()
|
|
&& mySeq_EXTERNAL.IsEmpty())
|
|
{
|
|
return;
|
|
}
|
|
|
|
// create entity owner for every part of the face
|
|
// set different priorities for primitives of different orientation
|
|
Handle(SelectMgr_EntityOwner) anOwner_Forward = new SelectMgr_EntityOwner(this, 7);
|
|
Handle(SelectMgr_EntityOwner) anOwner_Reversed = new SelectMgr_EntityOwner(this, 6);
|
|
Handle(SelectMgr_EntityOwner) anOwner_Internal = new SelectMgr_EntityOwner(this, 5);
|
|
Handle(SelectMgr_EntityOwner) anOwner_External = new SelectMgr_EntityOwner(this, 4);
|
|
|
|
// create a sensitive for every part
|
|
Handle(Select3D_SensitiveGroup) aForwardGroup = new Select3D_SensitiveGroup(anOwner_Forward);
|
|
Handle(Select3D_SensitiveGroup) aReversedGroup = new Select3D_SensitiveGroup(anOwner_Reversed);
|
|
Handle(Select3D_SensitiveGroup) aInternalGroup = new Select3D_SensitiveGroup(anOwner_Internal);
|
|
Handle(Select3D_SensitiveGroup) aExternalGroup = new Select3D_SensitiveGroup(anOwner_External);
|
|
|
|
Standard_Integer aLength = mySeq_FORWARD.Length();
|
|
for (Standard_Integer i = 1; i <= aLength; ++i)
|
|
{
|
|
Handle(Select3D_SensitiveCurve) aSensitveCurve = new Select3D_SensitiveCurve(anOwner_Forward, mySeq_FORWARD(i));
|
|
aForwardGroup->Add(aSensitveCurve);
|
|
}
|
|
theSelection->Add(aForwardGroup);
|
|
|
|
aLength = mySeq_REVERSED.Length();
|
|
for (Standard_Integer i = 1; i <= aLength; ++i)
|
|
{
|
|
Handle(Select3D_SensitiveCurve) aSensitveCurve = new Select3D_SensitiveCurve(anOwner_Reversed, mySeq_REVERSED(i));
|
|
aReversedGroup->Add(aSensitveCurve);
|
|
}
|
|
theSelection->Add(aReversedGroup);
|
|
|
|
aLength = mySeq_INTERNAL.Length();
|
|
for (Standard_Integer i = 1; i <= aLength; ++i)
|
|
{
|
|
Handle(Select3D_SensitiveCurve) aSensitveCurve = new Select3D_SensitiveCurve(anOwner_Internal, mySeq_INTERNAL(i));
|
|
aInternalGroup->Add(aSensitveCurve);
|
|
}
|
|
theSelection->Add(aInternalGroup);
|
|
|
|
aLength = mySeq_EXTERNAL.Length();
|
|
for (Standard_Integer i = 1; i <= aLength; ++i)
|
|
{
|
|
Handle(Select3D_SensitiveCurve) aSensitveCurve = new Select3D_SensitiveCurve(anOwner_External, mySeq_EXTERNAL(i));
|
|
aExternalGroup->Add(aSensitveCurve);
|
|
}
|
|
theSelection->Add(aExternalGroup);
|
|
}
|