// Created on: 1992-03-02 // Created by: Laurent BUCHARD // 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 #include #include #include #include #include #include #include #include #include #include #include #include #include //====================================================================== #define EPSDIST Tol #define EPSNUL TolConf #define EPSX ParTool::EpsX(TheParCurve) #define NB_ECHANTILLONS //====================================================================== void IntImpParGen_Intersector::And_Domaine_Objet1_Intersections(const ImpTool& TheImpTool, const ParCurve& TheParCurve, const IntRes2d_Domain& TheImpCurveDomain, const IntRes2d_Domain& TheParCurveDomain, Standard_Integer& NbResultats, TColStd_Array1OfReal& Inter2_And_Domain2, TColStd_Array1OfReal& Inter1, TColStd_Array1OfReal& Resultat1, TColStd_Array1OfReal& Resultat2, const Standard_Real EpsNul) const { Standard_Integer Nb_Bornes_Intersection = NbResultats; NbResultats = 0; for (Standard_Integer i = 1; i <= Nb_Bornes_Intersection; i += 2) { Standard_Real param1 = Inter1.Value(i); Standard_Real param2 = Inter1.Value(i + 1); Standard_Integer indice_1 = i; Standard_Integer indice_2 = i + 1; if (param1>param2) { Standard_Real t = param1; param1 = param2; param2 = t; indice_1 = i + 1; indice_2 = i; } gp_Pnt2d Pt1 = TheImpTool.Value(param1); gp_Pnt2d Pt2 = TheImpTool.Value(param2); gp_Pnt2d Pt; Standard_Boolean IsOnTheImpCurveDomain1 = Standard_True; Standard_Boolean IsOnTheImpCurveDomain2 = Standard_True; //-------------------------------------------------------------------- if (TheImpCurveDomain.HasFirstPoint()) { if (param1 TheImpCurveDomain.FirstTolerance()) { IsOnTheImpCurveDomain1 = Standard_False; } } } if (IsOnTheImpCurveDomain1 && TheImpCurveDomain.HasLastPoint()) { if (param1>TheImpCurveDomain.LastParameter()) { if (Pt1.Distance(TheImpCurveDomain.LastPoint()) > TheImpCurveDomain.FirstTolerance()) { IsOnTheImpCurveDomain1 = Standard_False; } } } //-------------------------------------------------------------------- if (TheImpCurveDomain.HasFirstPoint()) { if (param2 TheImpCurveDomain.FirstTolerance()) { IsOnTheImpCurveDomain2 = Standard_False; } } } if (IsOnTheImpCurveDomain2 && TheImpCurveDomain.HasLastPoint()) { if (param2>TheImpCurveDomain.LastParameter()) { if (Pt2.Distance(TheImpCurveDomain.LastPoint()) > TheImpCurveDomain.FirstTolerance()) { IsOnTheImpCurveDomain2 = Standard_False; } } } if (IsOnTheImpCurveDomain1) { //------------------------------------------------------------------ //--- la borne 1 est sur le domaine -- NbResultats++; Resultat1.SetValue(NbResultats, Inter1.Value(indice_1)); Resultat2.SetValue(NbResultats, Inter2_And_Domain2.Value(indice_1)); //--- la borne2 est aussi sur le domaine --- if (IsOnTheImpCurveDomain2) { NbResultats++; Resultat1.SetValue(NbResultats, Inter1.Value(indice_2)); Resultat2.SetValue(NbResultats, Inter2_And_Domain2.Value(indice_2)); } else { //--- Borne1 sur domaine et Borne 2 Hors Domaine --- Standard_Real t; NbResultats++; t = TheImpCurveDomain.LastParameter(); Resultat1.SetValue(NbResultats, t); // Standard_Real popResult = FindV(t,Pt,TheImpTool,TheParCurve, // TheParCurveDomain, // Inter2_And_Domain2.Value(indice_1), // Inter2_And_Domain2.Value(indice_2), // EpsNul); // // Resultat2.SetValue(NbResultats,popResult); Resultat2.SetValue(NbResultats, IntImpParGen_Intersector::FindV(t, Pt, TheImpTool, TheParCurve, TheParCurveDomain, Inter2_And_Domain2.Value(indice_1), Inter2_And_Domain2.Value(indice_2), EpsNul)); } } else { //======= la borne1 n est pas sur le domaine ======== if (IsOnTheImpCurveDomain2) { Standard_Real t; NbResultats++; t = TheImpCurveDomain.FirstParameter(); Resultat1.SetValue(NbResultats, t); Resultat2.SetValue(NbResultats, IntImpParGen_Intersector::FindV(t, Pt, TheImpTool, TheParCurve, TheParCurveDomain, Inter2_And_Domain2.Value(indice_1), Inter2_And_Domain2.Value(indice_2), EpsNul)); NbResultats++; Resultat1.SetValue(NbResultats, Inter1.Value(indice_2)); Resultat2.SetValue(NbResultats, Inter2_And_Domain2.Value(indice_2)); } else { //====== la borne2 et la borne1 sont hors domaine ===== if (param1TheImpCurveDomain.LastParameter()) { Standard_Real t; NbResultats++; t = TheImpCurveDomain.FirstParameter(); Resultat1.SetValue(NbResultats, t); Resultat2.SetValue(NbResultats, IntImpParGen_Intersector::FindV(t, Pt, TheImpTool, TheParCurve, TheParCurveDomain, Inter2_And_Domain2.Value(indice_1), Inter2_And_Domain2.Value(indice_2), EpsNul)); NbResultats++; t = TheImpCurveDomain.LastParameter(); Resultat1.SetValue(NbResultats, t); Resultat2.SetValue(NbResultats, IntImpParGen_Intersector::FindV(t, Pt, TheImpTool, TheParCurve, TheParCurveDomain, Inter2_And_Domain2.Value(indice_1), Inter2_And_Domain2.Value(indice_2), EpsNul)); } } } } } //====================================================================== //-- C o n s t r u c t e u r s e t P e r f o r m IntImpParGen_Intersector::IntImpParGen_Intersector() { done = Standard_False; } //---------------------------------------------------------------------- //-- IntImpParGen_Intersector::IntImpParGen_Intersector(const ImpTool& TheImpTool, const IntRes2d_Domain& TheImpCurveDomain, const ParCurve& TheParCurve, const IntRes2d_Domain& TheParCurveDomain, const Standard_Real TolConf, const Standard_Real Tol) { Perform(TheImpTool, TheImpCurveDomain, TheParCurve, TheParCurveDomain, TolConf, Tol); } //---------------------------------------------------------------------- //-- void IntImpParGen_Intersector::Perform(const ImpTool& TheImpTool, const IntRes2d_Domain& TheImpCurveDomain, const ParCurve& TheParCurve, const IntRes2d_Domain& TheParCurveDomain, const Standard_Real TolConf, const Standard_Real Tol) { Standard_Integer i, nb_segments_solution, nb_points_solution; Standard_Real param1, param2, EpsX, EpsNul, EpsDist; IntRes2d_Transition Trans1, Trans2; gp_Pnt2d pt1, pt2; gp_Vec2d Tan1, Tan2, Norm1, Norm2; IntRes2d_Position Pos1, Pos2; //---------------------------------------------- //-- On teste apres appel aux maths si les bornes //-- des domaines sont des solutions //-- Standard_Boolean HeadOnImp = Standard_False; Standard_Boolean HeadOnPar = Standard_False; Standard_Boolean EndOnImp = Standard_False; Standard_Boolean EndOnPar = Standard_False; this->ResetFields(); IntImpParGen_MyImpParTool TheImpParTool(TheImpTool, TheParCurve); if (!(TheParCurveDomain.HasFirstPoint() && TheParCurveDomain.HasLastPoint())) { Standard_ConstructionError::Raise("Domaine sur courbe incorrect"); } Standard_Integer nb_echantillons = ParTool::NbSamples(TheParCurve, TheParCurveDomain.FirstParameter(), TheParCurveDomain.LastParameter()); EpsX = EPSX; if (EpsX>1.0e-10) EpsX = 1.0e-10; EpsNul = (TolConf <= 1.0e-10) ? 1.0e-10 : TolConf; EpsDist = (Tol <= 1.0e-10) ? 1.0e-10 : Tol; Standard_Real Tolerance_Angulaire = EpsDist; if ((TheParCurveDomain.LastParameter() - TheParCurveDomain.FirstParameter()) < 100.0*EpsX) { EpsX = (TheParCurveDomain.LastParameter() - TheParCurveDomain.FirstParameter())*0.01; } math_FunctionSample Sample2(TheParCurveDomain.FirstParameter(), TheParCurveDomain.LastParameter(), nb_echantillons); math_FunctionAllRoots Sol(TheImpParTool, Sample2, EpsX, EpsDist, EpsNul); if (!Sol.IsDone()) { done = Standard_False; return; } nb_segments_solution = Sol.NbIntervals(); nb_points_solution = Sol.NbPoints(); //-------------------------------------------------------------------- //-- T r a i t e m e n t d e s P o i n t s S o l u t i o n s for (i = 1; i <= nb_points_solution; i++) { gp_Pnt2d Pt; param2 = Sol.GetPoint(i); param1 = FindU(param2, Pt, TheParCurve, TheImpTool); if (TheImpCurveDomain.IsClosed()) { param1 = IntImpParGen::NormalizeOnDomain(param1 , TheImpCurveDomain); } Standard_Boolean IsOnTheImpCurveDomain = Standard_True; if (TheImpCurveDomain.HasFirstPoint()) { if (param1 TheImpCurveDomain.FirstTolerance()) { IsOnTheImpCurveDomain = Standard_False; } } } if (IsOnTheImpCurveDomain && TheImpCurveDomain.HasLastPoint()) { if (param1>TheImpCurveDomain.LastParameter()) { if (Pt.Distance(TheImpCurveDomain.LastPoint()) > TheImpCurveDomain.FirstTolerance()) { IsOnTheImpCurveDomain = Standard_False; } } } if (IsOnTheImpCurveDomain) { TheImpTool.D2(param1, pt1, Tan1, Norm1); ParTool::D2(TheParCurve, param2, pt2, Tan2, Norm2); IntImpParGen::DeterminePosition(Pos1, TheImpCurveDomain, pt1, param1); IntImpParGen::DeterminePosition(Pos2, TheParCurveDomain, pt2, param2); if (Pos1 == IntRes2d_End) EndOnImp = Standard_True; else if (Pos1 == IntRes2d_Head) HeadOnImp = Standard_True; if (Pos2 == IntRes2d_End) EndOnPar = Standard_True; else if (Pos2 == IntRes2d_Head) HeadOnPar = Standard_True; IntImpParGen::DetermineTransition(Pos1, Tan1, Norm1, Trans1, Pos2, Tan2, Norm2, Trans2, Tolerance_Angulaire); IntRes2d_IntersectionPoint IP(pt1, param1, param2 , Trans1, Trans2 , ReversedParameters()); Insert(IP); } } //-- F i n d u T r a i t e m e n t d e s P t s S o l. //-------------------------------------------------------------------- //-- T r a i t e m e n t D e s S e g m e n t s --- //-------------------------------------------------------------------- //-- On a N segments solution sur le domaine de V soit au pire : //-- --> N segments solution sur le domaine de U //-- -->2N segments si la courbe en U est fermee //-- TColStd_Array1OfReal Inter2_and_Domaine2(1, 2 + 8 * nb_segments_solution); TColStd_Array1OfReal Inter1(1, 2 + 8 * nb_segments_solution); Standard_Integer nb_segments_crees = 0; for (Standard_Integer j2 = 1, j = 1; j <= nb_segments_solution; j++, j2 += 2) { Standard_Real param2_inf, param2_sup; Standard_Real param1_inf, param1_sup; gp_Pnt2d Ptemp; Sol.GetInterval(j, param2_inf, param2_sup); param1_inf=FindU(param2_inf,Ptemp,TheParCurve,TheImpTool); param1_sup=FindU(param2_sup,Ptemp,TheParCurve,TheImpTool); //---------------------------------------------------------------------- //-- C o u r b e I m p l i c i t e F e r m e e if (TheImpCurveDomain.IsClosed()) { gp_Vec2d T1, T2, N1, N2; Standard_Real param1_origine, param1_fin; TheImpCurveDomain.EquivalentParameters(param1_origine, param1_fin); Standard_Real Periode = param1_fin - param1_origine; while (param1_inf= 0.0) { //--- param1_inf designe un point entrant (et T1 est vers la matiere) if (param1_inf >= param1_sup) { param1_sup += Periode; } } else { //--- param1_inf : point sortant (et T1 est Hors matiere) if (param1_inf <= param1_sup) { param1_inf += Periode; } } //--- On cree un nouveau segment decale de Periode //-- Exemple de Pb : Domaine PI/4 PI/2 et intervalle 0,PI //-- Domaine 1.5PI 2.5PI et intervalle 0,PI //-- -2pi 0 2pi //-- ------|--------------------|-----------------|----------- //-- [----------------------------] Domaine //-- [~~~~~~~~~~~~~~~~~] Inters. //-- //-- On cree un nouvel intervalle //-- interv decale //-- [a~~~~~~~~~~~~b] [a~~~~~~~~~~~~~~~b] et [a~~~] //-- // if (TheImpCurveDomain.LastParameter() > ((param1_inf>param1_sup) ? (param1_sup + Periode) : (param1_inf + Periode))) { Inter2_and_Domaine2.SetValue(j2, param2_inf); Inter1.SetValue(j2, param1_inf + Periode); Inter2_and_Domaine2.SetValue(j2 + 1, param2_sup); Inter1.SetValue(j2 + 1, param1_sup + Periode); j2 += 2; nb_segments_crees++; } if (TheImpCurveDomain.FirstParameter() <((param1_infVV1) X = VV1; else if (X