mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
Compare commits
1 Commits
CR30952_2
...
CR0_IntSeg
Author | SHA1 | Date | |
---|---|---|---|
|
cb2e41f927 |
@@ -2434,8 +2434,9 @@ BRepMesh_GeomTool::IntFlag BRepMesh_Delaun::intSegSeg(
|
||||
p3 = GetVertex( theEdg2.FirstNode() ).Coord();
|
||||
p4 = GetVertex( theEdg2.LastNode() ).Coord();
|
||||
|
||||
Standard_Real aIntParams[2];
|
||||
return BRepMesh_GeomTool::IntSegSeg(p1, p2, p3, p4,
|
||||
isConsiderEndPointTouch, isConsiderPointOnEdge, theIntPnt);
|
||||
isConsiderEndPointTouch, isConsiderPointOnEdge, theIntPnt, aIntParams);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
@@ -19,191 +19,6 @@
|
||||
#include <OSD_Parallel.hxx>
|
||||
#include <BRepMesh_GeomTool.hxx>
|
||||
|
||||
namespace
|
||||
{
|
||||
const Standard_Real MaxTangentAngle = 5. * M_PI / 180.;
|
||||
|
||||
//! Functor to be used to fill segments and bounding box tree in parallel.
|
||||
class SegmentsFiller
|
||||
{
|
||||
public:
|
||||
//! Constructor.
|
||||
SegmentsFiller(const IMeshData::IFaceHandle& theDFace,
|
||||
Handle(BRepMesh_FaceChecker::ArrayOfSegments)& theWiresSegments,
|
||||
Handle(BRepMesh_FaceChecker::ArrayOfBndBoxTree)& theWiresBndBoxTree)
|
||||
: myDFace(theDFace),
|
||||
myWiresSegments(theWiresSegments),
|
||||
myWiresBndBoxTree(theWiresBndBoxTree)
|
||||
{
|
||||
myWiresSegments = new BRepMesh_FaceChecker::ArrayOfSegments (0, myDFace->WiresNb() - 1);
|
||||
myWiresBndBoxTree = new BRepMesh_FaceChecker::ArrayOfBndBoxTree (0, myDFace->WiresNb() - 1);
|
||||
}
|
||||
|
||||
//! Performs initialization of wire with the given index.
|
||||
void operator()(const Standard_Integer theWireIndex) const
|
||||
{
|
||||
const IMeshData::IWireHandle& aDWire = myDFace->GetWire(theWireIndex);
|
||||
|
||||
Handle(NCollection_IncAllocator) aTmpAlloc1 = new NCollection_IncAllocator();
|
||||
|
||||
Handle(BRepMesh_FaceChecker::Segments) aSegments =
|
||||
new BRepMesh_FaceChecker::Segments(aDWire->EdgesNb(), aTmpAlloc1);
|
||||
Handle(IMeshData::BndBox2dTree) aBndBoxTree = new IMeshData::BndBox2dTree(aTmpAlloc1);
|
||||
|
||||
myWiresSegments ->ChangeValue(theWireIndex) = aSegments;
|
||||
myWiresBndBoxTree->ChangeValue(theWireIndex) = aBndBoxTree;
|
||||
|
||||
Handle(NCollection_IncAllocator) aTmpAlloc2 = new NCollection_IncAllocator();
|
||||
IMeshData::BndBox2dTreeFiller aBndBoxTreeFiller(*aBndBoxTree, aTmpAlloc2);
|
||||
|
||||
for (Standard_Integer aEdgeIt = 0; aEdgeIt < aDWire->EdgesNb(); ++aEdgeIt)
|
||||
{
|
||||
// TODO: check 2d wire for consistency.
|
||||
|
||||
const IMeshData::IEdgePtr& aDEdge = aDWire->GetEdge(aEdgeIt);
|
||||
const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve(myDFace.get(), aDWire->GetEdgeOrientation(aEdgeIt));
|
||||
|
||||
for (Standard_Integer aPointIt = 1; aPointIt < aPCurve->ParametersNb(); ++aPointIt)
|
||||
{
|
||||
gp_Pnt2d& aPnt1 = aPCurve->GetPoint(aPointIt - 1);
|
||||
gp_Pnt2d& aPnt2 = aPCurve->GetPoint(aPointIt);
|
||||
|
||||
Bnd_Box2d aBox;
|
||||
aBox.Add(aPnt1);
|
||||
aBox.Add(aPnt2);
|
||||
aBox.Enlarge(Precision::Confusion());
|
||||
|
||||
aBndBoxTreeFiller.Add(aSegments->Size(), aBox);
|
||||
aSegments->Append(BRepMesh_FaceChecker::Segment(aDEdge, &aPnt1, &aPnt2));
|
||||
}
|
||||
}
|
||||
|
||||
aBndBoxTreeFiller.Fill();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
SegmentsFiller (const SegmentsFiller& theOther);
|
||||
|
||||
void operator=(const SegmentsFiller& theOther);
|
||||
|
||||
private:
|
||||
|
||||
const IMeshData::IFaceHandle& myDFace;
|
||||
Handle(BRepMesh_FaceChecker::ArrayOfSegments)& myWiresSegments;
|
||||
Handle(BRepMesh_FaceChecker::ArrayOfBndBoxTree)& myWiresBndBoxTree;
|
||||
};
|
||||
|
||||
//! Selector.
|
||||
//! Used to identify segments with overlapped bounding boxes.
|
||||
class BndBox2dTreeSelector : public IMeshData::BndBox2dTree::Selector
|
||||
{
|
||||
public:
|
||||
//! Constructor.
|
||||
BndBox2dTreeSelector(const Standard_Real theTolerance)
|
||||
: myMaxLoopSize(M_PI * theTolerance * theTolerance),
|
||||
mySelfSegmentIndex(-1),
|
||||
myIndices(256, new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE))
|
||||
{
|
||||
}
|
||||
|
||||
//! Sets working set of segments.
|
||||
void SetSegments(const Handle(BRepMesh_FaceChecker::Segments)& theSegments)
|
||||
{
|
||||
mySegments = theSegments;
|
||||
}
|
||||
|
||||
//! Resets current selector.
|
||||
void Reset(const BRepMesh_FaceChecker::Segment* theSegment,
|
||||
const Standard_Integer theSelfSegmentIndex)
|
||||
{
|
||||
myIndices.Clear();
|
||||
|
||||
mySelfSegmentIndex = theSelfSegmentIndex;
|
||||
mySegment = theSegment;
|
||||
|
||||
myBox.SetVoid();
|
||||
myBox.Add(*mySegment->Point1);
|
||||
myBox.Add(*mySegment->Point2);
|
||||
myBox.Enlarge(Precision::Confusion());
|
||||
}
|
||||
|
||||
//! Indicates should the given box be rejected or not.
|
||||
virtual Standard_Boolean Reject(const Bnd_Box2d& theBox) const
|
||||
{
|
||||
return myBox.IsOut(theBox);
|
||||
}
|
||||
|
||||
//! Accepts segment with the given index in case if it fits conditions.
|
||||
virtual Standard_Boolean Accept(const Standard_Integer& theSegmentIndex)
|
||||
{
|
||||
const BRepMesh_FaceChecker::Segment& aSegment = mySegments->Value(theSegmentIndex);
|
||||
|
||||
gp_Pnt2d aIntPnt;
|
||||
const BRepMesh_GeomTool::IntFlag aIntStatus = BRepMesh_GeomTool::IntSegSeg(
|
||||
mySegment->Point1->XY(), mySegment->Point2->XY(),
|
||||
aSegment.Point1->XY(), aSegment.Point2->XY(),
|
||||
Standard_False, Standard_False, aIntPnt);
|
||||
|
||||
if (aIntStatus == BRepMesh_GeomTool::Cross)
|
||||
{
|
||||
const Standard_Real aAngle = gp_Vec2d(mySegment->Point1->XY(), mySegment->Point2->XY()).Angle(
|
||||
gp_Vec2d(aSegment.Point1->XY(), aSegment.Point2->XY()));
|
||||
|
||||
if (Abs(aAngle) < MaxTangentAngle)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
if (mySelfSegmentIndex != -1)
|
||||
{
|
||||
gp_XY aPrevVec;
|
||||
Standard_Real aSumS = 0.;
|
||||
const gp_XY& aRefPnt = aIntPnt.Coord();
|
||||
for (Standard_Integer i = mySelfSegmentIndex; i < theSegmentIndex; ++i)
|
||||
{
|
||||
const BRepMesh_FaceChecker::Segment& aCurrSegment = mySegments->Value(i);
|
||||
gp_XY aCurVec = aCurrSegment.Point2->XY() - aRefPnt;
|
||||
|
||||
if (aCurVec.SquareModulus() < gp::Resolution())
|
||||
continue;
|
||||
|
||||
if (aPrevVec.SquareModulus() > gp::Resolution())
|
||||
aSumS += aPrevVec ^ aCurVec;
|
||||
|
||||
aPrevVec = aCurVec;
|
||||
}
|
||||
|
||||
if (Abs(aSumS / 2.) < myMaxLoopSize)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
|
||||
myIndices.Append(theSegmentIndex);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
//! Returns indices of intersecting segments.
|
||||
const IMeshData::VectorOfInteger& Indices() const
|
||||
{
|
||||
return myIndices;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Standard_Real myMaxLoopSize;
|
||||
Standard_Integer mySelfSegmentIndex;
|
||||
Handle(BRepMesh_FaceChecker::Segments) mySegments;
|
||||
const BRepMesh_FaceChecker::Segment* mySegment;
|
||||
Bnd_Box2d myBox;
|
||||
IMeshData::VectorOfInteger myIndices;
|
||||
};
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Constructor
|
||||
//purpose :
|
||||
@@ -211,8 +26,7 @@ namespace
|
||||
BRepMesh_FaceChecker::BRepMesh_FaceChecker(
|
||||
const IMeshData::IFaceHandle& theFace,
|
||||
const IMeshTools_Parameters& theParameters)
|
||||
: myDFace(theFace),
|
||||
myParameters(theParameters)
|
||||
: BRepMesh_SegmentedFace (theFace, theParameters)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -230,50 +44,39 @@ BRepMesh_FaceChecker::~BRepMesh_FaceChecker()
|
||||
//=======================================================================
|
||||
Standard_Boolean BRepMesh_FaceChecker::Perform()
|
||||
{
|
||||
myIntersectingEdges = new IMeshData::MapOfIEdgePtr;
|
||||
collectSegments();
|
||||
|
||||
myIntersectingEdges = new IMeshData::MapOfIEdgePtr;
|
||||
myWiresIntersectingEdges = new ArrayOfMapOfIEdgePtr(0, myDFace->WiresNb() - 1);
|
||||
|
||||
OSD_Parallel::For(0, myDFace->WiresNb(), *this, !isParallel());
|
||||
collectResult();
|
||||
|
||||
myWiresBndBoxTree.Nullify();
|
||||
myWiresSegments.Nullify();
|
||||
myWiresBndBoxTree .Nullify();
|
||||
myWiresSegments .Nullify();
|
||||
myWiresIntersectingEdges.Nullify();
|
||||
return myIntersectingEdges->IsEmpty();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : collectSegments
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_FaceChecker::collectSegments()
|
||||
{
|
||||
SegmentsFiller aSegmentsFiller(myDFace, myWiresSegments, myWiresBndBoxTree);
|
||||
OSD_Parallel::For(0, myDFace->WiresNb(), aSegmentsFiller, !isParallel());
|
||||
|
||||
myWiresIntersectingEdges = new ArrayOfMapOfIEdgePtr(0, myDFace->WiresNb() - 1);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_FaceChecker::perform(const Standard_Integer theWireIndex) const
|
||||
{
|
||||
const Handle(Segments)& aSegments1 = myWiresSegments->Value(theWireIndex);
|
||||
const Handle(Segments)& aSegments1 = myWiresSegments ->Value (theWireIndex);
|
||||
Handle(IMeshData::MapOfIEdgePtr)& aIntersections = myWiresIntersectingEdges->ChangeValue(theWireIndex);
|
||||
|
||||
// TODO: Tolerance is set to twice value of face deflection in order to fit regressions.
|
||||
BndBox2dTreeSelector aSelector(2 * myDFace->GetDeflection());
|
||||
BRepMesh_SegmentedFace::BndBox2dTreeSelector aSelector (Standard_False);
|
||||
for (Standard_Integer aWireIt = theWireIndex; aWireIt < myDFace->WiresNb(); ++aWireIt)
|
||||
{
|
||||
const Handle(IMeshData::BndBox2dTree)& aBndBoxTree2 = myWiresBndBoxTree->Value(aWireIt);
|
||||
const Handle(Segments)& aSegments2 = myWiresSegments->Value(aWireIt);
|
||||
const Handle(Segments)& aSegments2 = myWiresSegments ->Value(aWireIt);
|
||||
|
||||
aSelector.SetSegments(aSegments2);
|
||||
for (Standard_Integer aSegmentIt = 0; aSegmentIt < aSegments1->Size(); ++aSegmentIt)
|
||||
{
|
||||
const BRepMesh_FaceChecker::Segment& aSegment1 = aSegments1->Value(aSegmentIt);
|
||||
const BRepMesh_SegmentedFace::Segment& aSegment1 = aSegments1->Value(aSegmentIt);
|
||||
aSelector.Reset(&aSegment1, (aWireIt == theWireIndex) ? aSegmentIt : -1);
|
||||
if (aBndBoxTree2->Select(aSelector) != 0)
|
||||
{
|
||||
@@ -287,7 +90,7 @@ void BRepMesh_FaceChecker::perform(const Standard_Integer theWireIndex) const
|
||||
const IMeshData::VectorOfInteger& aSegments = aSelector.Indices();
|
||||
for (Standard_Integer aSelIt = 0; aSelIt < aSegments.Size(); ++aSelIt)
|
||||
{
|
||||
const BRepMesh_FaceChecker::Segment& aSegment2 = aSegments2->Value(aSegments(aSelIt));
|
||||
const BRepMesh_SegmentedFace::Segment& aSegment2 = aSegments2->Value(aSegments(aSelIt));
|
||||
aIntersections->Add(aSegment2.EdgePtr);
|
||||
}
|
||||
}
|
||||
|
@@ -16,49 +16,18 @@
|
||||
#ifndef _BRepMesh_FaceChecker_HeaderFile
|
||||
#define _BRepMesh_FaceChecker_HeaderFile
|
||||
|
||||
#include <IMeshTools_Parameters.hxx>
|
||||
#include <Standard_Transient.hxx>
|
||||
#include <IMeshData_Face.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
#include <NCollection_Shared.hxx>
|
||||
#include <BRepMesh_SegmentedFace.hxx>
|
||||
|
||||
//! Auxiliary class checking wires of target face for self-intersections.
|
||||
//! Explodes wires of discrete face on sets of segments using tessellation
|
||||
//! data stored in model. Each segment is then checked for intersection with
|
||||
//! other ones. All collisions are registerd and returned as result of check.
|
||||
class BRepMesh_FaceChecker : public Standard_Transient
|
||||
class BRepMesh_FaceChecker : public BRepMesh_SegmentedFace
|
||||
{
|
||||
public: //! @name mesher API
|
||||
|
||||
//! Identifies segment inside face.
|
||||
struct Segment
|
||||
{
|
||||
IMeshData::IEdgePtr EdgePtr;
|
||||
gp_Pnt2d* Point1; // \ Use explicit pointers to points instead of accessing
|
||||
gp_Pnt2d* Point2; // / using indices.
|
||||
|
||||
Segment()
|
||||
: Point1(NULL)
|
||||
, Point2(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
Segment(const IMeshData::IEdgePtr& theEdgePtr,
|
||||
gp_Pnt2d* thePoint1,
|
||||
gp_Pnt2d* thePoint2)
|
||||
: EdgePtr(theEdgePtr)
|
||||
, Point1(thePoint1)
|
||||
, Point2(thePoint2)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
typedef NCollection_Shared<NCollection_Vector<Segment> > Segments;
|
||||
typedef NCollection_Shared<NCollection_Array1<Handle(Segments)> > ArrayOfSegments;
|
||||
typedef NCollection_Shared<NCollection_Array1<Handle(IMeshData::BndBox2dTree)> > ArrayOfBndBoxTree;
|
||||
typedef NCollection_Shared<NCollection_Array1<Handle(IMeshData::MapOfIEdgePtr)> > ArrayOfMapOfIEdgePtr;
|
||||
|
||||
|
||||
//! Default constructor
|
||||
Standard_EXPORT BRepMesh_FaceChecker(const IMeshData::IFaceHandle& theFace,
|
||||
const IMeshTools_Parameters& theParameters);
|
||||
@@ -82,19 +51,10 @@ public: //! @name mesher API
|
||||
perform(theWireIndex);
|
||||
}
|
||||
|
||||
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_FaceChecker, Standard_Transient)
|
||||
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_FaceChecker, BRepMesh_SegmentedFace)
|
||||
|
||||
private:
|
||||
|
||||
//! Returns True in case if check can be performed in parallel mode.
|
||||
inline Standard_Boolean isParallel() const
|
||||
{
|
||||
return (myParameters.InParallel && myDFace->WiresNb() > 1);
|
||||
}
|
||||
|
||||
//! Collects face segments.
|
||||
void collectSegments();
|
||||
|
||||
//! Collects intersecting edges.
|
||||
void collectResult();
|
||||
|
||||
@@ -109,11 +69,6 @@ private:
|
||||
|
||||
private:
|
||||
|
||||
IMeshData::IFaceHandle myDFace;
|
||||
const IMeshTools_Parameters& myParameters;
|
||||
|
||||
Handle(ArrayOfSegments) myWiresSegments;
|
||||
Handle(ArrayOfBndBoxTree) myWiresBndBoxTree;
|
||||
Handle(ArrayOfMapOfIEdgePtr) myWiresIntersectingEdges;
|
||||
Handle(IMeshData::MapOfIEdgePtr) myIntersectingEdges;
|
||||
|
||||
|
100
src/BRepMesh/BRepMesh_FaceIntersectionsSplitter.cxx
Normal file
100
src/BRepMesh/BRepMesh_FaceIntersectionsSplitter.cxx
Normal file
@@ -0,0 +1,100 @@
|
||||
// Created on: 2016-07-04
|
||||
// Copyright (c) 2016 OPEN CASCADE SAS
|
||||
// Created by: Oleg AGASHIN
|
||||
//
|
||||
// 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 <BRepMesh_FaceIntersectionsSplitter.hxx>
|
||||
#include <IMeshData_Wire.hxx>
|
||||
#include <IMeshData_Edge.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : Constructor
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
BRepMesh_FaceIntersectionsSplitter::BRepMesh_FaceIntersectionsSplitter(
|
||||
const IMeshData::IFaceHandle& theFace,
|
||||
const IMeshTools_Parameters& theParameters)
|
||||
: BRepMesh_SegmentedFace (theFace, theParameters)
|
||||
{
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Destructor
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
BRepMesh_FaceIntersectionsSplitter::~BRepMesh_FaceIntersectionsSplitter()
|
||||
{
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean BRepMesh_FaceIntersectionsSplitter::Perform()
|
||||
{
|
||||
for (Standard_Integer aWireIt = 0; aWireIt < myDFace->WiresNb(); ++aWireIt)
|
||||
{
|
||||
Standard_Boolean isSplit = Standard_True;
|
||||
while (isSplit)
|
||||
{
|
||||
collectSegments();
|
||||
|
||||
isSplit = perform(aWireIt);
|
||||
|
||||
myWiresSegments .Nullify();
|
||||
myWiresBndBoxTree.Nullify();
|
||||
}
|
||||
}
|
||||
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean BRepMesh_FaceIntersectionsSplitter::perform(
|
||||
const Standard_Integer theWireIndex)
|
||||
{
|
||||
const Handle(Segments)& aSegments1 = myWiresSegments->Value (theWireIndex);
|
||||
|
||||
BRepMesh_SegmentedFace::BndBox2dTreeSelector aSelector (Standard_True);
|
||||
for (Standard_Integer aWireIt = theWireIndex; aWireIt < myDFace->WiresNb(); ++aWireIt)
|
||||
{
|
||||
const Handle(IMeshData::BndBox2dTree)& aBndBoxTree2 = myWiresBndBoxTree->Value(aWireIt);
|
||||
const Handle(Segments)& aSegments2 = myWiresSegments ->Value(aWireIt);
|
||||
|
||||
aSelector.SetSegments(aSegments2);
|
||||
for (Standard_Integer aSegmentIt = 0; aSegmentIt < aSegments1->Size(); ++aSegmentIt)
|
||||
{
|
||||
const BRepMesh_SegmentedFace::Segment& aSegment1 = aSegments1->Value(aSegmentIt);
|
||||
aSelector.Reset(&aSegment1, (aWireIt == theWireIndex) ? aSegmentIt : -1);
|
||||
if (aBndBoxTree2->Select(aSelector) != 0)
|
||||
{
|
||||
const IMeshData::VectorOfInteger& aSegments = aSelector.Indices();
|
||||
const BRepMesh_SegmentedFace::VectorOfIntersectionParams& aIntParams = aSelector.IntParams();
|
||||
for (Standard_Integer aSelIt = 0; aSelIt < aSegments.Size(); ++aSelIt)
|
||||
{
|
||||
const BRepMesh_SegmentedFace::Segment& aSegment2 = aSegments2->Value(aSegments(aSelIt));
|
||||
|
||||
//aIntersections->Add(aSegment1.EdgePtr);
|
||||
//aIntersections->Add(aSegment2.EdgePtr);
|
||||
}
|
||||
|
||||
//return Standard_False;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Standard_False;
|
||||
}
|
55
src/BRepMesh/BRepMesh_FaceIntersectionsSplitter.hxx
Normal file
55
src/BRepMesh/BRepMesh_FaceIntersectionsSplitter.hxx
Normal file
@@ -0,0 +1,55 @@
|
||||
// Created on: 2016-07-04
|
||||
// Copyright (c) 2016 OPEN CASCADE SAS
|
||||
// Created by: Oleg AGASHIN
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef _BRepMesh_FaceIntersectionsSplitter_HeaderFile
|
||||
#define _BRepMesh_FaceIntersectionsSplitter_HeaderFile
|
||||
|
||||
#include <BRepMesh_SegmentedFace.hxx>
|
||||
|
||||
//! Auxiliary class splitting intersecting segments of wires of target face.
|
||||
//! Explodes wires of discrete face on sets of segments using tessellation
|
||||
//! data stored in model. Each segment is then checked for intersection with
|
||||
//! other ones and split on intersection point.
|
||||
class BRepMesh_FaceIntersectionsSplitter : public BRepMesh_SegmentedFace
|
||||
{
|
||||
public: //! @name mesher API
|
||||
|
||||
//! Default constructor
|
||||
Standard_EXPORT BRepMesh_FaceIntersectionsSplitter(
|
||||
const IMeshData::IFaceHandle& theFace,
|
||||
const IMeshTools_Parameters& theParameters);
|
||||
|
||||
//! Destructor
|
||||
Standard_EXPORT virtual ~BRepMesh_FaceIntersectionsSplitter();
|
||||
|
||||
//! Performs split of intersecting segments of wires of the face.
|
||||
//! @return True if there is no intersection, False elsewhere.
|
||||
Standard_EXPORT Standard_Boolean Perform();
|
||||
|
||||
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_FaceIntersectionsSplitter, BRepMesh_SegmentedFace)
|
||||
|
||||
private:
|
||||
|
||||
//! Splits wire with the given index at first intersection point with others.
|
||||
Standard_Boolean perform(const Standard_Integer theWireIndex);
|
||||
|
||||
private:
|
||||
|
||||
BRepMesh_FaceIntersectionsSplitter (const BRepMesh_FaceIntersectionsSplitter& theOther);
|
||||
|
||||
void operator=(const BRepMesh_FaceIntersectionsSplitter& theOther);
|
||||
};
|
||||
|
||||
#endif
|
@@ -333,7 +333,8 @@ BRepMesh_GeomTool::IntFlag BRepMesh_GeomTool::IntSegSeg(
|
||||
const gp_XY& theEndPnt2,
|
||||
const Standard_Boolean isConsiderEndPointTouch,
|
||||
const Standard_Boolean isConsiderPointOnSegment,
|
||||
gp_Pnt2d& theIntPnt)
|
||||
gp_Pnt2d& theIntPnt,
|
||||
Standard_Real (&theParamOnSegment)[2])
|
||||
{
|
||||
Standard_Integer aPointHash[] = {
|
||||
classifyPoint(theStartPnt1, theEndPnt1, theStartPnt2),
|
||||
@@ -393,9 +394,8 @@ BRepMesh_GeomTool::IntFlag BRepMesh_GeomTool::IntSegSeg(
|
||||
else if ( aPosHash == 2 )
|
||||
return BRepMesh_GeomTool::Glued;
|
||||
|
||||
Standard_Real aParam[2];
|
||||
IntFlag aIntFlag = IntLinLin(theStartPnt1, theEndPnt1,
|
||||
theStartPnt2, theEndPnt2, theIntPnt.ChangeCoord(), aParam);
|
||||
theStartPnt2, theEndPnt2, theIntPnt.ChangeCoord(), theParamOnSegment);
|
||||
|
||||
if (aIntFlag == BRepMesh_GeomTool::NoIntersection)
|
||||
return BRepMesh_GeomTool::NoIntersection;
|
||||
@@ -416,7 +416,7 @@ BRepMesh_GeomTool::IntFlag BRepMesh_GeomTool::IntSegSeg(
|
||||
const Standard_Real aEndPrec = 1 - aPrec;
|
||||
for (Standard_Integer i = 0; i < 2; ++i)
|
||||
{
|
||||
if(aParam[i] < aPrec || aParam[i] > aEndPrec )
|
||||
if(theParamOnSegment[i] < aPrec || theParamOnSegment[i] > aEndPrec )
|
||||
return BRepMesh_GeomTool::NoIntersection;
|
||||
}
|
||||
|
||||
|
@@ -194,7 +194,8 @@ public: //! @name static API
|
||||
const gp_XY& theEndPnt2,
|
||||
const Standard_Boolean isConsiderEndPointTouch,
|
||||
const Standard_Boolean isConsiderPointOnSegment,
|
||||
gp_Pnt2d& theIntPnt);
|
||||
gp_Pnt2d& theIntPnt,
|
||||
Standard_Real (&theParamOnSegment)[2]);
|
||||
|
||||
//! Compute deflection of the given segment.
|
||||
static Standard_Real SquareDeflectionOfSegment(
|
||||
|
@@ -17,6 +17,7 @@
|
||||
#include <BRepMesh_Deflection.hxx>
|
||||
#include <BRepMesh_ShapeTool.hxx>
|
||||
#include <BRepMesh_FaceChecker.hxx>
|
||||
#include <BRepMesh_FaceIntersectionsSplitter.hxx>
|
||||
#include <BRepMesh_EdgeDiscret.hxx>
|
||||
#include <IMeshData_Face.hxx>
|
||||
#include <IMeshData_Wire.hxx>
|
||||
@@ -150,7 +151,12 @@ Standard_Boolean BRepMesh_ModelHealer::performInternal(
|
||||
{
|
||||
const IMeshData::IFaceHandle aDFace = aFaceIt.Key();
|
||||
aDFace->SetStatus(IMeshData_SelfIntersectingWire);
|
||||
aDFace->SetStatus(IMeshData_Failure);
|
||||
|
||||
BRepMesh_FaceIntersectionsSplitter aSplitter (aDFace, myParameters);
|
||||
if (!aSplitter.Perform())
|
||||
{
|
||||
aDFace->SetStatus(IMeshData_Failure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
204
src/BRepMesh/BRepMesh_SegmentedFace.cxx
Normal file
204
src/BRepMesh/BRepMesh_SegmentedFace.cxx
Normal file
@@ -0,0 +1,204 @@
|
||||
// Created on: 2016-07-04
|
||||
// Copyright (c) 2016 OPEN CASCADE SAS
|
||||
// Created by: Oleg AGASHIN
|
||||
//
|
||||
// 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 <BRepMesh_SegmentedFace.hxx>
|
||||
#include <IMeshData_Wire.hxx>
|
||||
#include <IMeshData_Edge.hxx>
|
||||
#include <OSD_Parallel.hxx>
|
||||
|
||||
namespace
|
||||
{
|
||||
//! Functor to be used to fill segments and bounding box tree in parallel.
|
||||
class SegmentsFiller
|
||||
{
|
||||
public:
|
||||
//! Constructor.
|
||||
SegmentsFiller(const IMeshData::IFaceHandle& theDFace,
|
||||
Handle(BRepMesh_SegmentedFace::ArrayOfSegments)& theWiresSegments,
|
||||
Handle(BRepMesh_SegmentedFace::ArrayOfBndBoxTree)& theWiresBndBoxTree)
|
||||
: myDFace(theDFace),
|
||||
myWiresSegments(theWiresSegments),
|
||||
myWiresBndBoxTree(theWiresBndBoxTree)
|
||||
{
|
||||
myWiresSegments = new BRepMesh_SegmentedFace::ArrayOfSegments (0, myDFace->WiresNb() - 1);
|
||||
myWiresBndBoxTree = new BRepMesh_SegmentedFace::ArrayOfBndBoxTree (0, myDFace->WiresNb() - 1);
|
||||
}
|
||||
|
||||
//! Performs initialization of wire with the given index.
|
||||
void operator()(const Standard_Integer theWireIndex) const
|
||||
{
|
||||
const IMeshData::IWireHandle& aDWire = myDFace->GetWire(theWireIndex);
|
||||
|
||||
Handle(NCollection_IncAllocator) aTmpAlloc1 = new NCollection_IncAllocator();
|
||||
|
||||
Handle(BRepMesh_SegmentedFace::Segments) aSegments =
|
||||
new BRepMesh_SegmentedFace::Segments(aDWire->EdgesNb(), aTmpAlloc1);
|
||||
Handle(IMeshData::BndBox2dTree) aBndBoxTree = new IMeshData::BndBox2dTree(aTmpAlloc1);
|
||||
|
||||
myWiresSegments ->ChangeValue(theWireIndex) = aSegments;
|
||||
myWiresBndBoxTree->ChangeValue(theWireIndex) = aBndBoxTree;
|
||||
|
||||
Handle(NCollection_IncAllocator) aTmpAlloc2 = new NCollection_IncAllocator();
|
||||
IMeshData::BndBox2dTreeFiller aBndBoxTreeFiller(*aBndBoxTree, aTmpAlloc2);
|
||||
|
||||
for (Standard_Integer aEdgeIt = 0; aEdgeIt < aDWire->EdgesNb(); ++aEdgeIt)
|
||||
{
|
||||
// TODO: check 2d wire for consistency.
|
||||
|
||||
const IMeshData::IEdgePtr& aDEdge = aDWire->GetEdge(aEdgeIt);
|
||||
const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve(myDFace.get(), aDWire->GetEdgeOrientation(aEdgeIt));
|
||||
|
||||
for (Standard_Integer aPointIt = 1; aPointIt < aPCurve->ParametersNb(); ++aPointIt)
|
||||
{
|
||||
gp_Pnt2d& aPnt1 = aPCurve->GetPoint(aPointIt - 1);
|
||||
gp_Pnt2d& aPnt2 = aPCurve->GetPoint(aPointIt);
|
||||
|
||||
Bnd_Box2d aBox;
|
||||
aBox.Add(aPnt1);
|
||||
aBox.Add(aPnt2);
|
||||
aBox.Enlarge(Precision::Confusion());
|
||||
|
||||
aBndBoxTreeFiller.Add(aSegments->Size(), aBox);
|
||||
aSegments->Append(BRepMesh_SegmentedFace::Segment(
|
||||
aDEdge, aPCurve.get(),
|
||||
&aPnt1, aPointIt - 1,
|
||||
&aPnt2, aPointIt));
|
||||
}
|
||||
}
|
||||
|
||||
aBndBoxTreeFiller.Fill();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
SegmentsFiller (const SegmentsFiller& theOther);
|
||||
|
||||
void operator=(const SegmentsFiller& theOther);
|
||||
|
||||
private:
|
||||
|
||||
const IMeshData::IFaceHandle& myDFace;
|
||||
Handle(BRepMesh_SegmentedFace::ArrayOfSegments)& myWiresSegments;
|
||||
Handle(BRepMesh_SegmentedFace::ArrayOfBndBoxTree)& myWiresBndBoxTree;
|
||||
};
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Constructor
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
BRepMesh_SegmentedFace::BndBox2dTreeSelector::BndBox2dTreeSelector(
|
||||
const Standard_Boolean isCollectIntersectionParams)
|
||||
: myCollectIntersectionParams (isCollectIntersectionParams)
|
||||
, mySelfSegmentIndex(-1)
|
||||
, myIndices(256, new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE))
|
||||
{
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Reset
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_SegmentedFace::BndBox2dTreeSelector::Reset(
|
||||
const BRepMesh_SegmentedFace::Segment* theSegment,
|
||||
const Standard_Integer theSelfSegmentIndex)
|
||||
{
|
||||
myIndices .Clear();
|
||||
myIntParams.Clear();
|
||||
|
||||
mySelfSegmentIndex = theSelfSegmentIndex;
|
||||
mySegment = theSegment;
|
||||
|
||||
myBox.SetVoid();
|
||||
myBox.Add(*mySegment->Point1);
|
||||
myBox.Add(*mySegment->Point2);
|
||||
myBox.Enlarge(Precision::Confusion());
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Reject
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean BRepMesh_SegmentedFace::BndBox2dTreeSelector::Reject(
|
||||
const Bnd_Box2d& theBox) const
|
||||
{
|
||||
return myBox.IsOut(theBox);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Accept
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean BRepMesh_SegmentedFace::BndBox2dTreeSelector::Accept(
|
||||
const Standard_Integer& theSegmentIndex)
|
||||
{
|
||||
const BRepMesh_SegmentedFace::Segment& aSegment = mySegments->Value(theSegmentIndex);
|
||||
|
||||
IntersectionParams aIntNode;
|
||||
aIntNode.Type = BRepMesh_GeomTool::IntSegSeg(
|
||||
mySegment->Point1->XY(), mySegment->Point2->XY(),
|
||||
aSegment .Point1->XY(), aSegment .Point2->XY(),
|
||||
Standard_False, Standard_False,
|
||||
aIntNode.Point, aIntNode.Params);
|
||||
|
||||
if (aIntNode.Type == BRepMesh_GeomTool::Cross ||
|
||||
aIntNode.Type == BRepMesh_GeomTool::PointOnSegment ||
|
||||
aIntNode.Type == BRepMesh_GeomTool::Glued)
|
||||
{
|
||||
|
||||
myIndices.Append(theSegmentIndex);
|
||||
|
||||
if (myCollectIntersectionParams)
|
||||
{
|
||||
myIntParams.Append(aIntNode);
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Constructor
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
BRepMesh_SegmentedFace::BRepMesh_SegmentedFace(
|
||||
const IMeshData::IFaceHandle& theFace,
|
||||
const IMeshTools_Parameters& theParameters)
|
||||
: myDFace (theFace),
|
||||
myParameters(theParameters)
|
||||
{
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Destructor
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
BRepMesh_SegmentedFace::~BRepMesh_SegmentedFace()
|
||||
{
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : collectSegments
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_SegmentedFace::collectSegments()
|
||||
{
|
||||
SegmentsFiller aSegmentsFiller(myDFace, myWiresSegments, myWiresBndBoxTree);
|
||||
OSD_Parallel::For(0, myDFace->WiresNb(), aSegmentsFiller, !isParallel());
|
||||
}
|
169
src/BRepMesh/BRepMesh_SegmentedFace.hxx
Normal file
169
src/BRepMesh/BRepMesh_SegmentedFace.hxx
Normal file
@@ -0,0 +1,169 @@
|
||||
// Created on: 2016-07-04
|
||||
// Copyright (c) 2016 OPEN CASCADE SAS
|
||||
// Created by: Oleg AGASHIN
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef _BRepMesh_SegmentedFace_HeaderFile
|
||||
#define _BRepMesh_SegmentedFace_HeaderFile
|
||||
|
||||
#include <IMeshTools_Parameters.hxx>
|
||||
#include <Standard_Transient.hxx>
|
||||
#include <IMeshData_Face.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
#include <NCollection_Shared.hxx>
|
||||
#include <BRepMesh_GeomTool.hxx>
|
||||
|
||||
//! Auxiliary class providing common functionality for exploding wires of
|
||||
//! discrete face on sets of segments using tessellation data stored in model.
|
||||
class BRepMesh_SegmentedFace : public Standard_Transient
|
||||
{
|
||||
public: //! @name mesher API
|
||||
|
||||
//! Identifies segment inside face.
|
||||
//! Uses explicit pointers to points instead of accessing using indices.
|
||||
struct Segment
|
||||
{
|
||||
IMeshData::IEdgePtr EdgePtr;
|
||||
IMeshData::IPCurvePtr PCurvePtr;
|
||||
gp_Pnt2d* Point1;
|
||||
Standard_Integer Param1;
|
||||
gp_Pnt2d* Point2;
|
||||
Standard_Integer Param2;
|
||||
|
||||
Segment()
|
||||
: EdgePtr (NULL)
|
||||
, PCurvePtr(NULL)
|
||||
, Point1 (NULL)
|
||||
, Param1 (0)
|
||||
, Point2 (NULL)
|
||||
, Param2 (0)
|
||||
{
|
||||
}
|
||||
|
||||
Segment(const IMeshData::IEdgePtr& theEdgePtr,
|
||||
const IMeshData::IPCurvePtr& thePCurvePtr,
|
||||
gp_Pnt2d* thePoint1,
|
||||
const Standard_Integer theParam1,
|
||||
gp_Pnt2d* thePoint2,
|
||||
const Standard_Integer theParam2)
|
||||
: EdgePtr (theEdgePtr)
|
||||
, PCurvePtr(thePCurvePtr)
|
||||
, Point1 (thePoint1)
|
||||
, Param1 (theParam1)
|
||||
, Point2 (thePoint2)
|
||||
, Param2 (theParam2)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//! Keeps parameters of intersection of two segments.
|
||||
//! Params are in range relative to distance between points of corresponding segment.
|
||||
struct IntersectionParams
|
||||
{
|
||||
BRepMesh_GeomTool::IntFlag Type;
|
||||
gp_Pnt2d Point;
|
||||
Standard_Real Params[2];
|
||||
};
|
||||
|
||||
typedef NCollection_Vector<IntersectionParams> VectorOfIntersectionParams;
|
||||
typedef NCollection_Shared<NCollection_Vector<Segment> > Segments;
|
||||
typedef NCollection_Shared<NCollection_Array1<Handle(Segments)> > ArrayOfSegments;
|
||||
typedef NCollection_Shared<NCollection_Array1<Handle(IMeshData::BndBox2dTree)> > ArrayOfBndBoxTree;
|
||||
|
||||
|
||||
//! Default constructor
|
||||
Standard_EXPORT BRepMesh_SegmentedFace(const IMeshData::IFaceHandle& theFace,
|
||||
const IMeshTools_Parameters& theParameters);
|
||||
|
||||
//! Destructor
|
||||
Standard_EXPORT virtual ~BRepMesh_SegmentedFace();
|
||||
|
||||
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_SegmentedFace, Standard_Transient)
|
||||
|
||||
protected:
|
||||
|
||||
//! Returns True in case if check can be performed in parallel mode.
|
||||
inline Standard_Boolean isParallel() const
|
||||
{
|
||||
return (myParameters.InParallel && myDFace->WiresNb() > 1);
|
||||
}
|
||||
|
||||
//! Collects face segments.
|
||||
void collectSegments();
|
||||
|
||||
private:
|
||||
|
||||
BRepMesh_SegmentedFace (const BRepMesh_SegmentedFace& theOther);
|
||||
|
||||
void operator=(const BRepMesh_SegmentedFace& theOther);
|
||||
|
||||
protected:
|
||||
|
||||
//! Selector.
|
||||
//! Used to identify segments with overlapped bounding boxes.
|
||||
class BndBox2dTreeSelector : public IMeshData::BndBox2dTree::Selector
|
||||
{
|
||||
public:
|
||||
//! Constructor.
|
||||
BndBox2dTreeSelector(const Standard_Boolean isCollectIntersectionParams);
|
||||
|
||||
//! Sets working set of segments.
|
||||
inline void SetSegments(const Handle(BRepMesh_SegmentedFace::Segments)& theSegments)
|
||||
{
|
||||
mySegments = theSegments;
|
||||
}
|
||||
|
||||
//! Returns indices of intersecting segments.
|
||||
inline const IMeshData::VectorOfInteger& Indices() const
|
||||
{
|
||||
return myIndices;
|
||||
}
|
||||
|
||||
//! Returns intersection parameters.
|
||||
inline const BRepMesh_SegmentedFace::VectorOfIntersectionParams& IntParams() const
|
||||
{
|
||||
return myIntParams;
|
||||
}
|
||||
|
||||
//! Resets current selector.
|
||||
void Reset(const BRepMesh_SegmentedFace::Segment* theSegment,
|
||||
const Standard_Integer theSelfSegmentIndex);
|
||||
|
||||
//! Indicates should the given box be rejected or not.
|
||||
virtual Standard_Boolean Reject(const Bnd_Box2d& theBox) const;
|
||||
|
||||
//! Accepts segment with the given index in case if it fits conditions.
|
||||
virtual Standard_Boolean Accept(const Standard_Integer& theSegmentIndex);
|
||||
|
||||
private:
|
||||
|
||||
Standard_Boolean myCollectIntersectionParams;
|
||||
Standard_Integer mySelfSegmentIndex;
|
||||
Handle(BRepMesh_SegmentedFace::Segments) mySegments;
|
||||
const BRepMesh_SegmentedFace::Segment* mySegment;
|
||||
Bnd_Box2d myBox;
|
||||
IMeshData::VectorOfInteger myIndices;
|
||||
BRepMesh_SegmentedFace::VectorOfIntersectionParams myIntParams;
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
IMeshData::IFaceHandle myDFace;
|
||||
const IMeshTools_Parameters& myParameters;
|
||||
|
||||
Handle(ArrayOfSegments) myWiresSegments;
|
||||
Handle(ArrayOfBndBoxTree) myWiresBndBoxTree;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
@@ -41,6 +41,8 @@ BRepMesh_EdgeTessellationExtractor.cxx
|
||||
BRepMesh_EdgeTessellationExtractor.hxx
|
||||
BRepMesh_FaceChecker.cxx
|
||||
BRepMesh_FaceChecker.hxx
|
||||
BRepMesh_FaceIntersectionsSplitter.cxx
|
||||
BRepMesh_FaceIntersectionsSplitter.hxx
|
||||
BRepMesh_FaceDiscret.cxx
|
||||
BRepMesh_FaceDiscret.hxx
|
||||
BRepMesh_FactoryError.hxx
|
||||
@@ -68,6 +70,8 @@ BRepMesh_OrientedEdge.hxx
|
||||
BRepMesh_PairOfIndex.hxx
|
||||
BRepMesh_PluginEntryType.hxx
|
||||
BRepMesh_PluginMacro.hxx
|
||||
BRepMesh_SegmentedFace.cxx
|
||||
BRepMesh_SegmentedFace.hxx
|
||||
BRepMesh_SelectorOfDataStructureOfDelaun.cxx
|
||||
BRepMesh_SelectorOfDataStructureOfDelaun.hxx
|
||||
BRepMesh_ShapeTool.cxx
|
||||
|
@@ -77,8 +77,9 @@ namespace IMeshData
|
||||
const size_t MEMORY_BLOCK_SIZE_HUGE = 512 * 1024;
|
||||
#endif
|
||||
|
||||
typedef IMeshData_Edge* IEdgePtr;
|
||||
typedef IMeshData_Face* IFacePtr;
|
||||
typedef IMeshData_Edge* IEdgePtr;
|
||||
typedef IMeshData_PCurve* IPCurvePtr;
|
||||
typedef IMeshData_Face* IFacePtr;
|
||||
|
||||
typedef Handle(IMeshData_Edge) IEdgeHandle;
|
||||
typedef Handle(IMeshData_Wire) IWireHandle;
|
||||
|
@@ -3152,7 +3152,7 @@ static Standard_Integer OCC25547(
|
||||
|
||||
aIntFlag = BRepMesh_GeomTool::IntSegSeg(
|
||||
aRefPnts[0], aRefPnts[1], aRefPnts[2], aRefPnts[3],
|
||||
Standard_False, Standard_False, aIntPnt);
|
||||
Standard_False, Standard_False, aIntPnt, aParams);
|
||||
|
||||
aDiff = aIntPnt.Distance(gp::Origin2d());
|
||||
if (aIntFlag != BRepMesh_GeomTool::Cross || aDiff > Precision::PConfusion())
|
||||
|
@@ -1354,782 +1354,6 @@ static Standard_Integer VListColors (Draw_Interpretor& theDI,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <Graphic3d_ArrayOfTriangles.hxx>
|
||||
#include <Graphic3d_Text.hxx>
|
||||
|
||||
//! Create an array of triangles defining a rectangle.
|
||||
static void addRectangleToArray (const Handle(Graphic3d_ArrayOfTriangles)& theTris,
|
||||
const Graphic3d_Vec2i& theLower,
|
||||
const Graphic3d_Vec2i& theUpper)
|
||||
{
|
||||
const int aFirst = theTris->VertexNumber() + 1;
|
||||
theTris->AddVertex (gp_Pnt (theLower.x(), theLower.y(), 0.0), gp_Pnt2d (0.0, 1.0));
|
||||
theTris->AddVertex (gp_Pnt (theLower.x(), theUpper.y(), 0.0), gp_Pnt2d (0.0, 0.0));
|
||||
theTris->AddVertex (gp_Pnt (theUpper.x(), theUpper.y(), 0.0), gp_Pnt2d (1.0, 0.0));
|
||||
theTris->AddVertex (gp_Pnt (theUpper.x(), theLower.y(), 0.0), gp_Pnt2d (1.0, 1.0));
|
||||
theTris->AddEdges (aFirst + 0, aFirst + 1, aFirst + 2);
|
||||
theTris->AddEdges (aFirst + 0, aFirst + 2, aFirst + 3);
|
||||
}
|
||||
|
||||
//! Create an array of triangles defining a rectangle.
|
||||
static Handle(Graphic3d_ArrayOfTriangles) createRectangleArray (const Graphic3d_Vec2i& theLower,
|
||||
const Graphic3d_Vec2i& theUpper,
|
||||
Graphic3d_ArrayFlags theFlags)
|
||||
{
|
||||
Handle(Graphic3d_ArrayOfTriangles) aRectTris = new Graphic3d_ArrayOfTriangles (4, 6, theFlags);
|
||||
addRectangleToArray (aRectTris, theLower, theUpper);
|
||||
return aRectTris;
|
||||
}
|
||||
|
||||
//! Material widget action.
|
||||
enum AIS_MaterialEditorWidgetAction
|
||||
{
|
||||
AIS_MaterialEditorWidgetAction_Reset,
|
||||
AIS_MaterialEditorWidgetAction_Transparency,
|
||||
AIS_MaterialEditorWidgetAction_PbrAlbedo,
|
||||
AIS_MaterialEditorWidgetAction_PbrMetallic,
|
||||
AIS_MaterialEditorWidgetAction_PbrRoughness,
|
||||
AIS_MaterialEditorWidgetAction_PbrEmission,
|
||||
AIS_MaterialEditorWidgetAction_PbrIOR,
|
||||
AIS_MaterialEditorWidgetAction_CommonShininess,
|
||||
AIS_MaterialEditorWidgetAction_CommonAmbient,
|
||||
AIS_MaterialEditorWidgetAction_CommonDiffuse,
|
||||
AIS_MaterialEditorWidgetAction_CommonSpecular,
|
||||
AIS_MaterialEditorWidgetAction_CommonEmissive,
|
||||
AIS_MaterialEditorWidgetAction_NB
|
||||
};
|
||||
|
||||
//! Entity owner holding AIS_MaterialEditorWidget action.
|
||||
class AIS_MaterialEditorWidgetOwner : public SelectMgr_EntityOwner
|
||||
{
|
||||
DEFINE_STANDARD_RTTI_INLINE(AIS_MaterialEditorWidgetOwner, SelectMgr_EntityOwner)
|
||||
public:
|
||||
|
||||
//! Main constructor.
|
||||
//AIS_MaterialEditorWidgetOwner (const Handle(AIS_MaterialEditorWidget)& theSel)
|
||||
AIS_MaterialEditorWidgetOwner (const Handle(AIS_InteractiveObject)& theSel,
|
||||
const Handle(Graphic3d_Aspects)& theAspects,
|
||||
AIS_MaterialEditorWidgetAction theAction,
|
||||
Standard_Integer theComponent = 0)
|
||||
: SelectMgr_EntityOwner (theSel, 5),
|
||||
myAspects (theAspects),
|
||||
myAction (theAction),
|
||||
myComponent (theComponent) {}
|
||||
|
||||
//! Set last picking results.
|
||||
void SetPickedPoint (const gp_Pnt& thePickedCenterPnt,
|
||||
const gp_Pnt& thePnt,
|
||||
const gp_XY& theUV)
|
||||
{
|
||||
myPickedCenterPnt = thePickedCenterPnt;
|
||||
myPickedPnt = thePnt;
|
||||
myPickedUV = theUV;
|
||||
}
|
||||
|
||||
//! Reset highlighting.
|
||||
virtual void Unhilight (const Handle(PrsMgr_PresentationManager)& ,
|
||||
const Standard_Integer ) Standard_OVERRIDE {}
|
||||
|
||||
//! Handle highlighting.
|
||||
virtual void HilightWithColor (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
|
||||
const Handle(Prs3d_Drawer)& theStyle,
|
||||
const Standard_Integer theMode) Standard_OVERRIDE;
|
||||
private:
|
||||
Handle(Graphic3d_Aspects) myAspects;
|
||||
AIS_MaterialEditorWidgetAction myAction;
|
||||
Standard_Integer myComponent;
|
||||
gp_Pnt myPickedCenterPnt;
|
||||
gp_Pnt myPickedPnt;
|
||||
gp_XY myPickedUV;
|
||||
};
|
||||
|
||||
//! Sensitive quad.
|
||||
class AIS_MaterialEditorWidgetSensitiveQuad : public Select3D_SensitiveEntity
|
||||
{
|
||||
DEFINE_STANDARD_RTTI_INLINE(AIS_MaterialEditorWidgetSensitiveQuad, Select3D_SensitiveEntity)
|
||||
public:
|
||||
|
||||
//! Main constructor.
|
||||
AIS_MaterialEditorWidgetSensitiveQuad (const Handle(SelectBasics_EntityOwner)& theOwnerId,
|
||||
const Graphic3d_Vec2i& theLower,
|
||||
const Graphic3d_Vec2i& theUpper)
|
||||
: Select3D_SensitiveEntity (theOwnerId)
|
||||
{
|
||||
myPoints[0].SetCoord (theLower.x(), theLower.y(), 0.0);
|
||||
myPoints[1].SetCoord (theLower.x(), theUpper.y(), 0.0);
|
||||
myPoints[2].SetCoord (theUpper.x(), theUpper.y(), 0.0);
|
||||
myPoints[3].SetCoord (theUpper.x(), theLower.y(), 0.0);
|
||||
}
|
||||
|
||||
//! Checks whether the triangle overlaps current selecting volume
|
||||
virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
SelectBasics_PickResult& thePickResult) Standard_OVERRIDE
|
||||
{
|
||||
if (!theMgr.IsOverlapAllowed())
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
if (!theMgr.Overlaps (myPoints[0], myPoints[1], myPoints[2], Select3D_TOS_INTERIOR, thePickResult)
|
||||
&& !theMgr.Overlaps (myPoints[0], myPoints[2], myPoints[3], Select3D_TOS_INTERIOR, thePickResult))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
if (!thePickResult.HasPickedPoint())
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
if (AIS_MaterialEditorWidgetOwner* anOwner = dynamic_cast<AIS_MaterialEditorWidgetOwner* >(myOwnerId.get()))
|
||||
{
|
||||
gp_Vec aDirX (myPoints[0], gp_Pnt (myPoints[2].X(), myPoints[0].Y(), myPoints[0].Z()));
|
||||
gp_Vec aDirY (myPoints[0], gp_Pnt (myPoints[0].X(), myPoints[2].Y(), myPoints[0].Z()));
|
||||
aDirX.Normalize();
|
||||
aDirY.Normalize();
|
||||
const gp_Vec aDirP (myPoints[0], thePickResult.PickedPoint());
|
||||
const gp_Pnt aSize = myPoints[2].XYZ() - myPoints[0].XYZ();
|
||||
anOwner->SetPickedPoint (CenterOfGeometry(),
|
||||
thePickResult.PickedPoint(),
|
||||
gp_XY (Max (0.0, Min (1.0, aDirP.Dot (aDirX) / aSize.X())),
|
||||
Max (0.0, Min (1.0, aDirP.Dot (aDirY) / aSize.Y()))));
|
||||
}
|
||||
|
||||
//thePickResult.SetDistToGeomCenter (theMgr.DistToGeometryCenter (CenterOfGeometry()));
|
||||
thePickResult.SetDistToGeomCenter (0.0);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//! Returns the copy of this
|
||||
virtual Handle(Select3D_SensitiveEntity) GetConnected() Standard_OVERRIDE
|
||||
{
|
||||
Handle(Select3D_SensitiveEntity) aCopy = new AIS_MaterialEditorWidgetSensitiveQuad (*this);
|
||||
return aCopy;
|
||||
}
|
||||
|
||||
//! Returns bounding box of the triangle. If location transformation is set, it will be applied
|
||||
virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE
|
||||
{
|
||||
const SelectMgr_Vec3 aMinPnt (myPoints[0].X(), myPoints[0].Y(), myPoints[0].Z());
|
||||
const SelectMgr_Vec3 aMaxPnt (myPoints[2].X(), myPoints[2].Y(), myPoints[2].Z());
|
||||
return Select3D_BndBox3d (aMinPnt, aMaxPnt);
|
||||
}
|
||||
|
||||
//! Returns the amount of points
|
||||
virtual Standard_Integer NbSubElements() Standard_OVERRIDE { return 4; }
|
||||
|
||||
virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE { return (myPoints[0].XYZ() + myPoints[2].XYZ()) * 0.5; }
|
||||
|
||||
private:
|
||||
|
||||
//! Copy constructor.
|
||||
AIS_MaterialEditorWidgetSensitiveQuad (const AIS_MaterialEditorWidgetSensitiveQuad& theCopy)
|
||||
: Select3D_SensitiveEntity (theCopy.myOwnerId)
|
||||
{
|
||||
myPoints[0] = theCopy.myPoints[0];
|
||||
myPoints[1] = theCopy.myPoints[1];
|
||||
myPoints[2] = theCopy.myPoints[2];
|
||||
myPoints[3] = theCopy.myPoints[3];
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
gp_Pnt myPoints[4];
|
||||
|
||||
};
|
||||
|
||||
//! Widget for configuring material properties.
|
||||
class AIS_MaterialEditorWidget : public AIS_InteractiveObject
|
||||
{
|
||||
DEFINE_STANDARD_RTTI_INLINE(AIS_MaterialEditorWidget, AIS_InteractiveObject)
|
||||
public:
|
||||
|
||||
//! Empty constructor.
|
||||
AIS_MaterialEditorWidget()
|
||||
: myBackAspect (new Graphic3d_Aspects()),
|
||||
mySlideBackAspect (new Graphic3d_Aspects()),
|
||||
mySlideFillAspect (new Graphic3d_Aspects()),
|
||||
myCaptionTextAspect (new Graphic3d_AspectText3d()),
|
||||
mySlideTextAspect (new Graphic3d_AspectText3d()),
|
||||
myWidth (200),
|
||||
mySlideHeight (30)
|
||||
{
|
||||
myInfiniteState = true;
|
||||
myIsMutable = true;
|
||||
myDrawer->SetZLayer (Graphic3d_ZLayerId_TopOSD);
|
||||
myTransformPersistence = new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_RIGHT_LOWER);
|
||||
myTransformPersistence->SetOffset2d (Graphic3d_Vec2i (myWidth, 200));
|
||||
|
||||
myBackAspect->SetInteriorColor (Quantity_NOC_GRAY80);
|
||||
myBackAspect->SetShadingModel (Graphic3d_TOSM_UNLIT);
|
||||
//myBackAspect->ChangeFrontMaterial().SetTransparency (0.5f);
|
||||
//myBackAspect->SetAlphaMode (Graphic3d_AlphaMode_Blend);
|
||||
|
||||
mySlideBackAspect->SetInteriorColor (Quantity_NOC_GRAY30);
|
||||
mySlideBackAspect->SetShadingModel (Graphic3d_TOSM_UNLIT);
|
||||
|
||||
mySlideFillAspect->SetInteriorColor (Quantity_NOC_STEELBLUE4);
|
||||
mySlideFillAspect->SetShadingModel (Graphic3d_TOSM_UNLIT);
|
||||
|
||||
myCaptionTextAspect->SetFont (Font_NOF_SANS_SERIF);
|
||||
myCaptionTextAspect->SetTextDisplayType (Aspect_TODT_SHADOW);
|
||||
myCaptionTextAspect->SetColor (Quantity_NOC_WHITE);
|
||||
myCaptionTextAspect->SetColorSubTitle (Quantity_NOC_BLACK);
|
||||
myCaptionTextAspect->SetTextFontAspect (Font_FontAspect_Bold);
|
||||
|
||||
*mySlideTextAspect = *myCaptionTextAspect;
|
||||
mySlideTextAspect->SetTextFontAspect (Font_FontAspect_Regular);
|
||||
}
|
||||
|
||||
//! Set new widget width.
|
||||
Standard_Integer WidgetWidth() const { return myWidth; }
|
||||
|
||||
//! Set new widget width.
|
||||
void SetWidgetWidth (Standard_Integer theWidth)
|
||||
{
|
||||
myWidth = theWidth;
|
||||
SetToUpdate();
|
||||
}
|
||||
|
||||
//! Return list of attached presentations.
|
||||
const AIS_ListOfInteractive& ListOfAttachments() const { return myAttachedPrsList; }
|
||||
|
||||
//! Attach widget to specified presentation list.
|
||||
void Attach (const AIS_ListOfInteractive& thePrsList)
|
||||
{
|
||||
myAttachedPrsList = thePrsList;
|
||||
myEditAspects.Nullify();
|
||||
SetToUpdate();
|
||||
if (thePrsList.IsEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (thePrsList.First()->Attributes()->SetupOwnShadingAspect())
|
||||
{
|
||||
thePrsList.First()->SetToUpdate();
|
||||
}
|
||||
Handle(Prs3d_ShadingAspect) anAspect = thePrsList.First()->Attributes()->ShadingAspect();
|
||||
myEditAspects = anAspect->Aspect();
|
||||
for (AIS_ListOfInteractive::Iterator aPrsIter (thePrsList); aPrsIter.More(); aPrsIter.Next())
|
||||
{
|
||||
const Handle(AIS_InteractiveObject)& aPrs = aPrsIter.Value();
|
||||
if (aPrs->Attributes()->ShadingAspect() != anAspect)
|
||||
{
|
||||
aPrs->Attributes()->SetShadingAspect (anAspect);
|
||||
aPrs->SetToUpdate();
|
||||
}
|
||||
if (aPrs->HasInteractiveContext())
|
||||
{
|
||||
if (aPrs->ToBeUpdated())
|
||||
{
|
||||
aPrs->GetContext()->Display (aPrs, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
aPrs->SynchronizeAspects();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
//! Accept only display mode 0.
|
||||
virtual Standard_Boolean AcceptDisplayMode (const Standard_Integer theMode) const Standard_OVERRIDE { return theMode == 0; }
|
||||
|
||||
//! Global selection has no meaning for this class.
|
||||
virtual Handle(SelectMgr_EntityOwner) GlobalSelOwner() const Standard_OVERRIDE { return Handle(SelectMgr_EntityOwner)(); }
|
||||
|
||||
//! Compute presentation.
|
||||
virtual void Compute (const Handle(PrsMgr_PresentationManager3d)& ,
|
||||
const Handle(Prs3d_Presentation)& thePrs,
|
||||
const Standard_Integer theMode) Standard_OVERRIDE
|
||||
{
|
||||
if (theMode != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool toShowCommon = true, toShowPbr = false;
|
||||
Handle(V3d_View) aView = GetContext()->LastActiveView();
|
||||
if (aView.IsNull())
|
||||
{
|
||||
aView = GetContext()->CurrentViewer()->ActiveViews().First();
|
||||
}
|
||||
if (!aView.IsNull())
|
||||
{
|
||||
toShowPbr = aView->ShadingModel() == Graphic3d_TOSM_PBR
|
||||
|| aView->ShadingModel() == Graphic3d_TOSM_PBR_FACET;
|
||||
toShowCommon = !toShowPbr;
|
||||
}
|
||||
|
||||
thePrs->SetInfiniteState (true);
|
||||
mySensQuads.Clear();
|
||||
mySelOwners.Clear();
|
||||
|
||||
Handle(Graphic3d_Aspects) anEditAspects = myEditAspects;
|
||||
if (anEditAspects.IsNull())
|
||||
{
|
||||
anEditAspects = new Graphic3d_Aspects();
|
||||
}
|
||||
|
||||
Handle(Graphic3d_Group) aBackGroup = thePrs->NewGroup();
|
||||
aBackGroup->SetGroupPrimitivesAspect (myBackAspect);
|
||||
|
||||
Handle(Graphic3d_Group) aSlideBackGroup = thePrs->NewGroup();
|
||||
aSlideBackGroup->SetGroupPrimitivesAspect (mySlideBackAspect);
|
||||
|
||||
Handle(Graphic3d_Group) aSlideFillGroup = thePrs->NewGroup();
|
||||
aSlideFillGroup->SetGroupPrimitivesAspect (mySlideFillAspect);
|
||||
|
||||
Handle(Graphic3d_Group) aCapGroup = thePrs->NewGroup();
|
||||
aCapGroup->SetGroupPrimitivesAspect (myCaptionTextAspect);
|
||||
|
||||
Handle(Graphic3d_Group) aLabGroup = thePrs->NewGroup();
|
||||
aLabGroup->SetGroupPrimitivesAspect (mySlideTextAspect);
|
||||
|
||||
Graphic3d_Vec2i aLower (0, 0);
|
||||
Graphic3d_Vec2i anUpper (myWidth, 0);
|
||||
{
|
||||
//Handle(Graphic3d_ArrayOfTriangles) aTris = createRectangleArray (aLower, anUpper, Graphic3d_ArrayFlags_None);
|
||||
//aBackGroup->AddPrimitiveArray (aTris);
|
||||
}
|
||||
|
||||
Standard_Integer aTopIter = anUpper.y();
|
||||
addCaption (aTopIter, NULL, aCapGroup, "Material");
|
||||
addCaption (aTopIter, NULL, aLabGroup, anEditAspects->FrontMaterial().StringName());
|
||||
addSlider (aTopIter, aSlideBackGroup, NULL, aLabGroup, "RESET",
|
||||
AIS_MaterialEditorWidgetAction_Reset, 0, -Precision::Infinite());
|
||||
|
||||
addCaption (aTopIter, NULL, aCapGroup, "Transparency");
|
||||
addSlider (aTopIter, aSlideBackGroup, aSlideFillGroup, aLabGroup, "",
|
||||
AIS_MaterialEditorWidgetAction_Transparency, 0, anEditAspects->FrontMaterial().Transparency());
|
||||
|
||||
if (toShowPbr)
|
||||
{
|
||||
const Graphic3d_Vec3 aBaseColVec3 = anEditAspects->FrontMaterial().PBRMaterial().Color().GetRGB();
|
||||
addCaption (aTopIter, NULL, aCapGroup, "Albedo");
|
||||
addSlider (aTopIter, aSlideBackGroup, aSlideFillGroup, aLabGroup, "%",
|
||||
AIS_MaterialEditorWidgetAction_PbrAlbedo, -1, aBaseColVec3.maxComp() * 100.0, Bnd_Range (0, 100));
|
||||
addSlider (aTopIter, aSlideBackGroup, aSlideFillGroup, aLabGroup, "r",
|
||||
AIS_MaterialEditorWidgetAction_PbrAlbedo, 0, aBaseColVec3.r());
|
||||
addSlider (aTopIter, aSlideBackGroup, aSlideFillGroup, aLabGroup, "g",
|
||||
AIS_MaterialEditorWidgetAction_PbrAlbedo, 1, aBaseColVec3.g());
|
||||
addSlider (aTopIter, aSlideBackGroup, aSlideFillGroup, aLabGroup, "b",
|
||||
AIS_MaterialEditorWidgetAction_PbrAlbedo, 2, aBaseColVec3.b());
|
||||
|
||||
addCaption (aTopIter, NULL, aCapGroup, "Metallic");
|
||||
addSlider (aTopIter, aSlideBackGroup, aSlideFillGroup, aLabGroup, "",
|
||||
AIS_MaterialEditorWidgetAction_PbrMetallic, 0, anEditAspects->FrontMaterial().PBRMaterial().Metallic());
|
||||
addCaption (aTopIter, NULL, aCapGroup, "Roughness");
|
||||
addSlider (aTopIter, aSlideBackGroup, aSlideFillGroup, aLabGroup, "",
|
||||
AIS_MaterialEditorWidgetAction_PbrRoughness, 0, anEditAspects->FrontMaterial().PBRMaterial().NormalizedRoughness());
|
||||
addCaption (aTopIter, NULL, aCapGroup, "IOR");
|
||||
addSlider (aTopIter, aSlideBackGroup, aSlideFillGroup, aLabGroup, "",
|
||||
AIS_MaterialEditorWidgetAction_PbrIOR, 0,
|
||||
anEditAspects->FrontMaterial().PBRMaterial().IOR(), Bnd_Range (1, 3));
|
||||
|
||||
const Graphic3d_Vec3 anEmissVec3 = anEditAspects->FrontMaterial().PBRMaterial().Emission();
|
||||
addCaption (aTopIter, NULL, aCapGroup, "Emission");
|
||||
addSlider (aTopIter, aSlideBackGroup, aSlideFillGroup, aLabGroup, "%",
|
||||
AIS_MaterialEditorWidgetAction_PbrEmission, -1, anEmissVec3.maxComp() * 100.0, Bnd_Range (0, 100));
|
||||
addSlider (aTopIter, aSlideBackGroup, aSlideFillGroup, aLabGroup, "r",
|
||||
AIS_MaterialEditorWidgetAction_PbrEmission, 0, anEmissVec3.r());
|
||||
addSlider (aTopIter, aSlideBackGroup, aSlideFillGroup, aLabGroup, "g",
|
||||
AIS_MaterialEditorWidgetAction_PbrEmission, 1, anEmissVec3.g());
|
||||
addSlider (aTopIter, aSlideBackGroup, aSlideFillGroup, aLabGroup, "b",
|
||||
AIS_MaterialEditorWidgetAction_PbrEmission, 2, anEmissVec3.b());
|
||||
}
|
||||
|
||||
if (toShowCommon)
|
||||
{
|
||||
addCaption (aTopIter, NULL, aCapGroup, "Shininess");
|
||||
addSlider (aTopIter, aSlideBackGroup, aSlideFillGroup, aLabGroup, "",
|
||||
AIS_MaterialEditorWidgetAction_CommonShininess, 0,
|
||||
anEditAspects->FrontMaterial().Shininess() * 128.0, Bnd_Range (0, 128));
|
||||
|
||||
const Graphic3d_Vec3 anAmbVec3 = anEditAspects->FrontMaterial().AmbientColor();
|
||||
addCaption (aTopIter, NULL, aCapGroup, "Ambient");
|
||||
addSlider (aTopIter, aSlideBackGroup, aSlideFillGroup, aLabGroup, "%",
|
||||
AIS_MaterialEditorWidgetAction_CommonAmbient, -1, anAmbVec3.maxComp() * 100.0, Bnd_Range (0, 100));
|
||||
addSlider (aTopIter, aSlideBackGroup, aSlideFillGroup, aLabGroup, "r",
|
||||
AIS_MaterialEditorWidgetAction_CommonAmbient, 0, anAmbVec3.r());
|
||||
addSlider (aTopIter, aSlideBackGroup, aSlideFillGroup, aLabGroup, "g",
|
||||
AIS_MaterialEditorWidgetAction_CommonAmbient, 1, anAmbVec3.g());
|
||||
addSlider (aTopIter, aSlideBackGroup, aSlideFillGroup, aLabGroup, "b",
|
||||
AIS_MaterialEditorWidgetAction_CommonAmbient, 2, anAmbVec3.b());
|
||||
|
||||
const Graphic3d_Vec3 aDiffVec3 = anEditAspects->FrontMaterial().DiffuseColor();
|
||||
addCaption (aTopIter, NULL, aCapGroup, "Diffuse");
|
||||
addSlider (aTopIter, aSlideBackGroup, aSlideFillGroup, aLabGroup, "%",
|
||||
AIS_MaterialEditorWidgetAction_CommonDiffuse, -1, aDiffVec3.maxComp() * 100.0, Bnd_Range (0, 100));
|
||||
addSlider (aTopIter, aSlideBackGroup, aSlideFillGroup, aLabGroup, "r",
|
||||
AIS_MaterialEditorWidgetAction_CommonDiffuse, 0, aDiffVec3.r());
|
||||
addSlider (aTopIter, aSlideBackGroup, aSlideFillGroup, aLabGroup, "g",
|
||||
AIS_MaterialEditorWidgetAction_CommonDiffuse, 1, aDiffVec3.g());
|
||||
addSlider (aTopIter, aSlideBackGroup, aSlideFillGroup, aLabGroup, "b",
|
||||
AIS_MaterialEditorWidgetAction_CommonDiffuse, 2, aDiffVec3.b());
|
||||
|
||||
const Graphic3d_Vec3 aSpecVec3 = anEditAspects->FrontMaterial().SpecularColor();
|
||||
addCaption (aTopIter, NULL, aCapGroup, "Specular");
|
||||
addSlider (aTopIter, aSlideBackGroup, aSlideFillGroup, aLabGroup, "%",
|
||||
AIS_MaterialEditorWidgetAction_CommonSpecular, -1, aSpecVec3.maxComp() * 100.0, Bnd_Range (0, 100));
|
||||
addSlider (aTopIter, aSlideBackGroup, aSlideFillGroup, aLabGroup, "r",
|
||||
AIS_MaterialEditorWidgetAction_CommonSpecular, 0, aSpecVec3.r());
|
||||
addSlider (aTopIter, aSlideBackGroup, aSlideFillGroup, aLabGroup, "g",
|
||||
AIS_MaterialEditorWidgetAction_CommonSpecular, 1, aSpecVec3.g());
|
||||
addSlider (aTopIter, aSlideBackGroup, aSlideFillGroup, aLabGroup, "b",
|
||||
AIS_MaterialEditorWidgetAction_CommonSpecular, 2, aSpecVec3.b());
|
||||
|
||||
const Graphic3d_Vec3 anEmissVec3 = anEditAspects->FrontMaterial().EmissiveColor();
|
||||
addCaption (aTopIter, NULL, aCapGroup, "Emissive");
|
||||
addSlider (aTopIter, aSlideBackGroup, aSlideFillGroup, aLabGroup, "%",
|
||||
AIS_MaterialEditorWidgetAction_CommonEmissive, -1, anEmissVec3.maxComp() * 100.0, Bnd_Range (0, 100));
|
||||
addSlider (aTopIter, aSlideBackGroup, aSlideFillGroup, aLabGroup, "r",
|
||||
AIS_MaterialEditorWidgetAction_CommonEmissive, 0, anEmissVec3.r());
|
||||
addSlider (aTopIter, aSlideBackGroup, aSlideFillGroup, aLabGroup, "g",
|
||||
AIS_MaterialEditorWidgetAction_CommonEmissive, 1, anEmissVec3.g());
|
||||
addSlider (aTopIter, aSlideBackGroup, aSlideFillGroup, aLabGroup, "b",
|
||||
AIS_MaterialEditorWidgetAction_CommonEmissive, 2, anEmissVec3.b());
|
||||
}
|
||||
|
||||
myTransformPersistence->SetOffset2d (Graphic3d_Vec2i (myWidth, Abs (aTopIter)));
|
||||
}
|
||||
|
||||
void addCaption (Standard_Integer& theTopIter,
|
||||
const Handle(Graphic3d_Group)& theBackGroup,
|
||||
const Handle(Graphic3d_Group)& theLabelsGroup,
|
||||
const TCollection_AsciiString& theText)
|
||||
{
|
||||
addSlider (theTopIter, theBackGroup, NULL, theLabelsGroup, theText,
|
||||
AIS_MaterialEditorWidgetAction_Transparency, -1, -Precision::Infinite());
|
||||
}
|
||||
|
||||
void addSlider (Standard_Integer& theTopIter,
|
||||
const Handle(Graphic3d_Group)& theSlideBackGroup,
|
||||
const Handle(Graphic3d_Group)& theSlideFillGroup,
|
||||
const Handle(Graphic3d_Group)& theLabelsGroup,
|
||||
const TCollection_AsciiString& theText,
|
||||
const AIS_MaterialEditorWidgetAction theAction,
|
||||
const Standard_Integer theActionComponent,
|
||||
const Standard_Real theValue,
|
||||
const Bnd_Range& theValueRange = Bnd_Range (0.0, 1.0))
|
||||
{
|
||||
const Standard_Integer aSlideGap = 8;
|
||||
const Graphic3d_Vec2i aSlideUpper (myWidth - aSlideGap, theTopIter - aSlideGap);
|
||||
const Graphic3d_Vec2i aSlideLower (aSlideGap, theTopIter - mySlideHeight + aSlideGap);
|
||||
if (!theSlideBackGroup.IsNull())
|
||||
{
|
||||
Handle(Graphic3d_ArrayOfTriangles) aTris = createRectangleArray (aSlideLower, aSlideUpper, Graphic3d_ArrayFlags_None);
|
||||
theSlideBackGroup->AddPrimitiveArray (aTris);
|
||||
|
||||
Handle(AIS_MaterialEditorWidgetOwner) aSensOwner =
|
||||
new AIS_MaterialEditorWidgetOwner (this, myEditAspects, theAction, theActionComponent);
|
||||
Handle(AIS_MaterialEditorWidgetSensitiveQuad) aSensQuad = new AIS_MaterialEditorWidgetSensitiveQuad (aSensOwner, aSlideLower, aSlideUpper);
|
||||
mySelOwners.Append (aSensOwner);
|
||||
mySensQuads.Append (aSensQuad);
|
||||
}
|
||||
|
||||
TCollection_AsciiString aTextVal = theText;
|
||||
if (!theSlideFillGroup.IsNull()
|
||||
&& !Precision::IsInfinite (theValue))
|
||||
{
|
||||
if (!aTextVal.IsEmpty())
|
||||
{
|
||||
aTextVal += ": ";
|
||||
}
|
||||
aTextVal += theValue;
|
||||
|
||||
Standard_Real aMin = 0.0, aMax = 1.0;
|
||||
theValueRange.GetBounds (aMin, aMax);
|
||||
Standard_Real aVal = (Max (Min (theValue, aMax), aMin) - aMin) / (aMax - aMin);
|
||||
const Graphic3d_Vec2i aFillUpper (aSlideLower.x() + Standard_Integer(aVal * (myWidth - aSlideGap * 2)),
|
||||
aSlideUpper.y());
|
||||
Handle(Graphic3d_ArrayOfTriangles) aTrisFill = createRectangleArray (aSlideLower, aFillUpper, Graphic3d_ArrayFlags_None);
|
||||
theSlideFillGroup->AddPrimitiveArray (aTrisFill);
|
||||
}
|
||||
|
||||
if (!aTextVal.IsEmpty()
|
||||
&& !theLabelsGroup.IsNull())
|
||||
{
|
||||
Handle(Graphic3d_Text) aText = new Graphic3d_Text ((float )myDrawer->TextAspect()->Height());
|
||||
aText->SetText (aTextVal);
|
||||
aText->SetHorizontalAlignment (Graphic3d_HTA_CENTER);
|
||||
aText->SetVerticalAlignment (Graphic3d_VTA_CENTER);
|
||||
aText->SetPosition (gp_Pnt (myWidth / 2, theTopIter - mySlideHeight / 2, 0));
|
||||
theLabelsGroup->AddText (aText);
|
||||
}
|
||||
|
||||
theTopIter -= mySlideHeight;
|
||||
}
|
||||
|
||||
//! Compute selection
|
||||
virtual void ComputeSelection (const Handle(SelectMgr_Selection)& theSel,
|
||||
const Standard_Integer theMode) Standard_OVERRIDE
|
||||
{
|
||||
if (theMode != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (NCollection_Sequence<Handle(AIS_MaterialEditorWidgetSensitiveQuad)>::Iterator aSensIter (mySensQuads);
|
||||
aSensIter.More(); aSensIter.Next())
|
||||
{
|
||||
theSel->Add (aSensIter.Value());
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
Handle(Graphic3d_Aspects) myEditAspects; //!< aspects to edit
|
||||
AIS_ListOfInteractive myAttachedPrsList; //!< list of attached presentations
|
||||
|
||||
Handle(Graphic3d_Aspects) myBackAspect; //!< widget background aspect
|
||||
Handle(Graphic3d_Aspects) mySlideBackAspect; //!< slider background aspect
|
||||
Handle(Graphic3d_Aspects) mySlideFillAspect; //!< slider progress aspect
|
||||
Handle(Graphic3d_AspectText3d) myCaptionTextAspect; //!< caption text aspect
|
||||
Handle(Graphic3d_AspectText3d) mySlideTextAspect; //!< slider text aspect
|
||||
Standard_Integer myWidth; //!< widget width
|
||||
Standard_Integer mySlideHeight; //!< slider height
|
||||
|
||||
NCollection_Sequence<Handle(AIS_MaterialEditorWidgetSensitiveQuad)> mySensQuads;
|
||||
NCollection_Sequence<Handle(AIS_MaterialEditorWidgetOwner)> mySelOwners;
|
||||
};
|
||||
|
||||
void AIS_MaterialEditorWidgetOwner::HilightWithColor (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
|
||||
const Handle(Prs3d_Drawer)& ,
|
||||
const Standard_Integer )
|
||||
{
|
||||
if (thePrsMgr->IsImmediateModeOn())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Handle(AIS_MaterialEditorWidget) aWidget = Handle(AIS_MaterialEditorWidget)::DownCast (Selectable());
|
||||
if (aWidget.IsNull())
|
||||
{
|
||||
throw Standard_ProgramError ("Internal Error within AIS_MaterialWidgetOwnerOwner::HilightWithColor()!");
|
||||
}
|
||||
|
||||
float aClamped = (float )Max (Min (myPickedUV.X(), 1.0), 0.0);
|
||||
switch (myAction)
|
||||
{
|
||||
case AIS_MaterialEditorWidgetAction_Reset:
|
||||
{
|
||||
myAspects->ChangeFrontMaterial() = myAspects->FrontMaterial().RequestedName();
|
||||
break;
|
||||
}
|
||||
case AIS_MaterialEditorWidgetAction_Transparency:
|
||||
{
|
||||
myAspects->ChangeFrontMaterial().SetTransparency (aClamped);
|
||||
break;
|
||||
}
|
||||
case AIS_MaterialEditorWidgetAction_PbrMetallic:
|
||||
{
|
||||
Graphic3d_PBRMaterial aPbr = myAspects->ChangeFrontMaterial().PBRMaterial();
|
||||
aPbr.SetMetallic (aClamped);
|
||||
myAspects->ChangeFrontMaterial().SetPBRMaterial (aPbr);
|
||||
break;
|
||||
}
|
||||
case AIS_MaterialEditorWidgetAction_PbrRoughness:
|
||||
{
|
||||
Graphic3d_PBRMaterial aPbr = myAspects->ChangeFrontMaterial().PBRMaterial();
|
||||
aPbr.SetRoughness (aClamped);
|
||||
myAspects->ChangeFrontMaterial().SetPBRMaterial (aPbr);
|
||||
break;
|
||||
}
|
||||
case AIS_MaterialEditorWidgetAction_PbrIOR:
|
||||
{
|
||||
Graphic3d_PBRMaterial aPbr = myAspects->ChangeFrontMaterial().PBRMaterial();
|
||||
aPbr.SetIOR (1.0f + aClamped * 2.0f);
|
||||
myAspects->ChangeFrontMaterial().SetPBRMaterial (aPbr);
|
||||
break;
|
||||
}
|
||||
case AIS_MaterialEditorWidgetAction_PbrAlbedo:
|
||||
{
|
||||
Graphic3d_Vec3 aVec = myAspects->FrontMaterial().PBRMaterial().Color().GetRGB();
|
||||
if (myComponent == -1)
|
||||
{
|
||||
const float aMaxComp = aVec.maxComp() > 0.0f ? aVec.maxComp() : 1.0f;
|
||||
aVec = (aVec / aMaxComp) * aClamped;
|
||||
}
|
||||
else
|
||||
{
|
||||
aVec[myComponent] = aClamped;
|
||||
}
|
||||
|
||||
Graphic3d_PBRMaterial aPbr = myAspects->ChangeFrontMaterial().PBRMaterial();
|
||||
aPbr.SetColor (Quantity_Color (aVec));
|
||||
myAspects->ChangeFrontMaterial().SetPBRMaterial (aPbr);
|
||||
break;
|
||||
}
|
||||
case AIS_MaterialEditorWidgetAction_PbrEmission:
|
||||
{
|
||||
Graphic3d_Vec3 aVec = myAspects->FrontMaterial().PBRMaterial().Emission();
|
||||
if (myComponent == -1)
|
||||
{
|
||||
const float aMaxComp = aVec.maxComp() > 0.0f ? aVec.maxComp() : 1.0f;
|
||||
aVec = (aVec / aMaxComp) * aClamped;
|
||||
}
|
||||
else
|
||||
{
|
||||
aVec[myComponent] = aClamped;
|
||||
}
|
||||
|
||||
Graphic3d_PBRMaterial aPbr = myAspects->ChangeFrontMaterial().PBRMaterial();
|
||||
aPbr.SetEmission (aVec);
|
||||
myAspects->ChangeFrontMaterial().SetPBRMaterial (aPbr);
|
||||
break;
|
||||
}
|
||||
case AIS_MaterialEditorWidgetAction_CommonShininess:
|
||||
{
|
||||
myAspects->ChangeFrontMaterial().SetShininess (aClamped);
|
||||
break;
|
||||
}
|
||||
case AIS_MaterialEditorWidgetAction_CommonAmbient:
|
||||
{
|
||||
Graphic3d_Vec3 aVec = myAspects->FrontMaterial().AmbientColor();
|
||||
if (myComponent == -1)
|
||||
{
|
||||
const float aMaxComp = aVec.maxComp() > 0.0f ? aVec.maxComp() : 1.0f;
|
||||
aVec = (aVec / aMaxComp) * aClamped;
|
||||
}
|
||||
else
|
||||
{
|
||||
aVec[myComponent] = aClamped;
|
||||
}
|
||||
myAspects->ChangeFrontMaterial().SetAmbientColor (Quantity_Color (aVec));
|
||||
break;
|
||||
}
|
||||
case AIS_MaterialEditorWidgetAction_CommonDiffuse:
|
||||
{
|
||||
Graphic3d_Vec3 aVec = myAspects->FrontMaterial().DiffuseColor();
|
||||
if (myComponent == -1)
|
||||
{
|
||||
const float aMaxComp = aVec.maxComp() > 0.0f ? aVec.maxComp() : 1.0f;
|
||||
aVec = (aVec / aMaxComp) * aClamped;
|
||||
}
|
||||
else
|
||||
{
|
||||
aVec[myComponent] = aClamped;
|
||||
}
|
||||
myAspects->ChangeFrontMaterial().SetDiffuseColor (Quantity_Color (aVec));
|
||||
break;
|
||||
}
|
||||
case AIS_MaterialEditorWidgetAction_CommonSpecular:
|
||||
{
|
||||
Graphic3d_Vec3 aVec = myAspects->FrontMaterial().SpecularColor();
|
||||
if (myComponent == -1)
|
||||
{
|
||||
const float aMaxComp = aVec.maxComp() > 0.0f ? aVec.maxComp() : 1.0f;
|
||||
aVec = (aVec / aMaxComp) * aClamped;
|
||||
}
|
||||
else
|
||||
{
|
||||
aVec[myComponent] = aClamped;
|
||||
}
|
||||
myAspects->ChangeFrontMaterial().SetSpecularColor (Quantity_Color (aVec));
|
||||
break;
|
||||
}
|
||||
case AIS_MaterialEditorWidgetAction_CommonEmissive:
|
||||
{
|
||||
Graphic3d_Vec3 aVec = myAspects->FrontMaterial().EmissiveColor();
|
||||
if (myComponent == -1)
|
||||
{
|
||||
const float aMaxComp = aVec.maxComp() > 0.0f ? aVec.maxComp() : 1.0f;
|
||||
aVec = (aVec / aMaxComp) * aClamped;
|
||||
}
|
||||
else
|
||||
{
|
||||
aVec[myComponent] = aClamped;
|
||||
}
|
||||
myAspects->ChangeFrontMaterial().SetEmissiveColor (Quantity_Color (aVec));
|
||||
break;
|
||||
}
|
||||
case AIS_MaterialEditorWidgetAction_NB:
|
||||
return;
|
||||
}
|
||||
|
||||
for (AIS_ListOfInteractive::Iterator aPrsIter (aWidget->ListOfAttachments()); aPrsIter.More(); aPrsIter.Next())
|
||||
{
|
||||
aPrsIter.Value()->SynchronizeAspects();
|
||||
}
|
||||
aWidget->GetContext()->Redisplay (aWidget, false);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
//function : VMaterialWidget
|
||||
//purpose :
|
||||
//==============================================================================
|
||||
static Standard_Integer VMaterialWidget (Draw_Interpretor& ,
|
||||
Standard_Integer theArgNb,
|
||||
const char** theArgVec)
|
||||
{
|
||||
const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
|
||||
if (aCtx.IsNull())
|
||||
{
|
||||
std::cout << "Error: no active view\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
TCollection_AsciiString aWidgetName;
|
||||
Handle(AIS_MaterialEditorWidget) aWidget;
|
||||
AIS_ListOfInteractive aPrsList;
|
||||
Standard_Integer aWidth = -1;
|
||||
for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
|
||||
{
|
||||
TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
|
||||
if (anArgCase == "-width"
|
||||
&& anArgIter + 1 < theArgNb)
|
||||
{
|
||||
aWidth = Draw::Atoi (theArgVec[++anArgIter]);
|
||||
}
|
||||
else if (aWidgetName.IsEmpty())
|
||||
{
|
||||
aWidgetName = theArgVec[anArgIter];
|
||||
Handle(AIS_InteractiveObject) aPrs;
|
||||
if (GetMapOfAIS().Find2 (aWidgetName, aPrs))
|
||||
{
|
||||
aWidget = Handle(AIS_MaterialEditorWidget)::DownCast (aPrs);
|
||||
}
|
||||
if (aWidget.IsNull())
|
||||
{
|
||||
aWidget = new AIS_MaterialEditorWidget();
|
||||
}
|
||||
else
|
||||
{
|
||||
aWidget->SetToUpdate();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Handle(AIS_InteractiveObject) aPrs;
|
||||
if (GetMapOfAIS().Find2 (theArgVec[anArgIter], aPrs))
|
||||
{
|
||||
aPrsList.Append (aPrs);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Syntax error: object '" << theArgVec[anArgIter] << "' is not displayed\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aWidget.IsNull())
|
||||
{
|
||||
std::cout << "Syntax error: wrong number of arguments\n";
|
||||
return 1;
|
||||
}
|
||||
if (aWidth != -1)
|
||||
{
|
||||
aWidget->SetWidgetWidth (aWidth);
|
||||
}
|
||||
aWidget->Attach (aPrsList);
|
||||
|
||||
ViewerTest::Display (aWidgetName, aWidget);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
//function : envlutWriteToFile
|
||||
//purpose :
|
||||
@@ -2334,10 +1558,6 @@ void ViewerTest::OpenGlCommands(Draw_Interpretor& theCommands)
|
||||
"\n\t\t: or dumped into specified file."
|
||||
"\n\t\t: * can be used to refer to complete list of standard colors.",
|
||||
__FILE__, VListColors, aGroup);
|
||||
theCommands.Add("vmaterialwidget",
|
||||
"vmaterialwidget widgetName prsName1 [prsName2 [...]]"
|
||||
"\n\t\t: Create a widget for configuring material properties of specified presentations.",
|
||||
__FILE__, VMaterialWidget, aGroup);
|
||||
theCommands.Add("vgenenvlut",
|
||||
"vgenenvlut [-size size = 128] [-nbsamples nbsamples = 1024]"
|
||||
"\n\t\t: Generates PBR environment look up table."
|
||||
|
Reference in New Issue
Block a user