Loading files
// Created on: 1997-04-17
// Created by: Christophe MARION
// Copyright (c) 1997-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.
#define No_Standard_OutOfRange
#include <HLRAlgo_Coincidence.hxx>
#include <HLRBRep_Data.hxx>
#include <HLRBRep_EdgeBuilder.hxx>
#include <HLRBRep_EdgeIList.hxx>
#include <HLRBRep_Hider.hxx>
#include <HLRBRep_VertexList.hxx>
#include <NCollection_Sequence.hxx>
#include <Standard_ErrorHandler.hxx>
//=================================================================================================
HLRBRep_Hider::HLRBRep_Hider(const occ::handle<HLRBRep_Data>& DS)
: myDS(DS)
{
}
//=================================================================================================
void HLRBRep_Hider::OwnHiding(const int) {}
//=================================================================================================
void HLRBRep_Hider::Hide(
const int FI,
NCollection_DataMap<TopoDS_Shape, BRepTopAdaptor_Tool, TopTools_ShapeMapHasher>& MST)
{
// *****************************************************************
//
// This algorithm hides a set of edges stored in the data structure <myDS>
// with the hiding face number FI in <myDS>.
//
// Outline of the algorithm
//
// 1. Loop on the Edges (not hidden and not rejected by the face minmax)
//
// The rejections depending of the face are
// - Edge above the face
// - Edge belonging to the face
// - Edge rejected by a wire minmax
//
// Compute interferences with the not rejected edges of the face.
// Store IN and ON interferences in two sorted lists
// ILHidden and ILOn
// If ILOn is not empty
// Resolve ComplexTransitions in ILOn
// Resolve ON Intersections in ILOn
// An On interference may become
// IN : Move it from ILOn to ILHidden
// OUT : Remove it from ILOn
// If ILHidden and ILOn are empty
// intersect the edge with the face and classify the Edge.
// - if inside and under the face hide it.
// Else
// If ILHidden is not empty
// Resolve ComplexTransitions in ILHidden
// Build Hidden parts of the edge
// - Hide them
// Build visible parts of the edge
// Build Parts of the edge under the boundary of the face
// - Hide them as Boundary
// If ILOn is not empty
// Build ON parts of the edge
// - Hide them as ON parts
// Build Parts of the edge on the boundary of the face
// - Hide them as ON parts on Boundary
//
//
// *****************************************************************
myDS->InitEdge(FI, MST);
if (!myDS->MoreEdge())
{ // there is nothing to do
return; // **********************
}
if (myDS->IsBadFace())
{
return;
}
HLRBRep_EdgeInterferenceTool EIT(myDS); // List of Intersections
NCollection_Array1<HLRBRep_EdgeData>& myEData = myDS->EDataArray();
for (; myDS->MoreEdge(); myDS->NextEdge())
{ // loop on the Edges
int E = myDS->Edge(); // *****************
try
{
OCC_CATCH_SIGNALS
bool hasOut = false;
NCollection_List<HLRAlgo_Interference> ILHidden;
NCollection_List<HLRAlgo_Interference> ILOn;
EIT.LoadEdge();
for (myDS->InitInterference(); // intersections with face-edges
myDS->MoreInterference(); // *****************************
myDS->NextInterference())
{
if (myDS->RejectedInterference())
{
if (myDS->AboveInterference() && myDS->SimpleHidingFace())
{
hasOut = true;
}
}
else
{
HLRAlgo_Interference& Int = myDS->Interference();
switch (Int.Intersection().State())
{
case TopAbs_IN:
HLRBRep_EdgeIList::AddInterference(ILHidden, Int, EIT);
break;
case TopAbs_ON:
HLRBRep_EdgeIList::AddInterference(ILOn, Int, EIT);
break;
case TopAbs_OUT:
case TopAbs_UNKNOWN:
break;
}
}
}
//-- ============================================================
bool Modif;
do
{
Modif = false;
NCollection_List<HLRAlgo_Interference>::Iterator ItSegHidden1(ILHidden);
while (ItSegHidden1.More() && !Modif)
{
HLRAlgo_Interference& Int1 = ItSegHidden1.ChangeValue();
int numseg1 = Int1.Intersection().SegIndex();
if (numseg1 != 0)
{
NCollection_List<HLRAlgo_Interference>::Iterator ItSegHidden2(ILHidden);
while (ItSegHidden2.More() && !Modif)
{
HLRAlgo_Interference& Int2 = ItSegHidden2.ChangeValue();
int numseg2 = Int2.Intersection().SegIndex();
if (numseg1 + numseg2 == 0)
{
//--printf("\nHidden Traitement du segment %d %d\n",numseg1,numseg2);
// fflush(stdout);
TopAbs_State stbef1, staft1, stbef2, staft2;
Int1.Boundary().State3D(stbef1, staft1);
Int2.Boundary().State3D(stbef2, staft2);
if (Int1.Orientation() == Int2.Orientation())
{
if (Int1.Transition() == Int2.Transition())
{
if (stbef1 == stbef2 && staft1 == staft2 && stbef1 != TopAbs_ON
&& staft1 != TopAbs_ON)
{
//-- printf("\n Index1 = %d Index2 =
//%d\n",Int1.Intersection().Index(),Int2.Intersection().Index());
int nind = -1;
if (Int1.Intersection().Index() != 0)
{
nind = Int1.Intersection().Index();
}
if (Int2.Intersection().Index() != 0)
{
if (nind != -1)
{
if (Int1.Intersection().Index() != Int2.Intersection().Index())
{
nind = -1;
}
}
else
{
nind = Int2.Intersection().Index();
}
}
if (Int1.Intersection().Index() == 0 && Int2.Intersection().Index() == 0)
{
nind = 0;
}
if (nind != -1)
{
//-- printf("\n Segment Supprime\n"); fflush(stdout);
HLRAlgo_Intersection& inter = Int1.ChangeIntersection();
inter.SegIndex(nind);
double p1 = Int1.Intersection().Parameter();
double p2 = Int2.Intersection().Parameter();
inter.Parameter((p1 + p2) * 0.5);
Int1.BoundaryTransition(TopAbs_EXTERNAL);
ILHidden.Remove(ItSegHidden2);
Modif = true;
}
}
}
}
}
if (!Modif)
{
ItSegHidden2.Next();
}
}
}
if (!Modif)
{
ItSegHidden1.Next();
}
}
} while (Modif);
//-- ============================================================
if (!ILOn.IsEmpty())
{ // process the interferences on ILOn
// *********************************
HLRBRep_EdgeIList::ProcessComplex // complex transition on ILOn
(ILOn, EIT); // **************************
NCollection_List<HLRAlgo_Interference>::Iterator It(ILOn);
while (It.More())
{ // process Intersections on the Face
// *********************************
HLRAlgo_Interference& Int = It.ChangeValue();
TopAbs_State stbef, staft; // read the 3d states
Int.Boundary().State3D(stbef, staft); // ******************
switch (Int.Transition())
{
case TopAbs_FORWARD:
switch (staft)
{
case TopAbs_OUT:
ILOn.Remove(It);
break;
case TopAbs_IN:
HLRBRep_EdgeIList::AddInterference(ILHidden, Int, EIT);
ILOn.Remove(It);
break;
case TopAbs_UNKNOWN:
#ifdef OCCT_DEBUG
std::cout << "UNKNOWN state staft" << std::endl;
#endif
case TopAbs_ON:
It.Next();
break;
}
break;
case TopAbs_REVERSED:
switch (stbef)
{
case TopAbs_OUT:
ILOn.Remove(It);
break;
case TopAbs_IN:
HLRBRep_EdgeIList::AddInterference(ILHidden, Int, EIT);
ILOn.Remove(It);
break;
case TopAbs_UNKNOWN:
#ifdef OCCT_DEBUG
std::cout << "UNKNOWN state stbef" << std::endl;
#endif
case TopAbs_ON:
It.Next();
break;
}
break;
case TopAbs_EXTERNAL:
ILOn.Remove(It);
break;
case TopAbs_INTERNAL:
switch (stbef)
{
case TopAbs_IN:
switch (staft)
{
case TopAbs_IN:
HLRBRep_EdgeIList::AddInterference(ILHidden, Int, EIT);
ILOn.Remove(It);
break;
case TopAbs_ON:
Int.Transition(TopAbs_FORWARD); // FORWARD in ILOn,
HLRBRep_EdgeIList::AddInterference // REVERSED in ILHidden
(ILHidden,
HLRAlgo_Interference(Int.Intersection(),
Int.Boundary(),
Int.Orientation(),
TopAbs_REVERSED,
Int.BoundaryTransition()),
EIT);
It.Next();
break;
case TopAbs_OUT:
Int.Transition(TopAbs_REVERSED); // set REVERSED
HLRBRep_EdgeIList::AddInterference(ILHidden, Int, EIT);
ILOn.Remove(It);
break;
case TopAbs_UNKNOWN:
#ifdef OCCT_DEBUG
std::cout << "UNKNOWN state after" << std::endl;
#endif
It.Next();
break;
}
break;
case TopAbs_ON:
switch (staft)
{
case TopAbs_IN:
Int.Transition(TopAbs_REVERSED); // REVERSED in ILOn,
HLRBRep_EdgeIList::AddInterference // REVERSED in ILHidden
(ILHidden,
HLRAlgo_Interference(Int.Intersection(),
Int.Boundary(),
Int.Orientation(),
TopAbs_FORWARD,
Int.BoundaryTransition()),
EIT);
break;
case TopAbs_ON:
break;
case TopAbs_OUT:
Int.Transition(TopAbs_REVERSED);
break;
case TopAbs_UNKNOWN:
#ifdef OCCT_DEBUG
std::cout << "UNKNOWN state after" << std::endl;
#endif
break;
}
It.Next();
break;
case TopAbs_OUT:
switch (staft)
{
case TopAbs_IN:
Int.Transition(TopAbs_FORWARD); // set FORWARD
HLRBRep_EdgeIList::AddInterference(ILHidden, Int, EIT);
ILOn.Remove(It);
break;
case TopAbs_ON:
Int.Transition(TopAbs_FORWARD); // FORWARD in ILOn
It.Next();
break;
case TopAbs_OUT:
ILOn.Remove(It);
break;
case TopAbs_UNKNOWN:
#ifdef OCCT_DEBUG
std::cout << "UNKNOWN state after" << std::endl;
#endif
It.Next();
break;
}
break;
case TopAbs_UNKNOWN:
#ifdef OCCT_DEBUG
std::cout << "UNKNOWN state stbef" << std::endl;
#endif
break;
}
}
}
}
if (ILHidden.IsEmpty() && ILOn.IsEmpty() && !hasOut)
{
HLRBRep_EdgeData& ed = myEData(E);
TopAbs_State st = myDS->Compare(E, ed); // Classification
if (st == TopAbs_IN || st == TopAbs_ON)
{ // **************
ed.Status().HideAll();
}
}
else
{
double p1 = 0., p2 = 0.;
float tol1 = 0., tol2 = 0.;
HLRBRep_EdgeData& ed = myEData(E);
HLRAlgo_EdgeStatus& ES = ed.Status();
bool foundHidden = false;
if (!ILHidden.IsEmpty())
{
HLRBRep_EdgeIList::ProcessComplex // complex transition on ILHidden
(ILHidden, EIT); // ******************************
int level = 0;
if (!myDS->SimpleHidingFace())
{ // Level at Start
level = myDS->HidingStartLevel(E, ed, ILHidden); // **************
}
NCollection_List<HLRAlgo_Interference>::Iterator It(ILHidden);
if (myDS->SimpleHidingFace()) // remove excess interferences
{
NCollection_Sequence<double> ToRemove;
TopAbs_Orientation PrevTrans = TopAbs_EXTERNAL;
double PrevParam = 0.;
for (; It.More(); It.Next())
{
const HLRAlgo_Interference& Int = It.Value();
TopAbs_Orientation aTrans = Int.Transition();
if (aTrans == PrevTrans)
{
if (aTrans == TopAbs_FORWARD)
{
ToRemove.Append(Int.Intersection().Parameter());
#ifdef OCCT_DEBUG
std::cout << "Two adjacent interferences with transition FORWARD" << std::endl;
#endif
}
else if (aTrans == TopAbs_REVERSED)
{
ToRemove.Append(PrevParam);
#ifdef OCCT_DEBUG
std::cout << "Two adjacent interferences with transition REVERSED" << std::endl;
#endif
}
}
PrevTrans = aTrans;
PrevParam = Int.Intersection().Parameter();
}
It.Initialize(ILHidden);
while (It.More())
{
double aParam = It.Value().Intersection().Parameter();
bool found = false;
for (int i = 1; i <= ToRemove.Length(); i++)
{
if (aParam == ToRemove(i))
{
found = true;
ILHidden.Remove(It);
ToRemove.Remove(i);
break;
}
}
if (!found)
{
It.Next();
}
}
} // remove excess interferences
It.Initialize(ILHidden);
while (It.More())
{ // suppress multi-inside Intersections
// ***********************************
const HLRAlgo_Interference& Int = It.Value();
switch (Int.Transition())
{
case TopAbs_FORWARD: {
int decal = Int.Intersection().Level();
if (level > 0)
{
ILHidden.Remove(It);
}
else
{
It.Next();
}
level = level + decal;
}
break;
case TopAbs_REVERSED: {
level = level - Int.Intersection().Level();
if (level > 0)
{
ILHidden.Remove(It);
}
else
{
It.Next();
}
}
break;
case TopAbs_EXTERNAL:
It.Next();
break;
case TopAbs_INTERNAL:
It.Next();
break;
default:
It.Next();
break;
}
}
if (ILHidden.IsEmpty())
{ // Edge hidden
ES.HideAll(); // ***********
}
else
{
foundHidden = true;
}
}
if (!ILHidden.IsEmpty())
{
// IFV
TopAbs_State aBuildIN = TopAbs_IN;
bool IsSuspicion = true;
double pmax, pmin;
bool allInt = false;
bool allFor = false;
bool allRev = false;
pmin = RealLast();
pmax = -pmin;
if (ILHidden.Extent() > 1)
{
allInt = true;
allFor = true;
allRev = true;
NCollection_List<HLRAlgo_Interference>::Iterator It(ILHidden);
for (; It.More(); It.Next())
{
double p = It.Value().Intersection().Parameter();
allFor = allFor && (It.Value().Transition() == TopAbs_FORWARD);
allRev = allRev && (It.Value().Transition() == TopAbs_REVERSED);
allInt = allInt && (It.Value().Transition() == TopAbs_INTERNAL);
if (p < pmin)
{
pmin = p;
}
if (p > pmax)
{
pmax = p;
}
}
}
NCollection_List<HLRAlgo_Interference>::Iterator Itl(ILHidden);
HLRBRep_VertexList IL(EIT, Itl);
HLRBRep_EdgeBuilder EB(IL);
EB.Builds(aBuildIN); // build hidden parts
// ******************
while (EB.MoreEdges())
{
p1 = 0.;
p2 = 0.;
int aMaskP1P2 = 0;
while (EB.MoreVertices())
{
switch (EB.Orientation())
{
case TopAbs_FORWARD:
p1 = EB.Current().Parameter();
tol1 = EB.Current().Tolerance();
aMaskP1P2 |= 1;
break;
case TopAbs_REVERSED:
p2 = EB.Current().Parameter();
tol2 = EB.Current().Tolerance();
aMaskP1P2 |= 2;
break;
case TopAbs_INTERNAL:
case TopAbs_EXTERNAL:
break;
}
EB.NextVertex();
}
if (aMaskP1P2 != 3 || p2 - p1 <= 1.e-7)
{
EB.NextEdge();
continue;
}
if (allInt)
{
if (p1 < pmin)
{
p1 = pmin;
}
if (p2 > pmax)
{
p2 = pmax;
}
// HLRBRep_EdgeData& ed = myEData(E);
// TopAbs_State st = myDS->Compare(E,ed); // Classification
}
TopAbs_State aTestState = TopAbs_IN;
if (IsSuspicion)
{
// int aNbp = 1;
// aTestState = myDS->SimplClassify(E, ed, aNbp, p1, p2);
int tmplevel = 0;
aTestState = myDS->Classify(E, ed, true, tmplevel, (p1 + p2) / 2.);
}
if (aTestState != TopAbs_OUT)
{
ES.Hide(p1,
tol1,
p2,
tol2,
false, // under the Face
false); // inside the Face
}
EB.NextEdge();
}
EB.Builds(TopAbs_ON); // build parts under the boundary
// ******************************
while (EB.MoreEdges())
{
p1 = 0.;
p2 = 0.;
int aMaskP1P2 = 0;
while (EB.MoreVertices())
{
switch (EB.Orientation())
{
case TopAbs_FORWARD:
p1 = EB.Current().Parameter();
tol1 = EB.Current().Tolerance();
aMaskP1P2 |= 1;
break;
case TopAbs_REVERSED:
p2 = EB.Current().Parameter();
tol2 = EB.Current().Tolerance();
aMaskP1P2 |= 2;
break;
case TopAbs_INTERNAL:
case TopAbs_EXTERNAL:
break;
}
EB.NextVertex();
}
if (aMaskP1P2 != 3 || p2 - p1 <= 1.e-7)
{
EB.NextEdge();
continue;
}
TopAbs_State aTestState = TopAbs_IN;
if (IsSuspicion)
{
// int aNbp = 1;
// aTestState = myDS->SimplClassify(E, ed, aNbp, p1, p2);
int tmplevel = 0;
aTestState = myDS->Classify(E, ed, true, tmplevel, (p1 + p2) / 2.);
}
if (aTestState != TopAbs_OUT)
{
ES.Hide(p1,
tol1,
p2,
tol2,
false, // under the Face
true); // on the boundary
}
EB.NextEdge();
}
}
if (!ILOn.IsEmpty())
{
int level = 0;
if (!myDS->SimpleHidingFace())
{ // Level at Start
level = myDS->HidingStartLevel(E, ed, ILOn); // **************
}
if (level > 0)
{
NCollection_List<HLRAlgo_Interference>::Iterator It(ILOn);
while (It.More())
{ // suppress multi-inside Intersections
// ***********************************
const HLRAlgo_Interference& Int = It.Value();
switch (Int.Transition())
{
case TopAbs_FORWARD: {
int decal = Int.Intersection().Level();
if (level > 0)
{
ILOn.Remove(It);
}
else
{
It.Next();
}
level = level + decal;
}
break;
case TopAbs_REVERSED:
level = level - Int.Intersection().Level();
if (level > 0)
{
ILOn.Remove(It);
}
else
{
It.Next();
}
break;
case TopAbs_EXTERNAL:
case TopAbs_INTERNAL:
default:
It.Next();
break;
}
}
if (ILOn.IsEmpty() && !foundHidden)
{ // Edge hidden
ES.HideAll(); // ***********
}
}
}
if (!ILOn.IsEmpty())
{
HLRBRep_VertexList IL(EIT, ILOn);
HLRBRep_EdgeBuilder EB(IL);
EB.Builds(TopAbs_IN); // build parts on the Face
// ***********************
while (EB.MoreEdges())
{
p1 = 0.;
p2 = 0.;
int aMaskP1P2 = 0;
while (EB.MoreVertices())
{
switch (EB.Orientation())
{
case TopAbs_FORWARD:
p1 = EB.Current().Parameter();
tol1 = EB.Current().Tolerance();
aMaskP1P2 |= 1;
break;
case TopAbs_REVERSED:
p2 = EB.Current().Parameter();
tol2 = EB.Current().Tolerance();
aMaskP1P2 |= 2;
break;
case TopAbs_INTERNAL:
case TopAbs_EXTERNAL:
break;
}
EB.NextVertex();
}
if (aMaskP1P2 != 3 || p2 - p1 <= 1.e-7)
{
EB.NextEdge();
continue;
}
ES.Hide(p1,
tol1,
p2,
tol2,
true, // on the Face
false); // inside the Face
EB.NextEdge();
}
EB.Builds(TopAbs_ON); // build hidden parts under the boundary
// *************************************
while (EB.MoreEdges())
{
p1 = 0.;
p2 = 0.;
int aMaskP1P2 = 0;
while (EB.MoreVertices())
{
switch (EB.Orientation())
{
case TopAbs_FORWARD:
p1 = EB.Current().Parameter();
tol1 = EB.Current().Tolerance();
aMaskP1P2 |= 1;
break;
case TopAbs_REVERSED:
p2 = EB.Current().Parameter();
tol2 = EB.Current().Tolerance();
aMaskP1P2 |= 2;
break;
case TopAbs_INTERNAL:
case TopAbs_EXTERNAL:
break;
}
EB.NextVertex();
}
if (aMaskP1P2 != 3 || p2 - p1 <= 1.e-7)
{
EB.NextEdge();
continue;
}
ES.Hide(p1,
tol1,
p2,
tol2,
true, // on the Face
true); // on the boundary
EB.NextEdge();
}
}
}
}
catch (Standard_Failure const& anException)
{
#ifdef OCCT_DEBUG
std::cout << "An exception was caught when hiding edge " << E;
std::cout << " by the face " << FI << std::endl;
std::cout << anException << std::endl;
#endif
(void)anException;
}
}
}
3d097a032This file is pinned to the selected release. Download the original to open it in your design tool.