1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-05-01 10:26:12 +03:00
occt/src/HLRBRep/HLRBRep_Surface.cxx
bugmster 973c2be1e1 0024428: Implementation of LGPL license
The copying permission statements at the beginning of source files updated to refer to LGPL.
Copyright dates extended till 2014 in advance.
2013-12-17 12:42:41 +04:00

287 lines
8.5 KiB
C++

// Created on: 1992-03-13
// Created by: Christophe MARION
// 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 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 <HLRBRep_Surface.ixx>
#include <HLRBRep_BSurfaceTool.hxx>
#include <gp_Pln.hxx>
#include <GProp_PEquation.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <BRepClass_FaceClassifier.hxx>
#include <HLRAlgo_Projector.hxx>
#include <HLRBRep_Curve.hxx>
#include <TColStd_Array2OfReal.hxx>
#include <Geom_BSplineSurface.hxx>
#include <Geom_BezierSurface.hxx>
//=======================================================================
//function : HLRBRep_Surface
//purpose :
//=======================================================================
HLRBRep_Surface::HLRBRep_Surface ()
{
}
//=======================================================================
//function : Surface
//purpose :
//=======================================================================
void HLRBRep_Surface::Surface (const TopoDS_Face& F)
{
mySurf.Initialize(F,Standard_False);
GeomAbs_SurfaceType typ = HLRBRep_BSurfaceTool::GetType(mySurf);
switch (typ) {
case GeomAbs_Plane :
case GeomAbs_Cylinder :
case GeomAbs_Cone :
case GeomAbs_Sphere :
case GeomAbs_Torus :
// unchanged type
myType = typ;
break;
case GeomAbs_BezierSurface :
if (HLRBRep_BSurfaceTool::UDegree(mySurf) == 1 &&
HLRBRep_BSurfaceTool::VDegree(mySurf) == 1) {
myType = GeomAbs_Plane;
}
else
myType = typ;
break;
default :
myType = GeomAbs_OtherSurface;
break;
}
}
//=======================================================================
//function : SideRowsOfPoles
//purpose :
//=======================================================================
Standard_Boolean
HLRBRep_Surface::SideRowsOfPoles (const Standard_Real tol,
const Standard_Integer nbuPoles,
const Standard_Integer nbvPoles,
TColgp_Array2OfPnt& Pnt) const
{
Standard_Integer iu,iv;
Standard_Real x0,y0,x,y,z;
Standard_Boolean result;
Standard_Real tole = (Standard_Real)tol;
const gp_Trsf& T = ((HLRAlgo_Projector*) myProj)->Transformation();
for (iu = 1; iu <= nbuPoles; iu++) {
for (iv = 1; iv <= nbvPoles; iv++)
Pnt(iu,iv).Transform(T);
}
result = Standard_True;
for (iu = 1; iu <= nbuPoles && result; iu++) { // Side iso u ?
Pnt(iu,1).Coord(x0,y0,z);
for (iv = 2; iv <= nbvPoles && result; iv++) {
Pnt(iu,iv).Coord(x,y,z);
result = Abs(x-x0) < tole && Abs(y-y0) < tole;
}
}
if (result) return result;
result = Standard_True;
for (iv = 1; iv <= nbvPoles && result; iv++) { // Side iso v ?
Pnt(1,iv).Coord(x0,y0,z);
for (iu = 2; iu <= nbuPoles && result; iu++) {
Pnt(iu,iv).Coord(x,y,z);
result = Abs(x-x0) < tole && Abs(y-y0) < tole;
}
}
if (result) return result;
// Are the Poles in a Side Plane ?
TColgp_Array1OfPnt p(1,nbuPoles*nbvPoles);
Standard_Integer i = 0;
for (iu = 1; iu <= nbuPoles; iu++) {
for (iv = 1; iv <= nbvPoles; iv++) {
i++;
p(i) = Pnt(iu,iv);
}
}
GProp_PEquation Pl(p,(Standard_Real)tol);
if (Pl.IsPlanar())
result = Abs(Pl.Plane().Axis().Direction().Z()) < 0.0001;
return result;
}
//=======================================================================
//function : IsSide
//purpose :
//=======================================================================
Standard_Boolean
HLRBRep_Surface::IsSide (const Standard_Real tolF,
const Standard_Real toler) const
{
gp_Pnt Pt;
gp_Vec D;
Standard_Real r;
if (myType == GeomAbs_Plane) {
gp_Pln Pl = Plane();
gp_Ax1 A = Pl.Axis();
Pt = A.Location();
D = A.Direction();
Pt.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
D .Transform(((HLRAlgo_Projector*) myProj)->Transformation());
if (((HLRAlgo_Projector*) myProj)->Perspective()) {
r = D.Z() * ((HLRAlgo_Projector*) myProj)->Focus() -
( D.X() * Pt.X() + D.Y() * Pt.Y() + D.Z() * Pt.Z() );
}
else r= D.Z();
return Abs(r) < toler;
}
else if (myType == GeomAbs_Cylinder) {
if (((HLRAlgo_Projector*) myProj)->Perspective()) return Standard_False;
gp_Cylinder Cyl = HLRBRep_BSurfaceTool::Cylinder(mySurf);
gp_Ax1 A = Cyl.Axis();
D = A.Direction();
D .Transform(((HLRAlgo_Projector*) myProj)->Transformation());
r = Sqrt(D.X() * D.X() + D.Y() * D.Y());
return r < toler;
}
else if (myType == GeomAbs_Cone) {
if (!((HLRAlgo_Projector*) myProj)->Perspective()) return Standard_False;
gp_Cone Con = HLRBRep_BSurfaceTool::Cone(mySurf);
Pt = Con.Apex();
Pt.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
Standard_Real tol = 0.001;
return Pt.IsEqual(gp_Pnt(0,0,((HLRAlgo_Projector*) myProj)->Focus()),tol);
}
else if (myType == GeomAbs_BezierSurface) {
if (((HLRAlgo_Projector*) myProj)->Perspective()) return Standard_False;
Standard_Integer nu = HLRBRep_BSurfaceTool::NbUPoles(mySurf);
Standard_Integer nv = HLRBRep_BSurfaceTool::NbVPoles(mySurf);
TColgp_Array2OfPnt Pnt(1,nu,1,nv);
HLRBRep_BSurfaceTool::Bezier(mySurf)->Poles(Pnt);
return SideRowsOfPoles (tolF,nu,nv,Pnt);
}
else if (myType == GeomAbs_BSplineSurface) {
if (((HLRAlgo_Projector*) myProj)->Perspective()) return Standard_False;
Standard_Integer nu = HLRBRep_BSurfaceTool::NbUPoles(mySurf);
Standard_Integer nv = HLRBRep_BSurfaceTool::NbVPoles(mySurf);
TColgp_Array2OfPnt Pnt(1,nu,1,nv);
TColStd_Array2OfReal W(1,nu,1,nv);
HLRBRep_BSurfaceTool::BSpline(mySurf)->Poles(Pnt);
HLRBRep_BSurfaceTool::BSpline(mySurf)->Weights(W);
return SideRowsOfPoles (tolF,nu,nv,Pnt);
}
else return Standard_False;
}
//=======================================================================
//function : IsAbove
//purpose :
//=======================================================================
Standard_Boolean
HLRBRep_Surface::IsAbove (const Standard_Boolean back,
const Standard_Address A,
const Standard_Real tol) const
{
Standard_Boolean planar = (myType == GeomAbs_Plane);
if (planar) {
gp_Pln Pl = Plane();
Standard_Real a,b,c,d;
Pl.Coefficients(a,b,c,d);
Standard_Real u,u1,u2,dd,x,y,z;
gp_Pnt P;
u1 = ((HLRBRep_Curve*)A)->Parameter3d
(((HLRBRep_Curve*)A)->FirstParameter());
u2 = ((HLRBRep_Curve*)A)->Parameter3d
(((HLRBRep_Curve*)A)->LastParameter());
u=u1;
((HLRBRep_Curve*)A)->D0(u,P);
P.Coord(x,y,z);
dd = a*x + b*y + c*z + d;
if (back) dd = -dd;
if (dd < -tol) return Standard_False;
if (((HLRBRep_Curve*)A)->GetType() != GeomAbs_Line) {
Standard_Integer nbPnt = 30;
Standard_Real step = (u2-u1)/(nbPnt+1);
for (Standard_Integer i = 1; i <= nbPnt; i++) {
u += step;
((HLRBRep_Curve*)A)->D0(u,P);
P.Coord(x,y,z);
dd = a*x + b*y + c*z + d;
if (back) dd = -dd;
if (dd < -tol) return Standard_False;
}
}
u = u2;
((HLRBRep_Curve*)A)->D0(u,P);
P.Coord(x,y,z);
dd = a*x + b*y + c*z + d;
if (back) dd = -dd;
if (dd < -tol) return Standard_False;
return Standard_True;
}
else return Standard_False;
}
//=======================================================================
//function : Value
//purpose :
//=======================================================================
gp_Pnt HLRBRep_Surface::Value (const Standard_Real U,
const Standard_Real V) const
{
gp_Pnt P;
D0(U,V,P);
return P;
}
//=======================================================================
//function : Plane
//purpose :
//=======================================================================
gp_Pln HLRBRep_Surface::Plane () const
{
GeomAbs_SurfaceType typ = HLRBRep_BSurfaceTool::GetType(mySurf);
switch (typ) {
case GeomAbs_BezierSurface :
{
gp_Pnt P;
gp_Vec D1U;
gp_Vec D1V;
D1(0.5,0.5,P,D1U,D1V);
return gp_Pln(P,gp_Dir(D1U.Crossed(D1V)));
}
default :
return HLRBRep_BSurfaceTool::Plane(mySurf);
}
}