Loading files
3d097a032This file is pinned to the selected release. Download the original to open it in your design tool.
// Created on: 1992-12-21
// Created by: Didier PIFFAULT
// Copyright (c) 1992-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <gp_XYZ.hxx>
#include <gp_Vec.hxx>
#include <Standard_Integer.hxx>
#include <NCollection_List.hxx>
#include <Bnd_Box.hxx>
#include <Intf_Tool.hxx>
#include <Bnd_BoundSortBox.hxx>
#include <gp_Lin.hxx>
#include <NCollection_Array1.hxx>
#include <Intf_SectionPoint.hxx>
#include <NCollection_Sequence.hxx>
#include <Intf_TangentZone.hxx>
#include <Intf.hxx>
#include <Extrema_ExtElC.hxx>
#include <Extrema_POnCurv.hxx>
static const int Pourcent3[4] = {0, 1, 2, 0};
static bool IsInSegment(const gp_Vec& P1P2,
const gp_Vec& P1P,
const double NP1P2,
double& Param,
const double Tolerance)
{
if (NP1P2 < Precision::Computational())
return false;
Param = P1P2.Dot(P1P);
Param /= NP1P2;
if (Param > (NP1P2 + Tolerance))
return (false);
if (Param < (-Tolerance))
return (false);
Param /= NP1P2;
if (Param < 0.0)
Param = 0.0;
if (Param > 1.0)
Param = 1.0;
return (true);
}
//=================================================================================================
Intf_InterferencePolygonPolyhedron::Intf_InterferencePolygonPolyhedron()
: Intf_Interference(false),
BeginOfClosedPolygon(false),
iLin(0)
{
}
//=======================================================================
// function : Intf_InterferencePolygonPolyhedron
// purpose : Construct and compute an interference between a Polygon3d
// and a Polyhedron.
//=======================================================================
Intf_InterferencePolygonPolyhedron::Intf_InterferencePolygonPolyhedron(const Polygon3d& thePolyg,
const Polyhedron& thePolyh)
: Intf_Interference(false),
BeginOfClosedPolygon(false),
iLin(0)
{
Tolerance = ToolPolygon3d::DeflectionOverEstimation(thePolyg)
+ ToolPolyh::DeflectionOverEstimation(thePolyh);
if (Tolerance == 0.)
Tolerance = Epsilon(1000.);
if (!ToolPolygon3d::Bounding(thePolyg).IsOut(ToolPolyh::Bounding(thePolyh)))
{
Interference(thePolyg, thePolyh);
}
}
Intf_InterferencePolygonPolyhedron::Intf_InterferencePolygonPolyhedron(const Polygon3d& thePolyg,
const Polyhedron& thePolyh,
Bnd_BoundSortBox& PolyhGrid)
: Intf_Interference(false),
BeginOfClosedPolygon(false),
iLin(0)
{
Tolerance = ToolPolygon3d::DeflectionOverEstimation(thePolyg)
+ ToolPolyh::DeflectionOverEstimation(thePolyh);
if (Tolerance == 0.)
Tolerance = Epsilon(1000.);
if (!ToolPolygon3d::Bounding(thePolyg).IsOut(ToolPolyh::Bounding(thePolyh)))
{
Interference(thePolyg, thePolyh, PolyhGrid);
}
}
//=======================================================================
// function : Intf_InterferencePolygonPolyhedron
// purpose : Construct and compute an interference between a Straight
// Line and a Polyhedron.
//=======================================================================
Intf_InterferencePolygonPolyhedron::Intf_InterferencePolygonPolyhedron(const gp_Lin& theLin,
const Polyhedron& thePolyh)
: Intf_Interference(false),
BeginOfClosedPolygon(false),
iLin(0)
{
Tolerance = ToolPolyh::DeflectionOverEstimation(thePolyh);
if (Tolerance == 0.)
Tolerance = Epsilon(1000.);
BeginOfClosedPolygon = false;
Bnd_BoundSortBox PolyhGrid;
PolyhGrid.Initialize(ToolPolyh::Bounding(thePolyh), ToolPolyh::ComponentsBounding(thePolyh));
int indTri;
iLin = 0;
Bnd_Box bofLin;
Intf_Tool btoo;
btoo.LinBox(theLin, ToolPolyh::Bounding(thePolyh), bofLin);
NCollection_List<int>::Iterator iCl(PolyhGrid.Compare(bofLin));
while (iCl.More())
{
indTri = iCl.Value();
Intersect(theLin.Location(),
theLin.Location().Translated(gp_Vec(theLin.Direction())),
true,
indTri,
thePolyh);
iCl.Next();
}
}
//=======================================================================
// function : Intf_InterferencePolygonPolyhedron
// purpose : Construct and compute an interference between the Straights
// Lines in <Obje> and the Polyhedron <thePolyh>.
//=======================================================================
Intf_InterferencePolygonPolyhedron::Intf_InterferencePolygonPolyhedron(
const NCollection_Array1<gp_Lin>& theLins,
const Polyhedron& thePolyh)
: Intf_Interference(false),
BeginOfClosedPolygon(false),
iLin(0)
{
Tolerance = ToolPolyh::DeflectionOverEstimation(thePolyh);
if (Tolerance == 0.)
Tolerance = Epsilon(1000.);
Bnd_Box bofLin;
Intf_Tool bToo;
BeginOfClosedPolygon = false;
Bnd_BoundSortBox PolyhGrid;
PolyhGrid.Initialize(ToolPolyh::Bounding(thePolyh), ToolPolyh::ComponentsBounding(thePolyh));
int indTri;
for (iLin = 1; iLin <= theLins.Length(); iLin++)
{
bToo.LinBox(theLins(iLin), ToolPolyh::Bounding(thePolyh), bofLin);
NCollection_List<int>::Iterator ilC(PolyhGrid.Compare(bofLin));
while (ilC.More())
{
indTri = ilC.Value();
Intersect(theLins(iLin).Location(),
theLins(iLin).Location().Translated(gp_Vec(theLins(iLin).Direction())),
true,
indTri,
thePolyh);
ilC.Next();
}
}
}
//=================================================================================================
void Intf_InterferencePolygonPolyhedron::Perform(const Polygon3d& thePolyg,
const Polyhedron& thePolyh)
{
SelfInterference(false);
Tolerance = ToolPolygon3d::DeflectionOverEstimation(thePolyg)
+ ToolPolyh::DeflectionOverEstimation(thePolyh);
if (Tolerance == 0.)
Tolerance = Epsilon(1000.);
if (!ToolPolygon3d::Bounding(thePolyg).IsOut(ToolPolyh::Bounding(thePolyh)))
{
Interference(thePolyg, thePolyh);
}
}
//=================================================================================================
void Intf_InterferencePolygonPolyhedron::Perform(const gp_Lin& theLin, const Polyhedron& thePolyh)
{
SelfInterference(false);
Tolerance = ToolPolyh::DeflectionOverEstimation(thePolyh);
if (Tolerance == 0.)
Tolerance = Epsilon(1000.);
BeginOfClosedPolygon = false;
Bnd_BoundSortBox PolyhGrid;
PolyhGrid.Initialize(ToolPolyh::Bounding(thePolyh), ToolPolyh::ComponentsBounding(thePolyh));
int indTri;
iLin = 0;
Bnd_Box bofLin;
Intf_Tool btoo;
btoo.LinBox(theLin, ToolPolyh::Bounding(thePolyh), bofLin);
NCollection_List<int>::Iterator lCi(PolyhGrid.Compare(bofLin));
while (lCi.More())
{
indTri = lCi.Value();
Intersect(theLin.Location(),
theLin.Location().Translated(gp_Vec(theLin.Direction())),
true,
indTri,
thePolyh);
lCi.Next();
}
}
//=======================================================================
// function : Perform
// purpose : Compute an interference between the Straights
// Lines in <Obje> and the Polyhedron <thePolyh>.
//=======================================================================
void Intf_InterferencePolygonPolyhedron::Perform(const NCollection_Array1<gp_Lin>& theLins,
const Polyhedron& thePolyh)
{
SelfInterference(false);
Tolerance = ToolPolyh::DeflectionOverEstimation(thePolyh);
if (Tolerance == 0.)
Tolerance = Epsilon(1000.);
Bnd_Box bofLin;
Intf_Tool Btoo;
BeginOfClosedPolygon = false;
Bnd_BoundSortBox PolyhGrid;
PolyhGrid.Initialize(ToolPolyh::Bounding(thePolyh), ToolPolyh::ComponentsBounding(thePolyh));
int indTri;
for (iLin = 1; iLin <= theLins.Length(); iLin++)
{
Btoo.LinBox(theLins(iLin), ToolPolyh::Bounding(thePolyh), bofLin);
NCollection_List<int>::Iterator tlC(PolyhGrid.Compare(bofLin));
while (tlC.More())
{
indTri = tlC.Value();
Intersect(theLins(iLin).Location(),
theLins(iLin).Location().Translated(gp_Vec(theLins(iLin).Direction())),
true,
indTri,
thePolyh);
tlC.Next();
}
}
}
//=======================================================================
// function : Interference
// purpose : Compare the boundings between the segment of <Obje>
// and the facets of <thePolyh>.
//=======================================================================
void Intf_InterferencePolygonPolyhedron::Interference(const Polygon3d& thePolyg,
const Polyhedron& thePolyh)
{
Bnd_Box bofSeg;
Bnd_BoundSortBox PolyhGrid;
PolyhGrid.Initialize(ToolPolyh::Bounding(thePolyh), ToolPolyh::ComponentsBounding(thePolyh));
int indTri;
BeginOfClosedPolygon = ToolPolygon3d::Closed(thePolyg);
double defPh = ToolPolyh::DeflectionOverEstimation(thePolyh);
for (iLin = 1; iLin <= ToolPolygon3d::NbSegments(thePolyg); iLin++)
{
bofSeg.SetVoid();
bofSeg.Add(ToolPolygon3d::BeginOfSeg(thePolyg, iLin));
bofSeg.Add(ToolPolygon3d::EndOfSeg(thePolyg, iLin));
bofSeg.Enlarge(ToolPolygon3d::DeflectionOverEstimation(thePolyg));
NCollection_List<int> maliste;
maliste = PolyhGrid.Compare(bofSeg);
NCollection_List<int>::Iterator clt(maliste);
for (; clt.More(); clt.Next())
{
indTri = clt.Value();
gp_Pnt p1 = ToolPolygon3d::BeginOfSeg(thePolyg, iLin);
gp_Pnt p2 = ToolPolygon3d::EndOfSeg(thePolyg, iLin);
int pTri0, pTri1, pTri2;
ToolPolyh::Triangle(thePolyh, indTri, pTri0, pTri1, pTri2);
gp_Pnt Pa = ToolPolyh::Point(thePolyh, pTri0);
gp_Pnt Pb = ToolPolyh::Point(thePolyh, pTri1);
gp_Pnt Pc = ToolPolyh::Point(thePolyh, pTri2);
gp_Vec PaPb(Pa, Pb);
gp_Vec PaPc(Pa, Pc);
gp_Vec Normale = PaPb.Crossed(PaPc);
double Norm_Normale = Normale.Magnitude();
if (Norm_Normale < 1e-14)
continue;
Normale.Multiply(defPh / Norm_Normale);
gp_Pnt p1m = p1.Translated(-Normale);
gp_Pnt p1p = p1.Translated(Normale);
gp_Pnt p2m = p2.Translated(-Normale);
gp_Pnt p2p = p2.Translated(Normale);
Intersect(p1m, p2p, false, indTri, thePolyh);
Intersect(p1p, p2m, false, indTri, thePolyh);
// Intersect(ToolPolygon3d::BeginOfSeg(thePolyg, iLin),
// ToolPolygon3d::EndOfSeg(thePolyg, iLin),
// false, indTri, thePolyh);
}
BeginOfClosedPolygon = false;
}
}
//=======================================================================
// function : Intf_InterferencePolygonPolyhedron
// purpose : Construct and compute an interference between a Straight
// Line and a Polyhedron.
//=======================================================================
Intf_InterferencePolygonPolyhedron::Intf_InterferencePolygonPolyhedron(const gp_Lin& theLin,
const Polyhedron& thePolyh,
Bnd_BoundSortBox& PolyhGrid)
: Intf_Interference(false)
{
Tolerance = ToolPolyh::DeflectionOverEstimation(thePolyh);
if (Tolerance == 0.)
Tolerance = Epsilon(1000.);
BeginOfClosedPolygon = false;
int indTri;
iLin = 0;
Bnd_Box bofLin;
Intf_Tool btoo;
btoo.LinBox(theLin, ToolPolyh::Bounding(thePolyh), bofLin);
NCollection_List<int>::Iterator iCl(PolyhGrid.Compare(bofLin));
while (iCl.More())
{
indTri = iCl.Value();
Intersect(theLin.Location(),
theLin.Location().Translated(gp_Vec(theLin.Direction())),
true,
indTri,
thePolyh);
iCl.Next();
}
}
//=======================================================================
// function : Intf_InterferencePolygonPolyhedron
// purpose : Construct and compute an interference between the Straights
// Lines in <Obje> and the Polyhedron <thePolyh>.
//=======================================================================
Intf_InterferencePolygonPolyhedron::Intf_InterferencePolygonPolyhedron(
const NCollection_Array1<gp_Lin>& theLins,
const Polyhedron& thePolyh,
Bnd_BoundSortBox& PolyhGrid)
: Intf_Interference(false)
{
Tolerance = ToolPolyh::DeflectionOverEstimation(thePolyh);
if (Tolerance == 0.)
Tolerance = Epsilon(1000.);
Bnd_Box bofLin;
Intf_Tool bToo;
BeginOfClosedPolygon = false;
int indTri;
for (iLin = 1; iLin <= theLins.Length(); iLin++)
{
bToo.LinBox(theLins(iLin), ToolPolyh::Bounding(thePolyh), bofLin);
NCollection_List<int>::Iterator ilC(PolyhGrid.Compare(bofLin));
while (ilC.More())
{
indTri = ilC.Value();
Intersect(theLins(iLin).Location(),
theLins(iLin).Location().Translated(gp_Vec(theLins(iLin).Direction())),
true,
indTri,
thePolyh);
ilC.Next();
}
}
}
//=================================================================================================
void Intf_InterferencePolygonPolyhedron::Perform(const Polygon3d& thePolyg,
const Polyhedron& thePolyh,
Bnd_BoundSortBox& PolyhGrid)
{
SelfInterference(false);
Tolerance = ToolPolygon3d::DeflectionOverEstimation(thePolyg)
+ ToolPolyh::DeflectionOverEstimation(thePolyh);
if (Tolerance == 0.)
Tolerance = Epsilon(1000.);
if (!ToolPolygon3d::Bounding(thePolyg).IsOut(ToolPolyh::Bounding(thePolyh)))
{
Interference(thePolyg, thePolyh, PolyhGrid);
}
}
//=================================================================================================
void Intf_InterferencePolygonPolyhedron::Perform(const gp_Lin& theLin,
const Polyhedron& thePolyh,
Bnd_BoundSortBox& PolyhGrid)
{
SelfInterference(false);
Tolerance = ToolPolyh::DeflectionOverEstimation(thePolyh);
if (Tolerance == 0.)
Tolerance = Epsilon(1000.);
BeginOfClosedPolygon = false;
int indTri;
iLin = 0;
Bnd_Box bofLin;
Intf_Tool btoo;
btoo.LinBox(theLin, ToolPolyh::Bounding(thePolyh), bofLin);
NCollection_List<int>::Iterator lCi(PolyhGrid.Compare(bofLin));
while (lCi.More())
{
indTri = lCi.Value();
Intersect(theLin.Location(),
theLin.Location().Translated(gp_Vec(theLin.Direction())),
true,
indTri,
thePolyh);
lCi.Next();
}
}
//=======================================================================
// function : Perform
// purpose : Compute an interference between the Straights
// Lines in <Obje> and the Polyhedron <thePolyh>.
//=======================================================================
void Intf_InterferencePolygonPolyhedron::Perform(const NCollection_Array1<gp_Lin>& theLins,
const Polyhedron& thePolyh,
Bnd_BoundSortBox& PolyhGrid)
{
SelfInterference(false);
Tolerance = ToolPolyh::DeflectionOverEstimation(thePolyh);
if (Tolerance == 0.)
Tolerance = Epsilon(1000.);
Bnd_Box bofLin;
Intf_Tool Btoo;
BeginOfClosedPolygon = false;
int indTri;
for (iLin = 1; iLin <= theLins.Length(); iLin++)
{
Btoo.LinBox(theLins(iLin), ToolPolyh::Bounding(thePolyh), bofLin);
NCollection_List<int>::Iterator tlC(PolyhGrid.Compare(bofLin));
while (tlC.More())
{
indTri = tlC.Value();
Intersect(theLins(iLin).Location(),
theLins(iLin).Location().Translated(gp_Vec(theLins(iLin).Direction())),
true,
indTri,
thePolyh);
tlC.Next();
}
}
}
//=======================================================================
// function : Interference
// purpose : Compare the boundings between the segment of <Obje>
// and the facets of <thePolyh>.
//=======================================================================
void Intf_InterferencePolygonPolyhedron::Interference(const Polygon3d& thePolyg,
const Polyhedron& thePolyh,
Bnd_BoundSortBox& PolyhGrid)
{
Bnd_Box bofSeg;
int indTri;
BeginOfClosedPolygon = ToolPolygon3d::Closed(thePolyg);
for (iLin = 1; iLin <= ToolPolygon3d::NbSegments(thePolyg); iLin++)
{
bofSeg.SetVoid();
bofSeg.Add(ToolPolygon3d::BeginOfSeg(thePolyg, iLin));
bofSeg.Add(ToolPolygon3d::EndOfSeg(thePolyg, iLin));
bofSeg.Enlarge(ToolPolygon3d::DeflectionOverEstimation(thePolyg));
// Modified by MKK - Thu Oct 25 12:40:11 2007
double defPh = ToolPolyh::DeflectionOverEstimation(thePolyh);
NCollection_List<int> maliste;
maliste = PolyhGrid.Compare(bofSeg);
NCollection_List<int>::Iterator clt(maliste);
// Modified by MKK - Thu Oct 25 12:40:11 2007 Begin
gp_Pnt p1, Beg0;
gp_Pnt p2, End0;
if (!maliste.IsEmpty())
{
p1 = ToolPolygon3d::BeginOfSeg(thePolyg, iLin);
p2 = ToolPolygon3d::EndOfSeg(thePolyg, iLin);
Beg0 = p1;
End0 = p2;
}
// Modified by MKK - Thu Oct 25 12:40:11 2007 End
while (clt.More())
{
indTri = clt.Value();
// Modified by MKK - Thu Oct 25 12:40:11 2007 Begin
int pTri[3];
ToolPolyh::Triangle(thePolyh, indTri, pTri[0], pTri[1], pTri[2]);
gp_XYZ triNor; // Vecteur normal.
double triDp = 0.; // Distance polaire.
Intf::PlaneEquation(ToolPolyh::Point(thePolyh, pTri[0]),
ToolPolyh::Point(thePolyh, pTri[1]),
ToolPolyh::Point(thePolyh, pTri[2]),
triNor,
triDp);
// enlarge boundary segment
if (iLin == 1)
{
gp_XYZ dif = p1.XYZ() - p2.XYZ();
double dist = dif.Modulus();
if (dist > gp::Resolution())
{
dif /= dist;
double aCos = dif * triNor;
aCos = fabs(aCos);
if (aCos > gp::Resolution())
{
double shift = defPh / aCos;
Beg0.SetXYZ(p1.XYZ() + dif * shift);
}
}
}
else if (iLin == ToolPolygon3d::NbSegments(thePolyg))
{
gp_XYZ dif = p2.XYZ() - p1.XYZ();
double dist = dif.Modulus();
if (dist > gp::Resolution())
{
dif /= dist;
double aCos = dif * triNor;
aCos = fabs(aCos);
if (aCos > gp::Resolution())
{
double shift = defPh / aCos;
End0.SetXYZ(p2.XYZ() + dif * shift);
}
}
}
double dBegTri = (triNor * Beg0.XYZ()) - triDp; // Distance <p1> plane
double dEndTri = (triNor * End0.XYZ()) - triDp; // Distance <p2> plane
Intersect(Beg0, End0, false, indTri, thePolyh, triNor, triDp, dBegTri, dEndTri);
// Modified by MKK - Thu Oct 25 12:40:11 2007 End
clt.Next();
}
BeginOfClosedPolygon = false;
}
}
//=======================================================================
// function : Intersect
// purpose : Compute the intersection between the segment or the line
// and the triangle <TTri>.
//=======================================================================
#if 0
void Intf_InterferencePolygonPolyhedron::Intersect
(const gp_Pnt& BegO, const gp_Pnt& EndO, const bool Infinite,
const int TTri, const Polyhedron& thePolyh)
{
int pTri0,pTri1,pTri2;
ToolPolyh::Triangle(thePolyh, TTri, pTri0, pTri1, pTri2);
gp_Pnt Pa=ToolPolyh::Point(thePolyh, pTri0);
gp_Pnt Pb=ToolPolyh::Point(thePolyh, pTri1);
gp_Pnt Pc=ToolPolyh::Point(thePolyh, pTri2);
gp_Vec PaPb(Pa,Pb);
gp_Vec PaPc(Pa,Pc);
gp_Vec Normale = PaPb.Crossed(PaPc);
double Norm_Normale=Normale.Magnitude();
if(Norm_Normale<1e-14)
return;
//-- Equation du Plan
double A=Normale.X()/Norm_Normale;
double B=Normale.Y()/Norm_Normale;
double C=Normale.Z()/Norm_Normale;
double D=-(A*Pa.X()+B*Pa.Y()+C*Pa.Z());
gp_Vec BegOEndO(BegO,EndO);
double Norm_BegOEndO=BegOEndO.Magnitude();
if(Norm_BegOEndO<1e-14)
return;
double Lx=BegOEndO.X()/Norm_BegOEndO;
double Ly=BegOEndO.Y()/Norm_BegOEndO;
double Lz=BegOEndO.Z()/Norm_BegOEndO;
double Vd=A*Lx+B*Ly+C*Lz; //-- DirLigne . NormalePlan
if(Vd==0) { //-- Droite parallele au plan
return;
}
//-- Calcul du parametre sur la ligne
double t=-(A*BegO.X()+B*BegO.Y()+C*BegO.Z()+D) / Vd;
double tol=1e-8; //-- Deflection sur le triangle
if(t<-tol || t>(Norm_BegOEndO+tol)) {
if(Infinite==false) {
return;
}
}
//-- On a une intersection droite plan
//-- On teste si c est dans le triangle
gp_Pnt PRes(BegO.X()+t*Lx,BegO.Y()+t*Ly,BegO.Z()+t*Lz);
double AbsA=A; if(AbsA<0) AbsA=-AbsA;
double AbsB=B; if(AbsB<0) AbsB=-AbsB;
double AbsC=C; if(AbsC<0) AbsC=-AbsC;
double Au,Av,Bu,Bv,Cu,Cv,Pu,Pv;
if(AbsA>AbsB) {
if(AbsA>AbsC) {
//-- Projeter selon X
Au=Pa.Y(); Bu=Pb.Y(); Cu=Pc.Y(); Pu=PRes.Y();
Av=Pa.Z(); Bv=Pb.Z(); Cv=Pc.Z(); Pv=PRes.Z();
}
else {
//-- Projeter selon Z
Au=Pa.Y(); Bu=Pb.Y(); Cu=Pc.Y(); Pu=PRes.Y();
Av=Pa.X(); Bv=Pb.X(); Cv=Pc.X(); Pv=PRes.X();
}
}
else {
if(AbsB>AbsC) {
//-- projeter selon Y
Au=Pa.Z(); Bu=Pb.Z(); Cu=Pc.Z(); Pu=PRes.Z();
Av=Pa.X(); Bv=Pb.X(); Cv=Pc.X(); Pv=PRes.X();
}
else {
//-- projeter selon Z
Au=Pa.Y(); Bu=Pb.Y(); Cu=Pc.Y(); Pu=PRes.Y();
Av=Pa.X(); Bv=Pb.X(); Cv=Pc.X(); Pv=PRes.X();
}
}
double ABu=Bu-Au; double ABv=Bv-Av;
double ACu=Cu-Au; double ACv=Cv-Av;
double BCu=Cu-Bu; double BCv=Cv-Bv;
double t1,t2;
//-- Test sur AB et C
t1=-ABv*Cu + ABu*Cv;
t2=-ABv*Pu + ABu*Pv;
if(t1<0) { if(t2>0) return; } else { if(t2<0) return; }
//-- Test sur AC et B
t1=-ACv*Bu + ACu*Bv;
t2=-ACv*Pu + ACu*Pv;
if(t1<0) { if(t2>0) return; } else { if(t2<0) return; }
//-- Test sur BC et A
t1=-BCv*Au + BCu*Av;
t2=-BCv*Pu + BCu*Pv;
if(t1<0) { if(t2>0) return; } else { if(t2<0) return; }
Intf_SectionPoint SP(PRes,
Intf_EDGE,
0,
iLin, //-- !!!!! VARIABLE STATIQUE
t / Norm_BegOEndO,
Intf_FACE,
TTri, 0, 0.,1.);
mySPoins.Append(SP);
}
#else
void Intf_InterferencePolygonPolyhedron::Intersect(const gp_Pnt& BegO,
const gp_Pnt& EndO,
const bool Infinite,
const int TTri,
const Polyhedron& thePolyh)
{
Intf_PIType typOnG = Intf_EDGE;
double t;
int pTri[3];
ToolPolyh::Triangle(thePolyh, TTri, pTri[0], pTri[1], pTri[2]);
gp_XYZ triNor; // Vecteur normal.
double triDp; // Distance polaire.
Intf::PlaneEquation(ToolPolyh::Point(thePolyh, pTri[0]),
ToolPolyh::Point(thePolyh, pTri[1]),
ToolPolyh::Point(thePolyh, pTri[2]),
triNor,
triDp);
double dBegTri = (triNor * BegO.XYZ()) - triDp; // Distance <BegO> plan
double dEndTri = (triNor * EndO.XYZ()) - triDp; // Distance <EndO> plan
bool NoIntersectionWithTriangle = false;
double param;
t = dBegTri - dEndTri;
if (t >= 1.e-16 || t <= -1.e-16)
param = dBegTri / t;
else
param = dBegTri;
double floatgap = Epsilon(1000.);
if (!Infinite)
{
if (dBegTri <= floatgap && dBegTri >= -floatgap)
{
param = 0.;
typOnG = Intf_VERTEX;
if (BeginOfClosedPolygon)
NoIntersectionWithTriangle = false;
}
else if (dEndTri <= floatgap && dEndTri >= -floatgap)
{
param = 1.;
typOnG = Intf_VERTEX;
NoIntersectionWithTriangle = false;
}
if (param < 0. || param > 1.)
{
NoIntersectionWithTriangle = true;
}
}
if (NoIntersectionWithTriangle == false)
{
gp_XYZ spLieu = BegO.XYZ() + ((EndO.XYZ() - BegO.XYZ()) * param);
double dPiE[3] = {0.0, 0.0, 0.0}, dPtPi[3], sigd;
int is = 0;
int sEdge = -1;
int sVertex = -1;
int tbreak = 0;
{ //-- is = 0
gp_XYZ segT(ToolPolyh::Point(thePolyh, pTri[1]).XYZ()
- ToolPolyh::Point(thePolyh, pTri[0]).XYZ());
gp_XYZ vecP(spLieu - ToolPolyh::Point(thePolyh, pTri[0]).XYZ());
dPtPi[0] = vecP.Modulus();
if (dPtPi[0] <= floatgap)
{
sVertex = 0;
is = 0;
tbreak = 1;
}
else
{
gp_XYZ segT_x_vecP(segT ^ vecP);
double Modulus_segT_x_vecP = segT_x_vecP.Modulus();
sigd = segT_x_vecP * triNor;
if (sigd > floatgap)
sigd = 1.0;
else if (sigd < -floatgap)
sigd = -1.0;
else
{
sigd = 0.0;
}
dPiE[0] = sigd * (Modulus_segT_x_vecP / segT.Modulus());
if (dPiE[0] <= floatgap && dPiE[0] >= -floatgap)
{
sEdge = 0;
is = 0;
tbreak = 1;
}
}
}
if (tbreak == 0)
{ //-- is = 1
gp_XYZ segT(ToolPolyh::Point(thePolyh, pTri[2]).XYZ()
- ToolPolyh::Point(thePolyh, pTri[1]).XYZ());
gp_XYZ vecP(spLieu - ToolPolyh::Point(thePolyh, pTri[1]).XYZ());
dPtPi[1] = vecP.Modulus();
if (dPtPi[1] <= floatgap)
{
sVertex = 1;
is = 1;
tbreak = 1;
}
else
{
gp_XYZ segT_x_vecP(segT ^ vecP);
double Modulus_segT_x_vecP = segT_x_vecP.Modulus();
sigd = segT_x_vecP * triNor;
if (sigd > floatgap)
sigd = 1.0;
else if (sigd < -floatgap)
sigd = -1.0;
else
{
sigd = 0.0;
}
dPiE[1] = sigd * (Modulus_segT_x_vecP / segT.Modulus());
if (dPiE[1] <= floatgap && dPiE[1] >= -floatgap)
{
sEdge = 1;
is = 1;
tbreak = 1;
}
}
}
if (tbreak == 0)
{ //-- is = 2
gp_XYZ segT(ToolPolyh::Point(thePolyh, pTri[0]).XYZ()
- ToolPolyh::Point(thePolyh, pTri[2]).XYZ());
gp_XYZ vecP(spLieu - ToolPolyh::Point(thePolyh, pTri[2]).XYZ());
dPtPi[2] = vecP.Modulus();
if (dPtPi[2] <= floatgap)
{
sVertex = 2;
is = 2;
}
gp_XYZ segT_x_vecP(segT ^ vecP);
double Modulus_segT_x_vecP = segT_x_vecP.Modulus();
sigd = segT_x_vecP * triNor;
if (sigd > floatgap)
sigd = 1.0;
else if (sigd < -floatgap)
sigd = -1.0;
else
{
sigd = 0.0;
}
dPiE[2] = sigd * (Modulus_segT_x_vecP / segT.Modulus());
if (dPiE[2] <= floatgap && dPiE[2] >= -floatgap)
{
sEdge = 2;
is = 2;
}
}
//-- fin for i=0 to 2
// !!cout<<endl;
int triCon, pedg;
if (sVertex > -1)
{
triCon = TTri;
pedg = pTri[Pourcent3[sVertex + 1]];
//-- while (triCon!=0) {
//-- ToolPolyh::TriConnex(thePolyh, triCon,pTri[sVertex],pedg,triCon,pedg);
//-- //-- if (triCon<TTri) return;
//-- if (triCon==TTri) break;
//-- }
Intf_SectionPoint SP(spLieu, typOnG, 0, iLin, param, Intf_VERTEX, pTri[is], 0, 0., 1.);
mySPoins.Append(SP);
}
else if (sEdge > -1)
{
ToolPolyh::TriConnex(thePolyh, TTri, pTri[sEdge], pTri[Pourcent3[sEdge + 1]], triCon, pedg);
//-- if (triCon<=TTri) return; ???????????????????? LBR
// !!cout<<" sEdge "<<endl;
Intf_SectionPoint SP(spLieu,
typOnG,
0,
iLin,
param,
Intf_EDGE,
std::min(pTri[sEdge], pTri[Pourcent3[sEdge + 1]]),
std::max(pTri[sEdge], pTri[Pourcent3[sEdge + 1]]),
0.,
1.);
mySPoins.Append(SP);
}
else if (dPiE[0] > 0. && dPiE[1] > 0. && dPiE[2] > 0.)
{
// !!cout<<" 3 Positifs "<<endl;
Intf_SectionPoint SP(spLieu, typOnG, 0, iLin, param, Intf_FACE, TTri, 0, 0., 1.);
mySPoins.Append(SP);
}
// Modified by Sergey KHROMOV - Fri Dec 7 14:40:11 2001 Begin
// Sometimes triangulation doesn't cover whole the face. In this
// case it is necessary to take into account the deflection between boundary
// isolines of the surface and boundary trianles. Computed value of this
// deflection is contained in thePolyh.
else
{
int i;
for (i = 1; i <= 3; i++)
{
int indP1 = (i == 3) ? pTri[0] : pTri[i];
int indP2 = pTri[i - 1];
if (ToolPolyh::IsOnBound(thePolyh, indP1, indP2))
{
// For boundary line it is necessary to check the border deflection.
double Deflection = ToolPolyh::GetBorderDeflection(thePolyh);
const gp_Pnt& BegP = ToolPolyh::Point(thePolyh, indP1);
const gp_Pnt& EndP = ToolPolyh::Point(thePolyh, indP2);
gp_Vec VecTri(BegP, EndP);
gp_Dir DirTri(VecTri);
gp_Lin LinTri(BegP, DirTri);
gp_Pnt aPOnE(spLieu);
double aDist = LinTri.Distance(aPOnE);
if (aDist <= Deflection)
{
gp_Vec aVLocPOnE(BegP, aPOnE);
gp_Vec aVecDirTri(DirTri);
double aPar = aVLocPOnE * aVecDirTri;
double aMaxPar = VecTri.Magnitude();
if (aPar >= 0 && aPar <= aMaxPar)
{
Intf_SectionPoint SP(spLieu, typOnG, 0, iLin, param, Intf_FACE, TTri, 0, 0., 1.);
mySPoins.Append(SP);
}
}
}
}
}
// Modified by Sergey KHROMOV - Fri Dec 7 14:40:29 2001 End
} //---- if(NoIntersectionWithTriangle == false)
//---------------------------------------------------------------------------
//-- On teste la distance entre les cotes du triangle et le polygone
//--
//-- Si cette distance est inferieure a Tolerance, on cree un SP.
//--
//-- printf("\nIntf_InterferencePolygPolyh : dBegTri=%g dEndTri=%g
// Tolerance=%g\n",dBegTri,dEndTri,Tolerance);
// if(std::abs(dBegTri) <= Tolerance || std::abs(dEndTri) <= Tolerance)
{
gp_Vec VecPol(BegO, EndO);
double NVecPol = VecPol.Magnitude();
if (NVecPol < Precision::Computational())
return;
gp_Dir DirPol(VecPol);
gp_Lin LinPol(BegO, DirPol);
double dist2, ParamOnO, ParamOnT;
for (int i = 0; i < 3; i++)
{
int pTri_ip1pc3 = pTri[Pourcent3[i + 1]];
int pTri_i = pTri[i];
const gp_Pnt& BegT = ToolPolyh::Point(thePolyh, pTri_ip1pc3);
const gp_Pnt& EndT = ToolPolyh::Point(thePolyh, pTri_i);
gp_Vec VecTri(BegT, EndT);
double NVecTri = VecTri.Magnitude();
if (NVecTri < Precision::Computational())
continue;
gp_Dir DirTri(VecTri);
gp_Lin LinTri(BegT, DirTri);
Extrema_ExtElC Extrema(LinPol, LinTri, 0.00000001);
if (Extrema.IsDone())
{
if (Extrema.IsParallel() == false)
{
if (Extrema.NbExt())
{
dist2 = Extrema.SquareDistance();
if (dist2 <= Tolerance * Tolerance)
{
Extrema_POnCurv POnC1, POnC2;
Extrema.Points(1, POnC1, POnC2);
const gp_Pnt& PO = POnC1.Value();
const gp_Pnt& PT = POnC2.Value();
//--cout<<" ** Nouveau "<<dist2<<endl;
if (IsInSegment(VecPol, gp_Vec(BegO, PO), NVecPol, ParamOnO, Tolerance))
{
if (IsInSegment(VecTri, gp_Vec(BegT, PT), NVecTri, ParamOnT, Tolerance))
{
//-- cout<<" * "<<endl;
gp_XYZ spLieu = BegT.XYZ() + ((EndT.XYZ() - BegT.XYZ()) * ParamOnT);
int tmin, tmax;
if (pTri_i > pTri_ip1pc3)
{
tmin = pTri_ip1pc3;
tmax = pTri_i;
}
else
{
tmax = pTri_ip1pc3;
tmin = pTri_i;
}
Intf_SectionPoint
SP(spLieu, typOnG, 0, iLin, ParamOnO, Intf_EDGE, tmin, tmax, 0., 1.);
mySPoins.Append(SP);
}
}
}
}
}
}
}
}
}
#endif
void Intf_InterferencePolygonPolyhedron::Intersect(const gp_Pnt& BegO,
const gp_Pnt& EndO,
const bool Infinite,
const int TTri,
const Polyhedron& thePolyh,
const gp_XYZ& TriNormal,
const double /*TriDp*/,
const double dBegTri,
const double dEndTri)
{
Intf_PIType typOnG = Intf_EDGE;
double t;
int pTri[3];
ToolPolyh::Triangle(thePolyh, TTri, pTri[0], pTri[1], pTri[2]);
gp_XYZ triNor = TriNormal; // Vecteur normal.
// double triDp = TriDp; // Distance polaire.
// double dBegTri=(triNor*BegO.XYZ())-triDp; // Distance <BegO> plan
// double dEndTri=(triNor*EndO.XYZ())-triDp; // Distance <EndO> plan
bool NoIntersectionWithTriangle = false;
double param;
t = dBegTri - dEndTri;
if (t >= 1.e-16 || t <= -1.e-16)
param = dBegTri / t;
else
param = dBegTri;
double floatgap = Epsilon(1000.);
if (!Infinite)
{
if (dBegTri <= floatgap && dBegTri >= -floatgap)
{
param = 0.;
typOnG = Intf_VERTEX;
if (BeginOfClosedPolygon)
NoIntersectionWithTriangle = false;
}
else if (dEndTri <= floatgap && dEndTri >= -floatgap)
{
param = 1.;
typOnG = Intf_VERTEX;
NoIntersectionWithTriangle = false;
}
if (param < 0. || param > 1.)
{
NoIntersectionWithTriangle = true;
}
}
if (NoIntersectionWithTriangle == false)
{
gp_XYZ spLieu = BegO.XYZ() + ((EndO.XYZ() - BegO.XYZ()) * param);
double dPiE[3] = {0.0, 0.0, 0.0}, dPtPi[3], sigd;
int is = 0;
int sEdge = -1;
int sVertex = -1;
int tbreak = 0;
{ //-- is = 0
gp_XYZ segT(ToolPolyh::Point(thePolyh, pTri[1]).XYZ()
- ToolPolyh::Point(thePolyh, pTri[0]).XYZ());
gp_XYZ vecP(spLieu - ToolPolyh::Point(thePolyh, pTri[0]).XYZ());
dPtPi[0] = vecP.Modulus();
if (dPtPi[0] <= floatgap)
{
sVertex = 0;
is = 0;
tbreak = 1;
}
else
{
gp_XYZ segT_x_vecP(segT ^ vecP);
double Modulus_segT_x_vecP = segT_x_vecP.Modulus();
sigd = segT_x_vecP * triNor;
if (sigd > floatgap)
sigd = 1.0;
else if (sigd < -floatgap)
sigd = -1.0;
else
{
sigd = 0.0;
}
dPiE[0] = sigd * (Modulus_segT_x_vecP / segT.Modulus());
if (dPiE[0] <= floatgap && dPiE[0] >= -floatgap)
{
sEdge = 0;
is = 0;
tbreak = 1;
}
}
}
if (tbreak == 0)
{ //-- is = 1
gp_XYZ segT(ToolPolyh::Point(thePolyh, pTri[2]).XYZ()
- ToolPolyh::Point(thePolyh, pTri[1]).XYZ());
gp_XYZ vecP(spLieu - ToolPolyh::Point(thePolyh, pTri[1]).XYZ());
dPtPi[1] = vecP.Modulus();
if (dPtPi[1] <= floatgap)
{
sVertex = 1;
is = 1;
tbreak = 1;
}
else
{
gp_XYZ segT_x_vecP(segT ^ vecP);
double Modulus_segT_x_vecP = segT_x_vecP.Modulus();
sigd = segT_x_vecP * triNor;
if (sigd > floatgap)
sigd = 1.0;
else if (sigd < -floatgap)
sigd = -1.0;
else
{
sigd = 0.0;
}
dPiE[1] = sigd * (Modulus_segT_x_vecP / segT.Modulus());
if (dPiE[1] <= floatgap && dPiE[1] >= -floatgap)
{
sEdge = 1;
is = 1;
tbreak = 1;
}
}
}
if (tbreak == 0)
{ //-- is = 2
gp_XYZ segT(ToolPolyh::Point(thePolyh, pTri[0]).XYZ()
- ToolPolyh::Point(thePolyh, pTri[2]).XYZ());
gp_XYZ vecP(spLieu - ToolPolyh::Point(thePolyh, pTri[2]).XYZ());
dPtPi[2] = vecP.Modulus();
if (dPtPi[2] <= floatgap)
{
sVertex = 2;
is = 2;
}
gp_XYZ segT_x_vecP(segT ^ vecP);
double Modulus_segT_x_vecP = segT_x_vecP.Modulus();
sigd = segT_x_vecP * triNor;
if (sigd > floatgap)
sigd = 1.0;
else if (sigd < -floatgap)
sigd = -1.0;
else
{
sigd = 0.0;
}
dPiE[2] = sigd * (Modulus_segT_x_vecP / segT.Modulus());
if (dPiE[2] <= floatgap && dPiE[2] >= -floatgap)
{
sEdge = 2;
is = 2;
}
}
//-- fin for i=0 to 2
// !!cout<<endl;
int triCon, pedg;
if (sVertex > -1)
{
triCon = TTri;
pedg = pTri[Pourcent3[sVertex + 1]];
//-- while (triCon!=0) {
//-- ToolPolyh::TriConnex(thePolyh, triCon,pTri[sVertex],pedg,triCon,pedg);
//-- //-- if (triCon<TTri) return;
//-- if (triCon==TTri) break;
//-- }
Intf_SectionPoint SP(spLieu, typOnG, 0, iLin, param, Intf_VERTEX, pTri[is], 0, 0., 1.);
mySPoins.Append(SP);
}
else if (sEdge > -1)
{
ToolPolyh::TriConnex(thePolyh, TTri, pTri[sEdge], pTri[Pourcent3[sEdge + 1]], triCon, pedg);
//-- if (triCon<=TTri) return; ???????????????????? LBR
// !!cout<<" sEdge "<<endl;
Intf_SectionPoint SP(spLieu,
typOnG,
0,
iLin,
param,
Intf_EDGE,
std::min(pTri[sEdge], pTri[Pourcent3[sEdge + 1]]),
std::max(pTri[sEdge], pTri[Pourcent3[sEdge + 1]]),
0.,
1.);
mySPoins.Append(SP);
}
else if (dPiE[0] > 0. && dPiE[1] > 0. && dPiE[2] > 0.)
{
// !!cout<<" 3 Positifs "<<endl;
Intf_SectionPoint SP(spLieu, typOnG, 0, iLin, param, Intf_FACE, TTri, 0, 0., 1.);
mySPoins.Append(SP);
}
// Modified by Sergey KHROMOV - Fri Dec 7 14:40:11 2001 Begin
// Sometimes triangulation doesn't cover whole the face. In this
// case it is necessary to take into account the deflection between boundary
// isolines of the surface and boundary trianles. Computed value of this
// deflection is contained in thePolyh.
else
{
int i;
for (i = 1; i <= 3; i++)
{
int indP1 = (i == 3) ? pTri[0] : pTri[i];
int indP2 = pTri[i - 1];
if (ToolPolyh::IsOnBound(thePolyh, indP1, indP2))
{
// For boundary line it is necessary to check the border deflection.
double Deflection = ToolPolyh::GetBorderDeflection(thePolyh);
const gp_Pnt& BegP = ToolPolyh::Point(thePolyh, indP1);
const gp_Pnt& EndP = ToolPolyh::Point(thePolyh, indP2);
gp_Vec VecTri(BegP, EndP);
gp_Dir DirTri(VecTri);
gp_Lin LinTri(BegP, DirTri);
gp_Pnt aPOnE(spLieu);
double aDist = LinTri.Distance(aPOnE);
if (aDist <= Deflection)
{
gp_Vec aVLocPOnE(BegP, aPOnE);
gp_Vec aVecDirTri(DirTri);
double aPar = aVLocPOnE * aVecDirTri;
double aMaxPar = VecTri.Magnitude();
if (aPar >= 0 && aPar <= aMaxPar)
{
Intf_SectionPoint SP(spLieu, typOnG, 0, iLin, param, Intf_FACE, TTri, 0, 0., 1.);
mySPoins.Append(SP);
}
}
}
}
}
// Modified by Sergey KHROMOV - Fri Dec 7 14:40:29 2001 End
} //---- if(NoIntersectionWithTriangle == false)
//---------------------------------------------------------------------------
//-- On teste la distance entre les cotes du triangle et le polygone
//--
//-- Si cette distance est inferieure a Tolerance, on cree un SP.
//--
//-- printf("\nIntf_InterferencePolygPolyh : dBegTri=%g dEndTri=%g
// Tolerance=%g\n",dBegTri,dEndTri,Tolerance);
// if (std::abs(dBegTri) <= Tolerance || std::abs(dEndTri) <= Tolerance)
{
gp_Vec VecPol(BegO, EndO);
double NVecPol = VecPol.Magnitude();
if (NVecPol < Precision::Computational())
return;
gp_Dir DirPol(VecPol);
gp_Lin LinPol(BegO, DirPol);
double dist2, ParamOnO, ParamOnT;
for (int i = 0; i < 3; i++)
{
int pTri_ip1pc3 = pTri[Pourcent3[i + 1]];
int pTri_i = pTri[i];
const gp_Pnt& BegT = ToolPolyh::Point(thePolyh, pTri_ip1pc3);
const gp_Pnt& EndT = ToolPolyh::Point(thePolyh, pTri_i);
gp_Vec VecTri(BegT, EndT);
double NVecTri = VecTri.Magnitude();
if (NVecTri < Precision::Computational())
continue;
gp_Dir DirTri(VecTri);
gp_Lin LinTri(BegT, DirTri);
Extrema_ExtElC Extrema(LinPol, LinTri, 0.00000001);
if (Extrema.IsDone())
{
if (Extrema.IsParallel() == false)
{
if (Extrema.NbExt())
{
dist2 = Extrema.SquareDistance();
if (dist2 <= Tolerance * Tolerance)
{
Extrema_POnCurv POnC1, POnC2;
Extrema.Points(1, POnC1, POnC2);
const gp_Pnt& PO = POnC1.Value();
const gp_Pnt& PT = POnC2.Value();
//--cout<<" ** Nouveau "<<dist2<<endl;
if (IsInSegment(VecPol, gp_Vec(BegO, PO), NVecPol, ParamOnO, Tolerance))
{
if (IsInSegment(VecTri, gp_Vec(BegT, PT), NVecTri, ParamOnT, Tolerance))
{
//-- cout<<" * "<<endl;
gp_XYZ spLieu = BegT.XYZ() + ((EndT.XYZ() - BegT.XYZ()) * ParamOnT);
int tmin, tmax;
if (pTri_i > pTri_ip1pc3)
{
tmin = pTri_ip1pc3;
tmax = pTri_i;
}
else
{
tmax = pTri_ip1pc3;
tmin = pTri_i;
}
Intf_SectionPoint
SP(spLieu, typOnG, 0, iLin, ParamOnO, Intf_EDGE, tmin, tmax, 0., 1.);
mySPoins.Append(SP);
}
}
}
}
}
}
}
}
}