2016-03-15 17:26:56 +05:00
|
|
|
// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
|
2013-11-19 17:55:25 +06:00
|
|
|
//
|
|
|
|
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
|
|
|
|
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
|
|
|
|
//
|
|
|
|
// This library is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU Lesser General Public
|
|
|
|
// License as published by the Free Software Foundation; either
|
2014-02-18 12:44:41 +06:00
|
|
|
// version 2.1 of the License, or (at your option) any later version.
|
2013-11-19 17:55:25 +06:00
|
|
|
//
|
|
|
|
// This library is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
// Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
|
|
// License along with this library; if not, write to the Free Software
|
|
|
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
//
|
|
|
|
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
#include <GEOMUtils_Hatcher.hxx>
|
|
|
|
|
|
|
|
#include <BRep_Tool.hxx>
|
|
|
|
#include <BRepTools.hxx>
|
|
|
|
#include <Geom2d_Line.hxx>
|
|
|
|
#include <Geom2d_TrimmedCurve.hxx>
|
|
|
|
#include <Geom2dAdaptor_Curve.hxx>
|
|
|
|
#include <TopExp_Explorer.hxx>
|
|
|
|
#include <TopoDS.hxx>
|
|
|
|
#include <TopoDS_Edge.hxx>
|
|
|
|
#include <HatchGen_Domain.hxx>
|
|
|
|
|
|
|
|
|
|
|
|
static Standard_Real IntersectorConfusion = 1.e-10; // -8;
|
|
|
|
static Standard_Real IntersectorTangency = 1.e-10; // -8;
|
|
|
|
static Standard_Real HatcherConfusion2d = 1.e-8;
|
|
|
|
static Standard_Real HatcherConfusion3d = 1.e-8;
|
|
|
|
// VTK uses float numbers - Precision::Infinite() is double and
|
|
|
|
// can not be accepted.
|
|
|
|
static float InfiniteValue = 1e38;
|
|
|
|
|
|
|
|
//=======================================================================
|
|
|
|
//function : GEOMUtils_Hatcher
|
|
|
|
//purpose :
|
|
|
|
//=======================================================================
|
2014-06-04 17:17:38 +06:00
|
|
|
GEOMUtils::Hatcher::Hatcher(const TopoDS_Face &theFace)
|
2013-11-19 17:55:25 +06:00
|
|
|
: myHatcher(Geom2dHatch_Intersector (IntersectorConfusion, IntersectorTangency),
|
|
|
|
HatcherConfusion2d, HatcherConfusion3d,
|
|
|
|
Standard_True, Standard_False),
|
|
|
|
myFace (theFace),
|
|
|
|
myIsDone (Standard_False),
|
|
|
|
myUMin (0.),
|
|
|
|
myUMax (0.),
|
|
|
|
myVMin (0.),
|
|
|
|
myVMax (0.)
|
|
|
|
{
|
|
|
|
// Get bounds.
|
|
|
|
BRepTools::UVBounds (theFace, myUMin, myUMax, myVMin, myVMax);
|
|
|
|
|
|
|
|
Standard_Boolean InfiniteUMin = Precision::IsNegativeInfinite (myUMin);
|
|
|
|
Standard_Boolean InfiniteUMax = Precision::IsPositiveInfinite (myUMax);
|
|
|
|
Standard_Boolean InfiniteVMin = Precision::IsNegativeInfinite (myVMin);
|
|
|
|
Standard_Boolean InfiniteVMax = Precision::IsPositiveInfinite (myVMax);
|
|
|
|
|
|
|
|
if (InfiniteUMin && InfiniteUMax) {
|
|
|
|
myUMin = - InfiniteValue;
|
|
|
|
myUMax = InfiniteValue;
|
|
|
|
} else if (InfiniteUMin) {
|
|
|
|
myUMin = myUMax - InfiniteValue;
|
|
|
|
} else if (InfiniteUMax) {
|
|
|
|
myUMax = myUMin + InfiniteValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (InfiniteVMin && InfiniteVMax) {
|
|
|
|
myVMin = - InfiniteValue;
|
|
|
|
myVMax = InfiniteValue;
|
|
|
|
} else if (InfiniteVMin) {
|
|
|
|
myVMin = myVMax - InfiniteValue;
|
|
|
|
} else if (InfiniteVMax) {
|
|
|
|
myVMax = myVMin + InfiniteValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add edges
|
|
|
|
TopExp_Explorer anExpEdges(theFace, TopAbs_EDGE);
|
|
|
|
const Standard_Real aParamTol = Precision::PConfusion();
|
|
|
|
|
|
|
|
for (; anExpEdges.More(); anExpEdges.Next()) {
|
|
|
|
const TopoDS_Edge& anEdge = TopoDS::Edge (anExpEdges.Current());
|
|
|
|
Standard_Real U1, U2;
|
|
|
|
const Handle(Geom2d_Curve) PCurve =
|
|
|
|
BRep_Tool::CurveOnSurface (anEdge, theFace, U1, U2);
|
|
|
|
|
|
|
|
if (PCurve.IsNull()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (U1 == U2) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-- Test if a TrimmedCurve is necessary
|
|
|
|
if(Abs(PCurve->FirstParameter() - U1) <= aParamTol &&
|
|
|
|
Abs(PCurve->LastParameter() - U2) <= aParamTol) {
|
|
|
|
myHatcher.AddElement(PCurve, anEdge.Orientation());
|
|
|
|
} else {
|
|
|
|
if (!PCurve->IsPeriodic()) {
|
|
|
|
Handle(Geom2d_TrimmedCurve) TrimPCurve =
|
|
|
|
Handle(Geom2d_TrimmedCurve)::DownCast(PCurve);
|
|
|
|
|
|
|
|
if (!TrimPCurve.IsNull()) {
|
|
|
|
Handle(Geom2d_Curve) aBasisCurve = TrimPCurve->BasisCurve();
|
|
|
|
|
|
|
|
if (aBasisCurve->FirstParameter() - U1 > aParamTol ||
|
|
|
|
U2 - aBasisCurve->LastParameter() > aParamTol) {
|
|
|
|
myHatcher.AddElement (PCurve, anEdge.Orientation());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (PCurve->FirstParameter() - U1 > aParamTol) {
|
|
|
|
U1 = PCurve->FirstParameter();
|
|
|
|
}
|
|
|
|
if (U2 - PCurve->LastParameter() > aParamTol) {
|
|
|
|
U2=PCurve->LastParameter();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Handle (Geom2d_TrimmedCurve) TrimPCurve =
|
|
|
|
new Geom2d_TrimmedCurve (PCurve, U1, U2);
|
|
|
|
|
|
|
|
myHatcher.AddElement (TrimPCurve, anEdge.Orientation());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//=======================================================================
|
|
|
|
//function : Init
|
|
|
|
//purpose :
|
|
|
|
//=======================================================================
|
2014-06-04 17:17:38 +06:00
|
|
|
void GEOMUtils::Hatcher::Init(const Standard_Integer theNbIsos)
|
2013-11-19 17:55:25 +06:00
|
|
|
{
|
|
|
|
Init(theNbIsos, theNbIsos);
|
|
|
|
}
|
|
|
|
|
|
|
|
//=======================================================================
|
|
|
|
//function : Init
|
|
|
|
//purpose :
|
|
|
|
//=======================================================================
|
2014-06-04 17:17:38 +06:00
|
|
|
void GEOMUtils::Hatcher::Init(const Standard_Integer theNbIsoU,
|
|
|
|
const Standard_Integer theNbIsoV)
|
2013-11-19 17:55:25 +06:00
|
|
|
{
|
|
|
|
// Initialize data.
|
|
|
|
Clear();
|
|
|
|
|
|
|
|
if (theNbIsoU > 0 || theNbIsoV > 0) {
|
|
|
|
Standard_Integer IIso;
|
|
|
|
Standard_Real DeltaU = Abs (myUMax - myUMin);
|
|
|
|
Standard_Real DeltaV = Abs (myVMax - myVMin);
|
|
|
|
Standard_Real confusion = Min (DeltaU, DeltaV) * myHatcher.Confusion3d();
|
|
|
|
|
|
|
|
myHatcher.Confusion3d (confusion);
|
|
|
|
|
|
|
|
if (theNbIsoU > 0) {
|
|
|
|
myUPrm = new TColStd_HArray1OfReal (1, theNbIsoU);
|
|
|
|
myUInd = new TColStd_HArray1OfInteger(1, theNbIsoU, 0);
|
|
|
|
|
|
|
|
Standard_Real StepU = DeltaU / (Standard_Real) theNbIsoU;
|
|
|
|
|
|
|
|
if (StepU > confusion) {
|
|
|
|
Standard_Real UPrm = myUMin + StepU / 2.;
|
|
|
|
gp_Dir2d Dir (0., 1.);
|
|
|
|
|
|
|
|
for (IIso = 1; IIso <= theNbIsoU; IIso++) {
|
|
|
|
myUPrm->SetValue(IIso, UPrm);
|
|
|
|
gp_Pnt2d Ori (UPrm, 0.);
|
|
|
|
Geom2dAdaptor_Curve HCur (new Geom2d_Line (Ori, Dir));
|
|
|
|
myUInd->SetValue(IIso, myHatcher.AddHatching(HCur));
|
|
|
|
UPrm += StepU;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (theNbIsoV > 0) {
|
|
|
|
myVPrm = new TColStd_HArray1OfReal (1, theNbIsoV);
|
|
|
|
myVInd = new TColStd_HArray1OfInteger(1, theNbIsoV, 0);
|
|
|
|
|
|
|
|
Standard_Real StepV = DeltaV / (Standard_Real) theNbIsoV;
|
|
|
|
|
|
|
|
if (StepV > confusion) {
|
|
|
|
Standard_Real VPrm = myVMin + StepV / 2.;
|
|
|
|
gp_Dir2d Dir (1., 0.);
|
|
|
|
|
|
|
|
for (IIso = 1; IIso <= theNbIsoV; IIso++) {
|
|
|
|
myVPrm->SetValue(IIso, VPrm);
|
|
|
|
gp_Pnt2d Ori (0., VPrm);
|
|
|
|
Geom2dAdaptor_Curve HCur (new Geom2d_Line (Ori, Dir));
|
|
|
|
myVInd->SetValue(IIso, myHatcher.AddHatching(HCur));
|
|
|
|
VPrm += StepV;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//=======================================================================
|
|
|
|
//function : Init
|
|
|
|
//purpose :
|
|
|
|
//=======================================================================
|
2014-06-04 17:17:38 +06:00
|
|
|
void GEOMUtils::Hatcher::Init(const GeomAbs_IsoType theIsoType,
|
|
|
|
const Standard_Real theParameter)
|
2013-11-19 17:55:25 +06:00
|
|
|
{
|
|
|
|
// Initialize data.
|
|
|
|
Clear();
|
|
|
|
|
|
|
|
if (theIsoType == GeomAbs_IsoU || theIsoType == GeomAbs_IsoV) {
|
|
|
|
const Standard_Boolean isIsoU = (theIsoType == GeomAbs_IsoU);
|
|
|
|
Handle(TColStd_HArray1OfReal) &aPrm = (isIsoU ? myUPrm : myVPrm);
|
|
|
|
Handle(TColStd_HArray1OfInteger) &anInd = (isIsoU ? myUInd : myVInd);
|
|
|
|
Handle(Geom2d_Line) aLine;
|
|
|
|
|
|
|
|
aPrm = new TColStd_HArray1OfReal (1, 1);
|
|
|
|
anInd = new TColStd_HArray1OfInteger(1, 1);
|
|
|
|
aPrm->SetValue(1, theParameter);
|
|
|
|
|
|
|
|
if (isIsoU) {
|
|
|
|
// U-isoline
|
|
|
|
gp_Dir2d aDir (0., 1.);
|
|
|
|
gp_Pnt2d anOri(theParameter, 0.);
|
|
|
|
|
|
|
|
aLine = new Geom2d_Line(anOri, aDir);
|
|
|
|
} else {
|
|
|
|
// V-isoline
|
|
|
|
gp_Dir2d aDir (1., 0.);
|
|
|
|
gp_Pnt2d anOri(0., theParameter);
|
|
|
|
|
|
|
|
aLine = new Geom2d_Line(anOri, aDir);
|
|
|
|
}
|
|
|
|
|
|
|
|
Geom2dAdaptor_Curve aGACurve (aLine);
|
|
|
|
|
|
|
|
anInd->SetValue(1, myHatcher.AddHatching(aGACurve));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//=======================================================================
|
|
|
|
//function : Perform
|
|
|
|
//purpose :
|
|
|
|
//=======================================================================
|
2014-06-04 17:17:38 +06:00
|
|
|
void GEOMUtils::Hatcher::Perform()
|
2013-11-19 17:55:25 +06:00
|
|
|
{
|
|
|
|
myHatcher.Trim();
|
|
|
|
|
|
|
|
// Compute domains.
|
|
|
|
Standard_Integer i;
|
|
|
|
Standard_Integer anIndex;
|
|
|
|
|
|
|
|
if (myUInd.IsNull() == Standard_False) {
|
|
|
|
for (i = myUInd->Lower() ; i <= myUInd->Upper() ; i++) {
|
|
|
|
anIndex = myUInd->Value(i);
|
|
|
|
|
|
|
|
if (anIndex != 0) {
|
|
|
|
if (myHatcher.TrimDone(anIndex) && !myHatcher.TrimFailed(anIndex)) {
|
|
|
|
myHatcher.ComputeDomains(anIndex);
|
|
|
|
|
|
|
|
if (!myIsDone) {
|
|
|
|
myIsDone = (myHatcher.NbDomains(anIndex) > 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (myVInd.IsNull() == Standard_False) {
|
|
|
|
for (i = myVInd->Lower() ; i <= myVInd->Upper() ; i++) {
|
|
|
|
anIndex = myVInd->Value(i);
|
|
|
|
|
|
|
|
if (anIndex != 0) {
|
|
|
|
if (myHatcher.TrimDone(anIndex) && !myHatcher.TrimFailed(anIndex)) {
|
|
|
|
myHatcher.ComputeDomains(anIndex);
|
|
|
|
|
|
|
|
if (!myIsDone) {
|
|
|
|
myIsDone = (myHatcher.NbDomains(anIndex) > 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//=======================================================================
|
|
|
|
//function : GetNbDomains
|
|
|
|
//purpose :
|
|
|
|
//=======================================================================
|
2014-06-04 17:17:38 +06:00
|
|
|
Standard_Integer GEOMUtils::Hatcher::GetNbDomains
|
2013-11-19 17:55:25 +06:00
|
|
|
(const Standard_Integer theHatchingIndex) const
|
|
|
|
{
|
|
|
|
Standard_Integer aResult = -1;
|
|
|
|
|
|
|
|
if (myIsDone && myHatcher.IsDone(theHatchingIndex)) {
|
|
|
|
aResult = myHatcher.NbDomains(theHatchingIndex);
|
|
|
|
}
|
|
|
|
|
|
|
|
return aResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
//=======================================================================
|
|
|
|
//function : GetDomain
|
|
|
|
//purpose :
|
|
|
|
//=======================================================================
|
2014-06-04 17:17:38 +06:00
|
|
|
Standard_Boolean GEOMUtils::Hatcher::GetDomain
|
2013-11-19 17:55:25 +06:00
|
|
|
(const Standard_Integer theHatchingIndex,
|
|
|
|
const Standard_Integer theDomainIndex,
|
|
|
|
Standard_Real &theParam1,
|
|
|
|
Standard_Real &theParam2) const
|
|
|
|
{
|
|
|
|
Standard_Boolean isOK = Standard_False;
|
|
|
|
|
|
|
|
if (theDomainIndex > 0) {
|
|
|
|
const Standard_Integer aNbDomains = GetNbDomains(theHatchingIndex);
|
|
|
|
|
|
|
|
if (theDomainIndex <= aNbDomains) {
|
|
|
|
const HatchGen_Domain& aDomain =
|
|
|
|
myHatcher.Domain (theHatchingIndex, theDomainIndex);
|
|
|
|
|
|
|
|
if (aDomain.HasFirstPoint()) {
|
|
|
|
theParam1 = aDomain.FirstPoint().Parameter();
|
|
|
|
} else {
|
|
|
|
theParam1 = myVMin - InfiniteValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aDomain.HasSecondPoint()) {
|
|
|
|
theParam2 = aDomain.SecondPoint().Parameter();
|
|
|
|
} else {
|
|
|
|
theParam2 = myVMax + InfiniteValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
isOK = Standard_True;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return isOK;
|
|
|
|
}
|
|
|
|
|
|
|
|
//=======================================================================
|
|
|
|
//function : IsDomainInfinite
|
|
|
|
//purpose :
|
|
|
|
//=======================================================================
|
2014-06-04 17:17:38 +06:00
|
|
|
Standard_Boolean GEOMUtils::Hatcher::IsDomainInfinite
|
2013-11-19 17:55:25 +06:00
|
|
|
(const Standard_Integer theHatchingIndex,
|
|
|
|
const Standard_Integer theDomainIndex) const
|
|
|
|
{
|
|
|
|
Standard_Boolean isInfinite = Standard_False;
|
|
|
|
|
|
|
|
if (theDomainIndex > 0) {
|
|
|
|
const Standard_Integer aNbDomains = GetNbDomains(theHatchingIndex);
|
|
|
|
|
|
|
|
if (theDomainIndex <= aNbDomains) {
|
|
|
|
const HatchGen_Domain& aDomain =
|
|
|
|
myHatcher.Domain (theHatchingIndex, theDomainIndex);
|
|
|
|
|
|
|
|
if (!aDomain.HasFirstPoint() || !aDomain.HasSecondPoint()) {
|
|
|
|
isInfinite = Standard_True;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return isInfinite;
|
|
|
|
}
|
|
|
|
|
|
|
|
//=======================================================================
|
|
|
|
//function : GetHatching
|
|
|
|
//purpose :
|
|
|
|
//=======================================================================
|
2014-06-04 17:17:38 +06:00
|
|
|
const Handle(Geom2d_Curve) &GEOMUtils::Hatcher::GetHatching
|
2013-11-19 17:55:25 +06:00
|
|
|
(const Standard_Integer theHatchingIndex) const
|
|
|
|
{
|
|
|
|
const Geom2dAdaptor_Curve &aGACurve =
|
|
|
|
myHatcher.HatchingCurve(theHatchingIndex);
|
|
|
|
|
|
|
|
return aGACurve.Curve();
|
|
|
|
}
|
|
|
|
|
|
|
|
//=======================================================================
|
|
|
|
//function : Clear
|
|
|
|
//purpose :
|
|
|
|
//=======================================================================
|
2014-06-04 17:17:38 +06:00
|
|
|
void GEOMUtils::Hatcher::Clear()
|
2013-11-19 17:55:25 +06:00
|
|
|
{
|
|
|
|
myIsDone = Standard_False;
|
|
|
|
myUPrm.Nullify();
|
|
|
|
myVPrm.Nullify();
|
|
|
|
myUInd.Nullify();
|
|
|
|
myVInd.Nullify();
|
|
|
|
myHatcher.ClrHatchings();
|
|
|
|
}
|