BOPAlgo_PaveFiller::MakeBlocks() - Improve Face/Face post treatment procedure by:
* Adding more existing edge for intersection with section edges to resolve all possible intersections.
* Using tree for edges selection.
* Avoiding intersection of the existing edges among themselves.
IntPatch_ImpImpIntersection::CyCyNoGeometric - add more points to wline to make it more smooth.
The following improvements have been introduced in Boolean Operations algorithm s:
1. UBTree is replaced with EBTree in Boolean operations to be able to add/remove elements into the tree of bounding boxes.
2. Repeated (nested) intersection of sub-shapes is performed with argument vertices whose tolerances increased during the operation.
3. The algorithms of Edge/Edge and Edge/Face intersection have been improved for the cases when the intersection point is located close to the edge boundaries .
4. New procedure has been implemented to ensure forced creation of Edge/Face common blocks in cases when the edge is really close to the face.
5. Post-processing of Face/Face intersection results has been improved.
6. Extension of the planar faces for Plane/Plane intersection is avoided.
7. Builder Face now better classifies potentially internal edges relatively to new faces with filtering by bounding boxes.
Side effect changes:
1. IntTools_ShrunkRange now keeps the length of the valid range of the edge.
2. The method BOPDS_DS::UpdateEdgeTolerance() has been removed as unused (replaced by the BOPAlgo_PaveFiller::UpdateEdgeTolerance()).
Test case for the issue 0029900.
Test case for the issue 0029711.
Adjustments of the existing test cases.
Avoid using uninitialized variables.
The usage of *BRepAlgo_Section* has been replaced with the usage of *BRepAlgoAPI_Section* in *BRepProj_Projection* algorithm.
The TODO statements have been removed from the failing test case in the "prj" grid as they are working correctly now.
The following changes have been made to improve the performance *BRepAlgoAPI_Section*:
1. Revision of the *IntPolyh_Intersection* class to avoid repeated calculation of the deflection of the same triangulation.
2. Small revision of the Edge/Face intersection algorithm to perform Extrema computation on the whole intersection range of the edge instead of discrete ranges.
3. Implementation of the extrema computation for the Circle and Sphere.
4. Correct computation of the parameter of the point on the Circle.
In order to improve performance of Boolean Operations on the relatively fast cases the following improvements have been made:
1. Initialization of the FaceInfo information for the faces participating in Face/Face interference, even when the gluing is ON, to take into account intersection of their sub-shapes.
2. Code simplification & duplication removal - the methods BOPAlgo_ShellSplitter::MakeConnexityBlocks and BOPAlgo_WireSplitter::MakeConnexityBlocks have been unified into BOPTools_AlgoTools::MakeConnexityBlocks.
3. Avoid unnecessary bounding box computation for solids during DS initialization. The bounding boxes for solids will be computed during the building stage to find faces located inside solids.
For the shape self-interference check (performed by the BOPAlgo_CheckerSI), the bounding box is still computed, as it is necessary to resolve Shape/Solid intersections.
4. Use only three sample points to check coincidence of line and plane.
5. Perform necessity of planes intersection only when the gluing is off.
6. Avoid repeated initialization of 2D classifier while building splits of the faces.
7. Post treat stage:
7.1. Method CorrectWires: Save edge's data (PCurve, parameter of the vertex, range) to avoid its recalculation.
7.2. Method CheckEdge: While checking vertices on edges avoid unnecessary calculation of their location.
8. Provide possibility to disable the classification of the input solids on the inverted status (to be the holes in the space).
9. Avoid building of bounding boxes for faces/solids during splitting of the input arguments for their classification relatively hole faces/shells if there are no holes created.
10. Avoid rebuilding of the faces/solids from arguments which does not acquire any inside parts from other arguments during the operation by using their draft versions as their splits.
Test cases for the issue.
Correction of the test cases boolean gdml_public A9 and bugs modalg_7 bug28485 as they are improvements.
Additional test case for the issue #28485 as it is fixed by the current changes.
Use of Cotire tool is introduced for acceleration of CMake builds, by usage of precompiled headers.
CMake option BUILD_USE_PCH is added to enable / disable use of precompiled headers
When precompiled headers are used, additional compiler macros are defined globally in the build system to avoid problems due to different order of included files:
- NOMINMAX is defined on Windows to prevent defining "min" and "max" as macros by windows.h
- STRSAFE_NO_DEPRECATE and _SCL_SECURE_NO_WARNINGS are defined on Windows to prevent declaring functions of standard C library as deprecated by #pragma, and other warnings in system headers
- GL_GLEXT_LEGACY and GLX_GLEXT_LEGACY are defined to ensure that only OCCT's own glext.h is used
- __STDC_FORMAT_MACROS is defined to have standard C print format macros always defined
Code is corrected to avoid conflicts with system headers and in case of compiling together as unity builds (partially):
- Some locally defined variables in TKV3d, TKHLR are renamed to be unique
- Duplicated definitions of macros and global functions are eliminated in TKSTEP
- Useless header WNT_UInt.hxx is removed
- Usage of local variables conflicting with X11 macro is avoided in Draw_Viewer.cxx
- Local variables in AIS_ConcentricRelation.cxx are renamed to avoid conflict with macros defined in windows.h
- HXX files containing code are renamed to PXX or merged with corresponding CXX files.
IVtkTools classes are corrected to avoid compiler warnings disabled in non-PCH builds by inclusion of VTK headers.
Useless pragmas disabling warnings on MSVC are removed
1. Exception in intersection of two analytical faces has been fixed by adding a simple check on number of vertices
in the resulting analytical curve;
2. Projection of the Circle on the Cone now checks if the Circle's normal direction is parallel to the Cone direction.
If it is not, the different, more advanced, algorithm will be used for projection - ProjLib_ComputeApprox;
3. Intersection of the Edge with the Face (IntTools_EdgeFace algorithm) in QuickCoincidenceCheck mode has been fixed to
avoid the checking of the type of the intersection result if the coincidence check gives the positive result;
4. All common IN edges of the intersecting faces has been added for intersection with section edges to avoid self-intersection in the result;
5. Post treatment of the section edges in Boolean operations has been improved with the new stage which treats the possible
common zones, not detected by the intersection algorithm, between faces by intersecting each section edge with all faces,
not participated in its creation, and in case of coincidence putting it as IN edge into FaceInfo structure of the face.
The new function has been implemented for that - BOPAlgo_PaveFiller::PutSEInOtherFaces().
6. Checking for the SameDomain splits of faces in Boolean Operations has been modified to process the pairs of faces in
which both the section curves and common zones are present.
7. Adjustment of the test case boolean gdml_private ZH3 as improvement.
8. Test cases for the issue.
9. Test cases for the parent issue - 0026789.
1. Unification of the usage of the BRepAdaptor_Surface in Boolean Operations algorithm.
For each face when it is necessary the Adaptor is initialized only once and stored in Context.
For that purpose the new IntTools_Context::SurfaceAdaptor(const TopoDS_Face&) method has been implemented.
To provide possibility to take the Adaptor from the context, the context has been added as
a parameter in following methods:
BOPTools_AlgoTools::MakePCurve()
BOPTools_AlgoTools::Sence()
BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace()
BOPTools_AlgoTools2D::PointOnSurface
BOPTools_AlgoTools2D::CurveOnSurface
BOPTools_AlgoTools2D::AdjustPCurveOnFace
BOPTools_AlgoTools2D::Make2D
BOPTools_AlgoTools2D::MakePCurveOnFace
BOPTools_AlgoTools3D::GetNormalToFaceOnEdge
It is also possible now to pass the context into BOPAlgo_WireSplitter algorithm.
Also, the new IntTools_Context::UVBounds(const TopoDS_Face&) method
has been implemented to get the UV bounds of a face.
2. Additional improvement is a calculation of reduced intersection range only for the intersection
type VERTEX during computation of Edge/Face interference.
3. The methods IntTools_EdgeFace::Prepare() and IntTools_EdgeFace::FindProjectableRoot()
and the fields IntTools_EdgeFace::myProjectableRanges and IntTools_EdgeFace::myFClass2d
have been removed as obsolete.
4. Test cases for the issue.
When fuzzy option is in force prevent increasing tolerance of input shapes. Instead pass increased by fuzzy value the tolerances of sub-shapes everywhere where it is needed by intersection algorithms.
The following changes in API have been made:
- The methods SetFuzzyValue and FuzzyValue have been moved from the classes BOPAlgo_ArgumentAnalyzer, BOPAlgo_Builder, and BOPAlgo_PaveFiller to the base class BOPAlgo_Algo.
- The public method BOPDS_DS::VerticesOnIn has been renamed to SubShapesOnIn, and the new output parameter theCommonPB has been added.
- In BOPTools_AlgoTools, a new argument "theFuzzyValue" has been added in the methods ComputeVV and AreFacesSameDomain.
- In IntTools_Context, a new argument "theFuzzyValue" has been added in the methods ComputeVE and ComputeVF.
- The methods SetFuzzyValue and FuzzyValue have been added in the classes IntTools_EdgeEdge, IntTools_FaceFace.
- In the class IntTools_EdgeFace, the methods SetTolE, SetTolF, TolE, TolF have been removed, and the methods SetFuzzyValue, FuzzyValue have been added.
- The new argument "theTol" has been added in the method IntTools_WLineTool::DecompositionOfWLine.
Some improvements in algorithms have been made during fighting with regressions:
- Correct initialization of pave blocks for degenerated edges.
- In BOPAlgo_PaveFiller::MakeBlocks(), filter out paves on intersection curve that were put on the curve accidentally due to wide range of E-F intersection vertex.
- In the method IntTools_Tools::ComputeTolerance the margin added to the computed tolerance has been increased up to 0.001%.
- The method BOPAlgo_PaveFiller::PutPaveOnCurve has been corrected in order to use the original vertex tolerance instead of the value increased during putting it on other curves.
- The new method BOPDS_PaveBlock::RemoveExtPave has been added.
- The vertex tolerance computation in BOPTools_AlgoTools::CorrectCurveOnSurface has been improved, taking into account intersection segments between p-curves (to avoid regression on "bugs modalg_6 bug22794").
- Improve IsExistingPaveBlock to make more stable catching of coincidence of common block with section curve (against regression "bugs modalg_4 bug697_2" on Linux).
Test case for the bug has been added.
The following test cases have been updated as improvements:
boolean gdml_private ZH2 ZI7 ZJ7
boolean volumemaker C4
The test case bugs/modalg_4/pro19653 has been corrected to make it stable. See comment inside the script for details.
The test case bugs/modalg_6/bug25880 has been corrected to suppress wrong bfuse commands.
The test bugs/modalg_6/bug26954_3 has been corrected to compare the result with more precise reference value.
The "faulty" TODO in boolean/volumemaker/A8 has been made actual for Linux as well.
//Eliminate compilation error on Linux.
1. The procedures for check of coincidence between Edge-Edge and Edge-Face have been added. These methods are used instead of searching interferences between corresponding sub-shapes. In most cases (including case for this issue), new methods are more reliable and faster than intersections. However, its use should be avoided in case when the edge is not coincide with edge/face of another argument evidently (e.g. if edge vertices are not in another edge/face).
2. Interface of both IntTools_EdgeFace and IntTools_EdgeEdge has been changed (adding/deleted some field and methods).
Some test cases have been corrected in accordance with their new behavior.
Test case for issue CR26132.
0026796: The result of General Fuse operation is self-intersecting shape
The fix forces creation of new sub-shapes (vertex, edge) when the tolerance of some sub-shape of an argument is to be increased.
This new behavior is turned off by default. It can be turned on using two ways:
1) Setting 'locking' flag of the arguments.
2) Calling the method SetNonDestructive(Standard_True) of the API classes.
Various bug fixes in the algorithm:
- Compute correct tolerance values for intersections of type Line/Line, Line/Plane, Plane/Plane.
- In case of Line/Plane intersection check if line's vertices lie on the plane.
- Do not allow decreasing of the tolerance value of the Line/Line intersection vertex.
- In IntTools_EdgeEdge, call the method FindParameters with proper 3D tolerance of the curve.
- Force making copy of a degenerated edge if its vertex is touched but no 2D intersection with other curves is found.
- Remove pave blocks both ends of which became referring to the same vertex after vertices substitution.
- Avoid exception in IntTools_Context::IsVertexOnLine if Extrema is not done.
- Reduce tolerance of vertex/edge using actual distances to interfered shapes if it was increased due to line/line, line/plane, or plane/plane small intersection angle.
- Update tolerance of edges to reach all representations in a common block.
- In V-E intersections, check if a vertex hits beyond shrunk range, in such case create V-V interference.
- Do not put a section edge to the result if it becomes to be a micro edge after updating its vertex.
- Correctly make vertices same-domain during the work of MakeBlocks.
- Decrease shrunk range at least on a Precision::Confusion() in addition to vertex tolerance.
- Add Confusion to bounding boxes of new shapes in DS
- Add tolerance Precision::Confusion() to compare distances of touching cases to fix regressions.
TODO marks have been removed from (or modified in) the following test cases (Improvements):
boolean bsection M3 N2 R2
boolean gdml_private B6 C2 C6 G7 I6 F6 J1 J4 M7 N1 N8 N9 O3 O4 O6 O8 O9 P1 P2 P5 Q1 Q3 Q5 S9 T2 U4 U5 U9 ZB5 ZB6 ZC1 ZC5 ZD3 ZD6 ZD7 ZH2 ZH5 ZI2 ZI5 ZI7 ZI9 ZJ3 ZJ4 ZJ7 F8 I6 G1
boolean volumemaker A5 A6 B3 B4 B7 B9 D3 D4 D7 F1
boolean bopcut_2d D5
bugs modalg_5 bug25043
bugs modalg_2 bug472_1 bug472_2 bug472_3
Test cases updated because they are still bad but can be accepted as non-regression:
boolean volumemaker C4 A3 A7 E6
bugs modalg_1 bug10232
boolean bsection N2
Put new TODO in the scripts:
bugs modalg_5 bug25232_9
bugs modalg_6 bug26619
bugs modalg_1 buc60462_2
bugs modalg_4 bug772
For the following tests the result in fix became better, so take fix result as the reference:
bugs modalg_5 bug24628
bugs modalg_6 bug26954_3
boolean volumemaker A4 B5 B6 C3 C8 D2 D5 F2
bugs modalg_2 bug472_2
bugs modalg_1 buc60776_1
- Add the method SetNonDestructive to API classes of user level
1) Macro definition WNT replaced by _WIN32 and _MSC_VER for platform and compiler detection accordingly.
2) Macro definition LIN replaced by __linux__ macro.
3) Macro definition DEB replaced by OCCT_DEBUG macro.
Automatic upgrade of OCCT code by command "occt_upgrade . -nocdl":
- WOK-generated header files from inc and sources from drv are moved to src
- CDL files removed
- All packages are converted to nocdlpack
Package SortTools and its derived classes are removed; STL sort algorithms are used instead.
Comparator objects are mostly reimplemented as local classes.
1. class BOPAlgo_PaveFiller
method void BOPAlgo_PaveFiller::PerformEF()
Do not create intersection vertices in case if it lies ON the boundary of the face.
2. class IntTools_Context
New method
Standard_Boolean IntTools_Context::IsPointInFace
(const gp_Pnt& aP,
const TopoDS_Face& aF,
const Standard_Real aTol)
has been implemented to check if the point IN the face.
3. class IntTools_EdgeFace
method
void IntTools_EdgeEdge::FindBestSolution(const Standard_Real aT11,
const Standard_Real aT12,
const Standard_Real aT21,
const Standard_Real aT22,
Standard_Real& aT1,
Standard_Real& aT2)
Treatment of the touching cases.
Test cases for issue CR24646
Correction of test cases for issue CR24646
Changes:
1. class IntTools_EdgeFace
method:
Standard_Boolean IntTools_EdgeFace::CheckTouchVertex
(const IntTools_CommonPrt& aCP,
Standard_Real& aTx)
The parametric size of the contact zone between vertex and face has been changed
Test cases for issue CR25449
Classes BOPInt_Context, BOPInt_ShrunkRange, BOPInt_Tools have been removed.
Package BOPInt has been removed
Classes IntTools_Context, IntTools_ShrunkRange have been added to replace corresponding BOPInt_ classes.
The classes provide same functionality as corresponding BOPInt_ classes.
Classes :
BOPAlgo_ArgumentAnalyzer
BOPAlgo_Builder
BOPAlgo_BuilderArea
BOPAlgo_BuilderFace
BOPAlgo_BuilderSolid
BOPAlgo_CheckerSI
BOPAlgo_PaveFiller
BOPAlgo_ShellSplitter
BOPTools_AlgoTools3D
BRepFill_TrimShellCorner
IntTools_BeanFaceIntersector
IntTools_EdgeFace
IntTools_FaceFace
IntTools_Tools
have been modified to use new classes IntTools_Context IntTools_ShrunkRange
Class IntTools_Tools has been modofied to provide the functionality that was in BOPInt_Tools.
Blend_Walking_1: value returned by TestArret() deleted.
IntTools_EdgeFace: deleted redundant parameter ff2 and anIsProj2 associated with ff2, since ff2 = !ff1. Refactoring.
ProjLib_ProjectedCurve: treatment of surface of revolution is symmetric for surface of revolution now. Refactoring.
License statement text corrected; compiler warnings caused by Bison 2.41 disabled for MSVC; a few other compiler warnings on 54-bit Windows eliminated by appropriate type cast
Wrong license statements corrected in several files.
Copyright and license statements added in XSD and GLSL files.
Copyright year updated in some files.
Obsolete documentation files removed from DrawResources.
When warnings are enabled, compilers report lots of occurrences
of unused local variables, which makes it harder to find other
meaningful warnings.
This commit does not fix all unused local variables.
Fix new type conversion warning
Code cleaned to avoid MSVC compiler warnings on unused function arguments.
Several useless pieces of code are removed.
Changes in IntTools_EdgeFace.cxx, Blend_Walking_1.gxx, Bnd_BoundSortBox.cxx, ProjLib_ProjectedCurve.cxx are reverted (separated to specific issue for more in-depth analysis).
- method:IntTools_EdgeFace has been changed
Standard_Boolean IntTools_EdgeFace::IsProjectable(const Standard_Real aT) const
The checking the distance between the point on the curve projected point has been added.
IntTools packages were modified
Test cases for issue CR24266
Got rid of warning -Wunused-variable
In FSD_File, use template specialization instead of comparison of sizeof() to specific value in if statement, thus eliminating warning "constant value in conditional expression"
Removing pPotentially uninitialized local variable
Got rid of most of warnings C4701: Potentially uninitialized local variable
Removed redundant variable definitions.
Refactored a part of AppParCurves_ResolConstraint CTOR.
Replaced 0. to Precision::Confusion for tolerance vars;
Changed values for min and max parameter vars;
Got rid of redundant variables' initialization.
Fix first subset of warnings (about 100)
- while(1) and similar constructs replaced by for(;;)
- some uninitialized variables corrected
Got rid of Warning C4189: local variable is initialised but not referenced
Corrected mistakes after getting rid of C4189 compiler warning
Corrected some mistakes that led to compiling errors
Fixed test case because of improvement message - removed unnecessary TODO.
Small fix: tabs have been replaced with whitespaces.
Added TODO for Windows platform
removed last TODO
Corrected mistakes, returned some #ifdef DEB code, fixed test case .
Restoring a few places which have been modified too much
Small grammar fix
Deleted unnecessary puts in bugs/end
Modifications:
- BRepOffset/BRepOffset_Tool.cxx, Features and Fillets algorithms have been ported on new BO algorithm.
- Old BO algorithm, that was implemented in BOP, BooleanOperations and BOPTools packages, has - been deleted.
- Porting SALOME algorithms to new BOP algorithm.
- Fixing regressions. Rebased on current master.
- Corrections in post treatment of section edges;
- Corrections in the accordance with the bug 0023293;
- Small corrections in the bopcheck and bopargcheck commands.
- NCollection maps have been replaced by NCollection indexed maps to guarantee the constant order of sub-shapes in the result of boolean operation.
- Test case feat featprism M9 has been fixed.
- Test cases chl 902 E3 H3 have been fixed (corrections in the treatment of section edges).
- Test cases caf driver B6 B7, caf named_shape F6 F7 have been modified according to the new order of sub-shapes in the result of boolean operation.
- Test cases blend buildevol G1, blend simple K4, bcommon_complex C7, feat featprism L6 have been modified as they are improvements.
- Test case boolean bsection A3 has been modified according to the new syntax of the bsection command.
- Test cases boolean bfuse_complex J1 P9 have been fixed (the function IsInternalFace has been modified to use the function GetFaceOff);
- Test case chl 902 H3 has been fixed (changes in the treatment of section edges);
- Test case boolean bsection D8 has been modified (removed TODO statement);
- Test case boolean bsection A3 has been modified (as the shapes have been changed).
- Added correction of the tolerance values of the shapes according to the bug 0023610.
- test cases:
boolean bcommon_complex C3,
boolean bcut_complex F2 O7,
boolean bfuse_complex C4 C5 E4,
boolean bsection B6 M8 M9 N4 N5 N7,
boolean bfuse_simple ZP6,
draft angle G8,
feat featprism S2
have been marked as invalid according to the bug 0022033;
- New value of result has been set in the test cases :
boolean bopsection D4
boolean bsection R8
as it is correct.
- test case bugs modalg bug23472 has been rewritten according to the new format of bsection command.
- The classes IntTools_Context and IntTools_ShrunkRange have been replaced by BOPInt_Context and BOPInt_ShrunkRange accordingly.
- The new class BRepAlgoAPI_Check has been added according to the bug 0023648.
- Some regressions have been fixed.
- The following test cases have been marked as invalid or rewritten
bugs modalg buc60462_2, 60531_2, 60776_1, bug472_1, bug472_2, bug472_3, bug497_3, bug62
bugs moddata bug26_1, bug26_2,
- The test case bugs modalg buc60533 has been rewritten to use the general fuse algorithm for building the result.
- The new value of the result has been set in the test case bugs modalg 60776_2.
- The following test cases have been rewritten according to the new format of the bsection command
bugs modlag fra62369, pro18892
bugs moddata bug75_1, bug75_2
- Corrected BRepAlgoAPI_Check.
- Removed package BOPTColStd.
- Rewritten test cases caf named_shape F8 F9.
- Removed unnecessary comments.
- Corrected the following test scripts :
boolean bcut_complex(012) O3 O4 O5 O6 O8
boolean bfuse_complex(013) O5 O6 P8
boolean bopcommon_complex(021) D8 D9
boolean bopfuse_complex(022) H1 J6
boolean boptuc_complex(024) D5
bugs modalg(006) bug399 bug497_1
feat featprism(003) C4
- Corrections in the treatment of section edges (putting paves on the curves);
- Corrections in BRepOffset_Tool;
- The following test cases have been rewritten according to the new format of the bsection command
bugs modalg bug6502, bug6554, bug6766_1, bug6766_3
- The new value of the result has been set in the following test cases
bugs modalg bug1255, bug1255_1
- The following test cases have been marked as invalid or rewritten
bugs modalg bug472_2, bug472_3, bug825_2
bugs moddata bug10603, bug152_1, bug152_2, bug3721_1, bug3721_2, bug3721_3
- The following test cases have been rewritten as improvements
bugs modalg bug693, bug693_1, bug817_1
bugs moddata bug3721_5, bug3721_6, bug6862_3, bug6862_4, bug6862_6
- Test cases bugs modlag buc60787_1, buc60787_2, buc60788_2, buc60788_3 have been corrected.
- Fixed some SALOME regressions (modifications in the treatment of the section edges);
- Fixed test case bugs modalg bug23100;
- Test cases bugs modalg bug21754, bug22990 have been corrected according to the new format of the bsection command.
- Test cases bugs modalg bug13116_*, bug23711 have been fixed;
- Test cases bugs modalg bug697_2, bug697_4, bug697_7, bug697_8 have been marked as invalid according to the issue 0022033;
- Test cases bugs modalg bug22109_2, bug22109_3 have been corrected;
- Test case bugs modalg bug18186 has been corrected as it is improvement;
- Test case bugs modalg bug22802 has been deleted as there is no package BOPTColStd.
1) Warning in Aspect.cxx couldn't be reproduced
2) Description of changes: added 'return' statements into ReadStep(...) functions of RWStepBasic_* classes.
3) BRepFill_OffsetWire.cxx - removed dead code;
4) IFSelect_WorkSession.cxx - swapped arguments;
5) TopOpeBRep_ShapeIntersector2d.cxx - removed 'brake' statement and changed loop to if-statement because of
void TopOpeBRep_ShapeIntersector2d::FindFFIntersection() function's call features.
6) V2d_RectangularGraphicGrid.cxx - left constants instead of functions beacuse of faster perfomance.
7) Commented unreachable code in files GeomFill_LocationGuide.cxx and TopOpeBRepTool_mkTondgE.cxx