Compare commits

...

185 Commits

Author SHA1 Message Date
Laurent Rineau a14621b595 fix license 2025-12-04 11:33:18 +01:00
Laurent Rineau 5d1f3306a6 WIP: new way to construct the cavity 2025-12-04 11:14:00 +01:00
Laurent Rineau ff9223ab21 fix precision 2025-12-04 11:09:44 +01:00
Laurent Rineau 25e41104d1 new datasets 2025-12-04 11:09:23 +01:00
Laurent Rineau 52740b5b6d Merge branch 'Stream_support-color_and_indenting_streams-lrineau' into CDT_3-fix_v2-lrineau
# Conflicts:
#	Installation/CHANGES.md
2025-12-03 12:07:05 +01:00
Laurent Rineau 6df6b69d7b Merge remote-tracking branch 'cgal/main' into CDT_3-fix_v2-lrineau 2025-12-03 12:05:54 +01:00
Laurent Rineau fdbbdb4cdc fixes the tools
-  bisect_failures no longer compare CGAL assertion messages
- rewrite Exception_ostream, because throwing in an `ios_base` operation has no effect but setting the bad bit.
2025-12-02 16:53:12 +01:00
Laurent Rineau 284d228b96 WIP on does_tetrahedron_intersect_triangle_interior 2025-12-02 16:51:27 +01:00
Laurent Rineau 2d56c7bfe6 better bisection 2025-12-02 16:51:09 +01:00
Laurent Rineau 7aa81c4505 two extra minified datasets 2025-12-02 16:50:55 +01:00
Laurent Rineau 93c4a44b90 fix clangd warnings (IWYU warnings) 2025-12-01 09:34:30 +01:00
Laurent Rineau dbcace69e6 fix oddities inherited from LaTeX 2025-11-26 11:52:09 +01:00
Laurent Rineau 88fea191ec Merge remote-tracking branch 'cgal/main' into Stream_support-color_and_indenting_streams-lrineau
# Conflicts:
#	Installation/CHANGES.md
2025-11-26 10:07:04 +01:00
Laurent Rineau bac686d05b
Fix leftover qt5 (#9152)
## Release Management

* Affected package(s): `GraphicsView`
* Issue(s) solved (if any): -
* Feature/Small Feature (if any): -
* License and copyright ownership: no changes
2025-11-26 09:39:38 +01:00
Laurent Rineau 30f63794c3
Spelling correction (#9146)
Spelling correction
2025-11-25 23:30:39 +01:00
Laurent Rineau 2d1da34beb fix getenv_s for Windows 2025-11-25 16:29:43 +01:00
Mael Rouxel-Labbé d14619c335 Fix leftover qt5 2025-11-24 21:23:08 +01:00
Laurent Rineau 50a187db38 fix Markdown lint warnings
There were real formatting issues.
2025-11-24 12:21:49 +01:00
Laurent Rineau 95a315335f remove duplicate paragraphs 2025-11-24 11:44:55 +01:00
Sébastien Loriot ff5166fbee fix version 2025-11-24 10:21:41 +01:00
Sébastien Loriot 9f2fcb5e28 Merge remote-tracking branch 'cgal/6.1.x-branch' into 'cgal/main' 2025-11-21 17:41:27 +01:00
Sebastien Loriot 85ef57ffa1
CDT_3 bug-fix: throw exceptions instead of raw crashs (like segfaults) (#9089)
## Summary of Changes

Bug-fix for `CGAL::Conforming_constrained_Delaunay_triangulation_3` in
CGAL-6.1.

## Release Management

* Affected package(s): Constrained_triangulation_3
* License and copyright ownership: GeometryFactory
2025-11-21 17:40:00 +01:00
Sebastien Loriot aefbc23955
precompiled demos for CGAL-6.1 (#9132)
## Summary of Changes

Small fixes for precompiled demos

## Release Management

* Affected package(s): Maintenance
* License and copyright ownership: N/A
2025-11-21 17:39:12 +01:00
albert-github da0f634cb2 Spelling correction
Spelling correction
2025-11-21 11:10:23 +01:00
Laurent Rineau 7bf5687d5d Remove -fexperimental-library 2025-11-21 10:42:35 +01:00
Sebastien Loriot 1069678f36
Optimize the `do_intersect()` functions of the 2D Regularized Boolean Set Operation" package (made it tolerant to inexact kernels.) (#9050)
## Summary of Changes

Optimized `do_intersect(polygon, polygon)`, `do_intersect(begin, end)`,
and `do_intersect(begin1, end1, begin2, end2)`:
(i) Terminated the execution once an intersection is detected. (In the
past, the intersection was computed in one phase and examined in a
subsequent phase.)
(ii) Made the variants of the free functions `do_intersect()` that apply
to linear polygons, robust even with an inexact-construction kernel. The
variants that apply to generalized polygons endure inexact constructions
much more than before; however, there are rare degenerate cases that are
still require an exact construction kernel.

In general, the changes described here do not affect the default
interface, so a small feature is not required. However, it is a major
impact, and it does affect the interface as described bellow, and even
somehow break backward compatibility.

Recently, the code of the package "2D Regularized Boolean Set
Operations" was optimized. In particular, a 3rd optional parameter was
introduced in the free functions. It determined whether the boundaries
of the input polygons are treated as cyclic sequences of single
(`x`-monotone) segments or as a cyclic sequences of (`x`-monotone)
polylines. The change described here eliminates this 3rd parameter, and
brings the interface of the `do_intersect() function back to the
original design with two input polygons.

## Release Management

* Affected package(s): Boolean_set_operations_2, Surface_sweep,
Arrangement_on_surface_2
* Feature/Small Feature (if any):
[here](https://cgalwiki.geometryfactory.com/CGAL/Members/wiki/Features/Small_Features/do_intersect_polygon_2_predicates_only)
* Link to compiled documentation (obligatory for small feature) [*wrong
link name to be changed*](httpssss://wrong_URL_to_be_changed/Manual/Pkg)
* License and copyright ownership: TAU
2025-11-21 09:21:02 +01:00
Laurent Rineau cda931ec46 fix a warning 2025-11-20 15:23:40 +01:00
Sébastien Loriot 583a8364c9 Merge remote-tracking branch 'cgal/6.1.x-branch' into 'cgal/main' 2025-11-20 10:29:11 +01:00
Sebastien Loriot 3ebe9203a7
Fix PMP on i386/i686 (32 bits, with the x87 FPU) (#8911)
## Summary of Changes

Fix PMP on i386/i686 (32 bits, with the x87 FPU).

## Release Management

* Affected package(s): PMP, Number_types
2025-11-20 10:28:31 +01:00
Sebastien Loriot bf25dd27b8
Stream support: Fix for Epeck (#9072)
## Summary of Changes

For file formats that expect floating point coordinates we convert on
the fly so that `CGAL::io::write_polygon_soup()` also works for polygon
soups with ` FT` which are non-float/double, e.g.
`Exact_predicates_exact_constructions_kernel`.
Additionally, we document the named parameter `point_map` as it was
missing.

## Release Management

* Affected package(s): Stream_support
* Issue(s) solved (if any): fix #9071
* License and copyright ownership: unchanged 
* upon integration update and test #9109
2025-11-20 10:27:33 +01:00
Sebastien Loriot 8ee288ee22
Spelling correction (#9144)
Spelling correction
2025-11-20 09:29:55 +01:00
albert-github e9fb73cadf Spelling correction
Spelling correction
2025-11-19 15:28:15 +01:00
Sébastien Loriot f98d968ed0 Merge remote-tracking branch 'cgal/6.1.x-branch' into 'cgal/main' 2025-11-19 14:46:33 +01:00
Sébastien Loriot 9bd1705bf8 Merge remote-tracking branch 'cgal/6.0.x-branch' into 'cgal/6.1.x-branch' 2025-11-19 14:45:21 +01:00
Sebastien Loriot 0fc710e95d
Fix bad 'if' condition & warning (#9126)
## Summary of Changes

```
Building CXX object test/Stream_support/CMakeFiles/issue8155.dir/issue8155.cpp.o
cd /home/cgal_tester/build/src/cmake/platforms/ArchLinux-clang-CXX20-Release/test/Stream_support && /bin/clang++ -DCGAL_DATA_DIR=\"/mnt/testsuite/data\" -DCGAL_TEST_SUITE=1 -DCGAL_USE_GMPXX=1 -I/home/cgal_tester/build/src/cmake/platforms/ArchLinux-clang-CXX20-Release/include -I/mnt/testsuite/include -isystem /usr/local/boost/include -Wall -O3 -std=c++20 -DCGAL_NDEBUG -MD -MT test/Stream_support/CMakeFiles/issue8155.dir/issue8155.cpp.o -MF CMakeFiles/issue8155.dir/issue8155.cpp.o.d -o CMakeFiles/issue8155.dir/issue8155.cpp.o -c /mnt/testsuite/test/Stream_support/issue8155.cpp
/mnt/testsuite/test/Stream_support/issue8155.cpp:27:17: warning: overlapping comparisons always evaluate to true [-Wtautological-overlap-compare]
   27 |     if (len > 0 || len != 1.0) {
      |         ~~~~~~~~^~~~~~~~~~~~~
1 warning generated.
```


https://cgal.geometryfactory.com/CGAL/testsuite/CGAL-6.2-Ic-36/Stream_support/TestReport_cgaltest_ArchLinux-clang-CXX20-Release.gz

## Release Management

* Affected package(s): `Stream_support`
* Issue(s) solved (if any): n/a
* Feature/Small Feature (if any): n/a
* License and copyright ownership: no change
2025-11-19 14:43:26 +01:00
Sebastien Loriot dee5ed8cc2
Fix edge collapse with incident non-triangular faces (#9117)
Make collapse able to handle non-triangular faces. The fix is easy as
you simply don't need to join faces in case the face won't disappear
after collapse

**TODO:**
update doc and constrained version
2025-11-19 14:42:28 +01:00
Sebastien Loriot 737bcb264e
Doc: fixing thirdparty links (#9134)
## Summary of Changes

fixed Metis/Eigen3/Qt6 links in Thirdparty
removed LEDA from doc as it is outdated

## Release Management

* Affected package(s): Documentation
2025-11-19 14:41:58 +01:00
Sebastien Loriot 2f9854b422
Fix warning about discarding return type of function with [[nodiscard]] (#9127)
## Summary of Changes

```
Building CXX object test/Generator_Demo/CMakeFiles/Generator_2.dir/Generator_2.cpp.o
cd /home/cgal_tester/build/src/cmake/platforms/ArchLinux-clang/test/Generator_Demo && /bin/clang++ -DCGAL_TEST_SUITE=1 -DCGAL_USE_GMPXX=1 -DQT_CORE_LIB -DQT_GUI_LIB -DQT_NO_KEYWORDS -DQT_OPENGLWIDGETS_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -I/home/cgal_tester/build/src/cmake/platforms/ArchLinux-clang/test/Generator_Demo -I/mnt/testsuite/test/Generator_Demo -I/home/cgal_tester/build/src/cmake/platforms/ArchLinux-clang/include -I/mnt/testsuite/include -I/home/cgal_tester/build/src/cmake/platforms/ArchLinux-clang/test/AABB_tree_Demo -isystem /home/cgal_tester/build/src/cmake/platforms/ArchLinux-clang/test/Generator_Demo/Generator_2_autogen/include -isystem /usr/include/qt6/QtCore -isystem /usr/include/qt6 -isystem /usr/lib/qt6/mkspecs/linux-g++ -isystem /usr/include/qt6/QtOpenGLWidgets -isystem /usr/include/qt6/QtOpenGL -isystem /usr/include/qt6/QtGui -isystem /usr/include/qt6/QtWidgets -Wall  -fno-direct-access-external-data -MD -MT test/Generator_Demo/CMakeFiles/Generator_2.dir/Generator_2.cpp.o -MF CMakeFiles/Generator_2.dir/Generator_2.cpp.o.d -o CMakeFiles/Generator_2.dir/Generator_2.cpp.o -c /mnt/testsuite/test/Generator_Demo/Generator_2.cpp
In file included from /mnt/testsuite/test/Generator_Demo/Generator_2.cpp:27:
In file included from /mnt/testsuite/include/CGAL/Qt/DemosMainWindow.h:130:
/mnt/testsuite/include/CGAL/Qt/DemosMainWindow_impl.h:224:3: warning: ignoring return value of function declared with 'nodiscard' attribute [-Wunused-result]
  224 |   about_CGAL.open(QIODevice::ReadOnly);
      |   ^~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~
1 warning generated.
```


https://cgal.geometryfactory.com/CGAL/testsuite/CGAL-6.2-Ic-36/Generator_Demo/TestReport_gimeno_ArchLinux-clang.gz

## Release Management

* Affected package(s): `GraphicsView`
* Issue(s) solved (if any): n/a
* Feature/Small Feature (if any): n/a
* License and copyright ownership: no change
2025-11-19 14:41:07 +01:00
Sven Oesau e12a760f03 fixed Metis/Eigen3/Qt6 links in Thirdparty
removed LEDA from doc as it is outdated
2025-11-13 16:32:40 +01:00
Mael eb992b38ca
Fix missing I/O function links 2025-11-13 15:20:23 +01:00
Laurent Rineau 1602be1348 precompiled demos for CGAL-6.1 2025-11-13 13:29:35 +01:00
Andreas Fabri ba17e0bdde cleanup an example 2025-11-13 11:05:26 +00:00
Laurent Rineau 12445cc6e1 revert unintended modification 2025-11-13 11:52:21 +01:00
Sébastien Loriot e7205b985d Merge remote-tracking branch 'cgal/6.1.x-branch' into 'cgal/main' 2025-11-13 10:42:42 +01:00
Sébastien Loriot 12a0f67674 Merge remote-tracking branch 'cgal/6.0.x-branch' into 'cgal/6.1.x-branch' 2025-11-13 10:41:53 +01:00
Sebastien Loriot 07347da411
Fix Ceres deprecation warning (#9121)
## Summary of Changes

Changing the used cmake target for Ceres to Ceres::ceres.

## Release Management

* Affected package(s): Installation, Polygon_mesh_processing
2025-11-13 10:02:36 +01:00
Andreas Fabri 1dc39039e9 merge cgal/main 2025-11-13 08:48:43 +00:00
Sebastien Loriot 1673cd0f9e
Fix OBJ loader crashing the demo on reading failure (#9128)
## Release Management

* Affected package(s): `Lab`
* Issue(s) solved (if any): a few entries in #6690 
* Feature/Small Feature (if any): n/a
* License and copyright ownership: no change
2025-11-13 09:40:07 +01:00
Sebastien Loriot dfc5fb5065
IO: write_PLY() for Epeck (#7874)
## Summary of Changes

As reported in #7868 the function `CGAL::IO::write_PLY()` used in binary
mode does not correctly write the coordinates if the points are from a
kernel with exact constructions.
~~This PR applies `to_double()" to the coordinates.~~

~~After a discussion with @MaelRL we decided that the user is in charge
to pass a `vertex_point_map` as named parameter that does the
conversion. This is straightforward as we offer the
[`Cartesian_converter_property_map`](https://doc.cgal.org/latest/Property_map/structCGAL_1_1Cartesian__converter__property__map.html).~~

Moving back to the previous proposal: hardcode some to_double and
to_float casts such that we meet the requirements of the file format,
whatever the input.

As the problem is the same for the vertex normals we add a named
parameter `vertex_normal_map`.

### Todo
- [x] Fix the generic function `write_polygon_mesh()`. Currently it is
fixed for `Surface_mesh`

## Release Management

* Affected package(s): Stream_support
* Issue(s) solved (if any): fix #7868 and fix
https://github.com/CGAL/cgal/issues/7327
* License and copyright ownership:  unchanged
* upcoming integration, update #9072 and test it
2025-11-13 09:38:55 +01:00
Laurent Rineau d226e504c4 fix a warning
use the correct implementation `popupAboutCGAL` from the base class
2025-11-12 16:48:59 +01:00
Laurent Rineau 097fc2c5ab fix memory leaks 2025-11-12 16:48:29 +01:00
Laurent Rineau 77bac5866b address Andreas' comment about the using-declaration 2025-11-12 15:51:28 +01:00
Sébastien Loriot 066159f792 assertion should be before the removal... 2025-11-10 10:17:33 +01:00
Mael Rouxel-Labbé 333a15584f Handle (invalid) zero vertex index in face 2025-11-07 22:02:20 +01:00
Mael Rouxel-Labbé cd787c84d1 Use verbose OBJ reader in Lab 2025-11-07 22:02:08 +01:00
Mael Rouxel-Labbé 0ac856dd41 Fix OBJ loader crahsing the demo on reading failure 2025-11-07 21:00:12 +01:00
Mael Rouxel-Labbé 31734df2ef Fix warning about discarding return type of function with [[nodiscard]] 2025-11-07 17:16:31 +01:00
Mael Rouxel-Labbé 3ef43324bb Fix bad 'if' condition & warning 2025-11-07 17:05:21 +01:00
Sébastien Loriot 3c7d507530 update doc + apply changes to the constrained version 2025-11-06 19:40:48 +01:00
Sébastien Loriot af94906903 leftover from Eigen5 update 2025-11-06 10:08:56 +01:00
Sébastien Loriot 3b0d95e0e5 Merge remote-tracking branch 'cgal/6.1.x-branch' into 'cgal/main' 2025-11-06 10:07:15 +01:00
Sven Oesau ffda347171 adding support for Eigen3 5.0.0 (6.1 version)
moving the Eigen3 version check into CGAL_Eigen3_support.cmake
2025-11-06 10:06:29 +01:00
Sébastien Loriot a9b369650a Merge remote-tracking branch 'cgal/6.0.x-branch' into 'cgal/6.1.x-branch' 2025-11-06 10:04:46 +01:00
Sebastien Loriot faae741666
Eigen3 5.0.0 support (#9112)
## Summary of Changes

Adding support for Eigen3 5.0.0 by updating CMakeLists.txt scripts.

## Release Management

* Issue(s) solved (if any): fix #9110
2025-11-06 10:03:20 +01:00
Sven Oesau 9e36c6744b adding support for Eigen3 5.0.0
moving the Eigen3 version check into CGAL_Eigen3_support.cmake
2025-11-06 10:01:01 +01:00
Laurent Rineau 175b7b9241
Merge branch 'main' into Stream_support-color_and_indenting_streams-lrineau 2025-11-05 09:32:07 +01:00
Laurent Rineau e74cd68cfb add backticks 2025-11-05 09:14:11 +01:00
Sven Oesau 05bf3c4ffc Changing cmake target for Ceres 2025-11-04 17:04:58 +01:00
Sébastien Loriot 7e1f685ea3 changes is for 6.2 2025-11-03 15:49:49 +01:00
Sébastien Loriot f92b41ae0a Merge remote-tracking branch 'cgal/main' into 'efifogel/Bso_2-do_intersect_efif' 2025-11-03 15:47:22 +01:00
Sébastien Loriot e4469c043e handle backward compatibility 2025-11-03 15:46:19 +01:00
Sébastien Loriot 25005a97d8 clean up 2025-11-03 09:24:31 +01:00
Sébastien Loriot 3fe83c7ce0 handle non-triangular faces 2025-10-31 11:36:44 +01:00
Andreas Fabri 622b652652 Add to BGL dependencies 2025-10-30 13:54:35 +01:00
Andreas Fabri 5050b54bfe robustify normal computation for STL 2025-10-30 12:03:22 +01:00
Andreas Fabri 35613b984f Deal with generic version 2025-10-30 11:45:28 +01:00
Andreas Fabri 00f5ae061d Use Simple_cartesian<Exact_rational> 2025-10-30 09:36:53 +01:00
Laurent Rineau 6e2caa7e28 the changelog 2025-10-29 21:48:40 +01:00
Laurent Rineau 27edd158c1 self-review
helped by Copilot
2025-10-29 17:34:57 +01:00
Laurent Rineau 73b8e65b5a fixes after first reviews 2025-10-29 16:19:58 +01:00
Laurent Rineau 7c4a3c1dad do not use std::getenv on Windows 2025-10-29 16:15:57 +01:00
Laurent Rineau eaea32ee9f Stream_support: add indenting and coloring stream wrappers 2025-10-29 14:14:00 +01:00
Andreas Fabri 8623f28bb0 Use internal::construct_normal_of_STL_face() 2025-10-22 10:32:00 +01:00
Andreas Fabri 4c27d08372
Apply suggestions from code review
Co-authored-by: Mael <mael.rouxel.labbe@geometryfactory.com>
2025-10-22 11:17:31 +02:00
Andreas Fabri 4acccc210b Fix in doc of STL_extension 2025-10-21 18:11:12 +01:00
Andreas Fabri 5d82eed3ea
Update Stream_support/include/CGAL/IO/STL.h 2025-10-21 17:26:45 +02:00
Andreas Fabri d9ba43a9ba Make it constexpr to avoid error in CI 2025-10-17 12:40:30 +01:00
Andreas Fabri 98a3051235 copy style 2025-10-17 10:48:26 +01:00
Andreas Fabri da011b2abe No longer #if 0 2025-10-17 10:43:33 +01:00
Andreas Fabri 3706528a0c
Update Stream_support/include/CGAL/IO/PLY/PLY_writer.h
Co-authored-by: Mael <mael.rouxel.labbe@geometryfactory.com>
2025-10-17 11:20:06 +02:00
Sebastien Loriot 878ba3fc53
suggestions from Mael
Co-authored-by: Mael <mael.rouxel.labbe@geometryfactory.com>
2025-10-17 10:28:57 +02:00
Andreas Fabri 62a9c9e04f cleanup 2025-10-15 16:23:59 +01:00
Sébastien Loriot 67349ccbe1 include for boost range 2025-10-15 16:49:15 +02:00
Sébastien Loriot 8215abd980 fix compilation and warnings 2025-10-15 09:57:32 +02:00
Andreas Fabri 358a588eae Deal with binary VTP for non-double kernel 2025-10-14 14:21:39 +01:00
Andreas Fabri c43058de26 Changes after Mael's comments 2025-10-14 09:24:44 +01:00
Sven Oesau 0ffa81d3c4 fix warnings 2025-10-08 13:36:35 +02:00
Andreas Fabri 865c1d2ed7 Fix error in test case 2025-10-06 13:05:32 +01:00
Sébastien Loriot 24024424ef use constexpr 2025-10-02 15:11:02 +02:00
Andreas Fabri 39531baac8 Use has_vnormal 2025-10-02 07:23:22 +01:00
Andreas Fabri 18f1f65bbf Fix plugin 2025-10-01 10:34:24 +01:00
Andreas Fabri 9a99df4a9d Comment static_assert 2025-10-01 09:38:38 +01:00
Andreas Fabri 737079e530 Fix warning 2025-10-01 09:15:54 +01:00
Andreas Fabri 0a743e6a1a Document named parameter verbose 2025-09-30 08:41:58 +01:00
Andreas Fabri 36b66946b8 after Mael's review 2025-09-30 08:30:55 +01:00
Andreas Fabri 89ba13f977 fix doxygen warning 2025-09-30 08:13:22 +01:00
Andreas Fabri 33bd58bbef fix doxygen warning 2025-09-30 06:47:14 +01:00
Andreas Fabri e652a7976a fix doxygen warning 2025-09-29 16:21:33 +01:00
Andreas Fabri 3be4ffce37 Fix plugin 2025-09-29 15:42:59 +01:00
Andreas Fabri 3567ba1456 Fix plugin 2025-09-29 15:08:02 +01:00
Andreas Fabri 806e65f259 undo 2025-09-29 15:05:47 +01:00
Andreas Fabri a9a60b5a00 Fix plugin 2025-09-29 15:01:00 +01:00
Andreas Fabri 92dc53c58a Undo change 2025-09-29 14:20:39 +01:00
Andreas Fabri b97c4b78c3 Convert on the fly to double 2025-09-29 13:55:26 +01:00
Andreas Fabri 5103fb4eb7 merge 2025-09-26 17:18:25 +01:00
Andreas Fabri fad48f7305 Fix dependencies 2025-09-26 17:00:05 +01:00
Andreas Fabri bdee2836df Fix dependencies 2025-09-26 16:16:27 +01:00
Andreas Fabri 39fe8b3a6d convert directly to Simple_cartesian<float> 2025-09-26 16:03:31 +01:00
Andreas Fabri 61cf55efee Convert internally to double as required by file format. Document the point property map which is implemented 2025-09-26 15:46:08 +01:00
Andreas Fabri 0cf9d434b6 Convert internally to double as required by file format. Document the point property map which is implemented 2025-09-26 15:22:32 +01:00
Sebastien Loriot 93d3356dd9
Fix warning 2025-09-23 17:28:04 +02:00
Mael Rouxel-Labbé 561ec37dc6 Remove extra space between NP entries 2025-09-22 11:53:21 +02:00
Mael Rouxel-Labbé 5c058a8c9b Fix missing \relates \ingroup for some property maps 2025-09-22 11:53:06 +02:00
Mael Rouxel-Labbé b668fb4b5a Fix grammar 2025-09-22 11:52:46 +02:00
Andreas Fabri d7cfaccfa1 Add Property_map to dependencies 2025-09-19 15:55:08 +01:00
Andreas Fabri 316c455034 Fix Default for the point_map type 2025-09-19 15:51:53 +01:00
Andreas Fabri 7d4852a60f trailing whitespace 2025-09-19 15:46:42 +01:00
Andreas Fabri 6c4aeabb9d Document the named parameter point_map and use it in the issue 2025-09-19 15:38:46 +01:00
Efi Fogel 9b3132a2cd Pacify MSVC (min/max issue) 2025-09-18 13:16:20 +03:00
Andreas Fabri 967aee62e9 Stream_support: Fix for Epeck 2025-09-18 09:19:19 +01:00
Efi Fogel 05dd65609d Cleaned up; eliminate warnings 2025-09-16 14:41:21 +03:00
Efi Fogel 2e087bc108 Removed unused (formal) variables 2025-09-16 14:41:00 +03:00
Efi Fogel bd6a4ca392 Removed redundant using statement 2025-09-13 19:15:39 +03:00
Andreas Fabri 3988fe2009
Update Gps_on_surface_base_2.h (std::min)(..) 2025-09-12 17:15:07 +02:00
Efi Fogel 0f2aa39b62 Fixed template template use 2025-09-10 18:46:58 +03:00
Efi Fogel ba19fbd67d ops; fixed typo 2025-09-10 18:46:26 +03:00
Efi Fogel 65c797ab44 Fixed definition of template template parameter 2025-09-10 18:38:03 +03:00
Efi Fogel a9e0eeec8f Commented out formal unused variable 2025-09-10 18:36:08 +03:00
Efi Fogel dc422a7531 Removed unused variable (indent) 2025-09-10 18:35:49 +03:00
Efi Fogel e73cf18c12 Removed unused typedefs 2025-09-10 18:35:30 +03:00
Efi Fogel bc29da5ee3 Removed tab 2025-09-09 21:25:12 +03:00
Efi Fogel 1d62c37822 Added some notes to indicate that inexact constructions are tolerated for do_intersect() when applied to (linear) polygons 2025-09-07 00:28:11 +03:00
Efi Fogel 4a6d766d8c Just realized the my the visitor of the surface sweep has never been published, so changes to it are not concidered as breaking backward compatibilty 2025-09-06 20:56:06 +03:00
Efi Fogel f8c9340c1c Enhanced the comment about the optimization of `do_intersect()` of the 2D Regularized Boolean Set Operation package 2025-09-06 20:50:01 +03:00
Efi Fogel 5b6df813f5 Fixed do_intersect() and cleaned up 2025-09-06 20:41:49 +03:00
Efi Fogel b871b81d57 Added a description of an optimization for the do_intersect() of the 2D Regularized Boolean Operation package 2025-09-01 15:34:57 +03:00
Efi Fogel 29715e44a4 Added an alternative divide & conquer for running do_intersect. 2025-08-30 20:47:31 +03:00
Efi Fogel f4a02aeaef Cleaned up 2025-08-30 20:46:42 +03:00
Efi Fogel f69ad03ef8 Interception sweep for do_intersect() 2025-08-28 12:11:48 +03:00
Efi Fogel a366725c85 Enhanced and removed the UsePolylines tag from do_intersect() 2025-08-27 14:39:24 +03:00
Efi Fogel 1c45ed834c Cleaned up 2025-08-26 22:33:24 +03:00
Efi Fogel 375681748d Cleaned up 2025-08-26 22:30:48 +03:00
Efi Fogel 81bb832333 More clean ups 2025-08-26 22:04:00 +03:00
Efi Fogel a74945062c Cleaned up; replaced `typedef` with `using`, etc. 2025-08-26 21:58:34 +03:00
Efi Fogel e5049d4b03 Last touches and fixes for testing whether two polygons intersect 2025-08-26 14:55:53 +03:00
Efi Fogel 1bd923b393 Removed all tags related to polylines 2025-08-26 14:55:22 +03:00
Efi Fogel c677355de2 Removed printout 2025-08-26 14:55:14 +03:00
Efi Fogel 0f528545c7 Suppressed using Polyline with do_intersect() and fixed the do-intersect oberlay sweep-line visitor 2025-08-25 19:10:19 +03:00
Efi Fogel 35721db0b9 Cleaned up 2025-08-25 19:09:36 +03:00
Efi Fogel d41efe0330 Cleaned up 2025-08-25 19:09:21 +03:00
Efi Fogel bf1bc2fc85 Cleaned up 2025-08-25 16:43:17 +03:00
Laurent Rineau e187dc03cb fix 2025-07-02 15:45:22 +02:00
Sébastien Loriot ad20fa497a always declare a value you are using 2025-06-03 18:44:59 +02:00
Sebastien Loriot 4cfd48ba76
fix warning 2025-06-03 18:29:59 +02:00
Laurent Rineau b66c3743ec fix FPU_get_cw with CGAL_ALWAYS_ROUND_TO_NEAREST 2025-05-28 00:52:20 +02:00
Laurent Rineau 5b2887240c fix a precondition
with a 80 bits floating points, it can be wrong when
the two numbers are supposed to be equal.
2025-05-27 23:44:34 +02:00
Andreas Fabri 5171477b26 Fix tests 2024-06-17 15:57:38 +01:00
Andreas Fabri 05014378d6 Add doxygen 2024-06-11 15:50:21 +01:00
Andreas Fabri 0e27e7632c cleanup 2024-06-11 15:36:07 +01:00
Andreas Fabri 7ab9468594 typename 2024-06-11 14:24:03 +01:00
Andreas Fabri a316b67548 Merge remote-tracking branch 'cgal/master' into IO-read_PLY_Epeck-GF 2024-06-11 14:14:18 +01:00
Andreas Fabri ba87b5c2e5 typename 2024-06-11 14:10:56 +01:00
Andreas Fabri a08388c4e3 Also write normals in the generic code 2024-06-11 14:02:31 +01:00
Andreas Fabri 969062e3df Add the possibility to pass a vertex normal map 2024-06-11 13:15:04 +01:00
Mael Rouxel-Labbé cfcc90d649 Add extra lines to clarify that the blocks aren't related 2024-06-10 14:01:24 +02:00
Mael Rouxel-Labbé c5a688590a Test the write output 2024-06-10 14:01:24 +02:00
Mael Rouxel-Labbé 710666a51b Use the normal computation function that uses approximate_sqrt
As to be able to write even for kernels that do not offer sqrt
2024-06-10 14:01:24 +02:00
Andreas Fabri c58286d716 Add #include 2024-06-07 15:30:25 +01:00
Andreas Fabri 6cba601ff3 WIP just to get it working 2024-06-07 15:06:37 +01:00
Andreas Fabri fe86a79bdc Fix the test 2024-06-07 09:01:29 +01:00
Andreas Fabri 7a984104fa Add code that shows the issue 2024-06-07 08:43:36 +01:00
Sébastien Loriot d876fbab69 add missing include 2023-11-22 15:21:04 +01:00
Andreas Fabri 5eb93449c5 Fix ascii output 2023-11-22 08:37:13 +00:00
Andreas Fabri 40dee7d2a0 whitespace 2023-11-20 14:04:56 +00:00
Andreas Fabri 2d72f21107 IO: read_PLY() for Epeck 2023-11-20 13:09:59 +00:00
198 changed files with 8420 additions and 5834 deletions

View File

@ -0,0 +1,236 @@
// Copyright (c) 2025 Tel-Aviv University (Israel).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s): Efi Fogel <efifogel@gmail.com>
#ifndef CGAL_ARR_DO_INTERSECT_OVERLAY_2_H
#define CGAL_ARR_DO_INTERSECT_OVERLAY_2_H
#include <CGAL/license/Arrangement_on_surface_2.h>
#include <CGAL/disable_warnings.h>
/*! \file
*
* Definition of the global do_intersect_overlay_2() function.
*/
#include <CGAL/Arrangement_on_surface_2.h>
#include <CGAL/Surface_sweep_2.h>
#include <CGAL/Surface_sweep_2/Arr_default_overlay_traits_base.h>
#include <CGAL/Surface_sweep_2/Arr_overlay_traits_2.h>
#include <CGAL/Surface_sweep_2/Arr_do_intersect_overlay_ss_visitor.h>
#include <CGAL/Surface_sweep_2/Arr_overlay_event.h>
#include <CGAL/Surface_sweep_2/Arr_overlay_subcurve.h>
#include <CGAL/assertions.h>
namespace CGAL {
/*! Compute the overlay of two input arrangements.
* \tparam GeometryTraitsA_2 the geometry traits of the first arrangement.
* \tparam GeometryTraitsB_2 the geometry traits of the second arrangement.
* \tparam GeometryTraitsRes_2 the geometry traits of the resulting arrangement.
* \tparam TopologyTraitsA the topology traits of the first arrangement.
* \tparam TopologyTraitsB the topology traits of the second arrangement.
* \tparam TopologyTraitsRes the topology traits of the resulting arrangement.
* \tparam OverlayTraits An overlay-traits class. As arr1, arr2 and res can be
* templated with different geometry-traits class and
* different DCELs (encapsulated in the various topology-traits
* classes). The geometry-traits of the result arrangement is
* used to construct the result arrangement. This means that all
* the types (e.g., Point_2, Curve_2 and X_monotone_2) of both
* arr1 and arr2 have to be convertible to the types
* in the result geometry-traits.
* The overlay-traits class defines the various
* overlay operations of pairs of DCEL features from
* TopologyTraitsA and TopologyTraitsB to the resulting ResDcel.
*/
template <typename GeometryTraitsA_2,
typename GeometryTraitsB_2,
typename GeometryTraitsRes_2,
typename TopologyTraitsA,
typename TopologyTraitsB,
typename TopologyTraitsRes,
typename OverlayTraits>
bool do_intersect_overlay(const Arrangement_on_surface_2<GeometryTraitsA_2, TopologyTraitsA>& arr1,
const Arrangement_on_surface_2<GeometryTraitsB_2, TopologyTraitsB>& arr2,
Arrangement_on_surface_2<GeometryTraitsRes_2, TopologyTraitsRes>& arr,
OverlayTraits& ovl_tr,
bool ignore_isolated_vertices = true) {
using Agt2 = GeometryTraitsA_2;
using Bgt2 = GeometryTraitsB_2;
using Rgt2 = GeometryTraitsRes_2;
using Att = TopologyTraitsA;
using Btt = TopologyTraitsB;
using Rtt = TopologyTraitsRes;
using Overlay_traits = OverlayTraits;
using Arr_a = Arrangement_on_surface_2<Agt2, Att>;
using Arr_b = Arrangement_on_surface_2<Bgt2, Btt>;
using Arr_res = Arrangement_on_surface_2<Rgt2, Rtt>;
using Allocator = typename Arr_res::Allocator;
// some type assertions (not all, but better than nothing).
using A_point = typename Agt2::Point_2;
using B_point = typename Bgt2::Point_2;
using Res_point = typename Rgt2::Point_2;
static_assert(std::is_convertible<A_point, Res_point>::value);
static_assert(std::is_convertible<B_point, Res_point>::value);
using A_xcv = typename Agt2::X_monotone_curve_2;
using B_xcv = typename Bgt2::X_monotone_curve_2;
using Res_xcv = typename Rgt2::X_monotone_curve_2;
static_assert(std::is_convertible<A_xcv, Res_xcv>::value);
static_assert(std::is_convertible<B_xcv, Res_xcv>::value);
using Gt_adaptor_2 = Arr_traits_basic_adaptor_2<Rgt2>;
using Ovl_gt2 = Arr_overlay_traits_2<Gt_adaptor_2, Arr_a, Arr_b>;
using Ovl_event = Arr_overlay_event<Ovl_gt2, Arr_res, Allocator>;
using Ovl_curve = Arr_overlay_subcurve<Ovl_gt2, Ovl_event, Allocator>;
using Ovl_helper = typename TopologyTraitsRes::template Overlay_helper<Ovl_gt2, Ovl_event, Ovl_curve, Arr_a, Arr_b>;
using Diovl_visitor = Arr_do_intersect_overlay_ss_visitor<Ovl_helper, Overlay_traits>;
using Ovl_x_monotone_curve_2 = typename Ovl_gt2::X_monotone_curve_2;
using Ovl_point_2 = typename Ovl_gt2::Point_2;
using Cell_handle_red = typename Ovl_gt2::Cell_handle_red;
using Optional_cell_red = typename Ovl_gt2::Optional_cell_red;
using Cell_handle_blue = typename Ovl_gt2::Cell_handle_blue;
using Optional_cell_blue = typename Ovl_gt2::Optional_cell_blue;
CGAL_USE_TYPE(Optional_cell_red);
CGAL_USE_TYPE(Optional_cell_blue);
// The result arrangement cannot be on of the input arrangements.
CGAL_precondition(((void*)(&arr) != (void*)(&arr1)) && ((void*)(&arr) != (void*)(&arr2)));
// Prepare a vector of extended x-monotone curves that represent all edges
// in both input arrangements. Each curve is associated with a halfedge
// directed from right to left.
typename Arr_a::Halfedge_const_handle invalid_he1;
typename Arr_b::Halfedge_const_handle invalid_he2;
std::vector<Ovl_x_monotone_curve_2> xcvs(arr1.number_of_edges() + arr2.number_of_edges());
std::size_t i = 0;
for (auto eit1 = arr1.edges_begin(); eit1 != arr1.edges_end(); ++eit1, ++i) {
typename Arr_a::Halfedge_const_handle he1 = eit1;
if (he1->direction() != ARR_RIGHT_TO_LEFT) he1 = he1->twin();
xcvs[i] = Ovl_x_monotone_curve_2(eit1->curve(), he1, invalid_he2);
}
for (auto eit2 = arr2.edges_begin(); eit2 != arr2.edges_end(); ++eit2, ++i) {
typename Arr_b::Halfedge_const_handle he2 = eit2;
if (he2->direction() != ARR_RIGHT_TO_LEFT) he2 = he2->twin();
xcvs[i] = Ovl_x_monotone_curve_2(eit2->curve(), invalid_he1, he2);
}
// Obtain an extended traits-class object and define the sweep-line visitor.
const typename Arr_res::Traits_adaptor_2* traits_adaptor = arr.traits_adaptor();
/* We would like to avoid copy construction of the geometry traits class.
* Copy construction is undesired, because it may results with data
* duplication or even data loss.
*
* If the type Ovl_gt2 is the same as the type
* GeomTraits, use a reference to GeomTraits to avoid constructing a new one.
* Otherwise, instantiate a local variable of the former and provide
* the latter as a single parameter to the constructor.
*
* Use the form 'A a(*b);' and not ''A a = b;' to handle the case where A has
* only an implicit constructor, (which takes *b as a parameter).
*/
std::conditional_t<std::is_same_v<Gt_adaptor_2, Ovl_gt2>, const Ovl_gt2&, Ovl_gt2> ex_traits(*traits_adaptor);
Diovl_visitor visitor(&arr1, &arr2, &arr, &ovl_tr);
Ss2::Surface_sweep_2<Diovl_visitor> surface_sweep(&ex_traits, &visitor);
// In case both arrangement do not contain isolated vertices, go on and overlay them.
if (ignore_isolated_vertices ||
((arr1.number_of_isolated_vertices() == 0) && (arr2.number_of_isolated_vertices() == 0))) {
// Clear the result arrangement and perform the sweep to construct it.
arr.clear();
if (std::is_same<typename Agt2::Bottom_side_category, Arr_contracted_side_tag>::value) {
surface_sweep.sweep(xcvs.begin(), xcvs.end());
xcvs.clear();
return visitor.found_intersection();
}
surface_sweep.indexed_sweep(xcvs, Indexed_sweep_accessor<Arr_a, Arr_b, Ovl_x_monotone_curve_2>(arr1, arr2));
xcvs.clear();
return visitor.found_intersection();
}
// Prepare a vector of extended points that represent all isolated vertices
// in both input arrangements.
std::vector<Ovl_point_2> pts_vec(arr1.number_of_isolated_vertices() + arr2.number_of_isolated_vertices());
i = 0;
for (auto vit1 = arr1.vertices_begin(); vit1 != arr1.vertices_end(); ++vit1) {
if (vit1->is_isolated()) {
typename Arr_a::Vertex_const_handle v1 = vit1;
pts_vec[i++] = Ovl_point_2(vit1->point(), std::make_optional(Cell_handle_red(v1)),
std::optional<Cell_handle_blue>());
}
}
for (auto vit2 = arr2.vertices_begin(); vit2 != arr2.vertices_end(); ++vit2) {
if (vit2->is_isolated()) {
typename Arr_b::Vertex_const_handle v2 = vit2;
pts_vec[i++] = Ovl_point_2(vit2->point(), std::optional<Cell_handle_red>(),
std::make_optional(Cell_handle_blue(v2)));
}
}
// Clear the result arrangement and perform the sweep to construct it.
arr.clear();
if (std::is_same<typename Agt2::Bottom_side_category, Arr_contracted_side_tag>::value) {
surface_sweep.sweep(xcvs.begin(), xcvs.end(), pts_vec.begin(), pts_vec.end());
xcvs.clear();
pts_vec.clear();
return visitor.found_intersection();
}
surface_sweep.indexed_sweep(xcvs, Indexed_sweep_accessor<Arr_a, Arr_b, Ovl_x_monotone_curve_2>(arr1, arr2),
pts_vec.begin(), pts_vec.end());
xcvs.clear();
pts_vec.clear();
return visitor.found_intersection();
}
/*! Compute the (simple) overlay of two input arrangements.
* \param[in] arr1 the first arrangement.
* \param[in] arr2 the second arrangement.
* \param[out] arr the resulting arrangement.
*/
template <typename GeometryTraitsA_2,
typename GeometryTraitsB_2,
typename GeometryTraitsRes_2,
typename TopologyTraitsA,
typename TopologyTraitsB,
typename TopologyTraitsRes>
bool do_intersect_overlay(const Arrangement_on_surface_2<GeometryTraitsA_2, TopologyTraitsA>& arr1,
const Arrangement_on_surface_2<GeometryTraitsB_2, TopologyTraitsB>& arr2,
Arrangement_on_surface_2<GeometryTraitsRes_2, TopologyTraitsRes>& arr) {
using Agt2 = GeometryTraitsA_2;
using Bgt2 = GeometryTraitsB_2;
using Rgt2 = GeometryTraitsRes_2;
using Att = TopologyTraitsA;
using Btt = TopologyTraitsB;
using Rtt = TopologyTraitsRes;
using Arr_a = Arrangement_on_surface_2<Agt2, Att>;
using Arr_b = Arrangement_on_surface_2<Bgt2, Btt>;
using Arr_res = Arrangement_on_surface_2<Rgt2, Rtt>;
_Arr_default_overlay_traits_base<Arr_a, Arr_b, Arr_res> ovl_traits;
return do_intersect_overlay(arr1, arr2, arr, ovl_traits);
}
} // namespace CGAL
#include <CGAL/enable_warnings.h>
#endif

View File

@ -8,8 +8,8 @@
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Efi Fogel <efifogel@gmail.com>
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Efi Fogel <efifogel@gmail.com>
#ifndef CGAL_ARR_OVERLAY_2_H
#define CGAL_ARR_OVERLAY_2_H
@ -40,24 +40,18 @@
namespace CGAL {
template <typename Arr1, typename Arr2, typename Curve>
class Indexed_sweep_accessor
{
const Arr1& arr1;
const Arr2& arr2;
mutable std::vector<void*> backup_inc;
class Indexed_sweep_accessor {
private:
const Arr1& m_arr1;
const Arr2& m_arr2;
mutable std::vector<void*> m_backup_inc;
public:
Indexed_sweep_accessor(const Arr1& arr1, const Arr2& arr2) : m_arr1(arr1), m_arr2(arr2) {}
Indexed_sweep_accessor (const Arr1& arr1, const Arr2& arr2)
: arr1(arr1), arr2(arr2) { }
std::size_t nb_vertices() const { return m_arr1.number_of_vertices() + m_arr2.number_of_vertices(); }
std::size_t nb_vertices() const
{
return arr1.number_of_vertices() + arr2.number_of_vertices();
}
std::size_t min_end_index (const Curve& c) const
{
std::size_t min_end_index(const Curve& c) const {
if (c.red_halfedge_handle() != typename Curve::HH_red())
return reinterpret_cast<std::size_t>(c.red_halfedge_handle()->target()->inc());
// else
@ -65,8 +59,7 @@ public:
return reinterpret_cast<std::size_t>(c.blue_halfedge_handle()->target()->inc());
}
std::size_t max_end_index (const Curve& c) const
{
std::size_t max_end_index(const Curve& c) const {
if (c.red_halfedge_handle() != typename Curve::HH_red())
return reinterpret_cast<std::size_t>(c.red_halfedge_handle()->source()->inc());
// else
@ -74,52 +67,36 @@ public:
return reinterpret_cast<std::size_t>(c.blue_halfedge_handle()->source()->inc());
}
const Curve& curve (const Curve& c) const
{
return c;
}
const Curve& curve(const Curve& c) const { return c; }
// Initializes indices by squatting Vertex::inc();
void before_init() const
{
void before_init() const {
std::size_t idx = 0;
backup_inc.resize (nb_vertices());
for (typename Arr1::Vertex_const_iterator vit = arr1.vertices_begin();
vit != arr1.vertices_end(); ++vit, ++idx)
{
CGAL_assertion (idx < backup_inc.size());
backup_inc[idx] = vit->inc();
vit->set_inc (reinterpret_cast<void*>(idx));
m_backup_inc.resize (nb_vertices());
for (auto vit = m_arr1.vertices_begin(); vit != m_arr1.vertices_end(); ++vit, ++idx) {
CGAL_assertion(idx < m_backup_inc.size());
m_backup_inc[idx] = vit->inc();
vit->set_inc(reinterpret_cast<void*>(idx));
}
for (typename Arr2::Vertex_const_iterator vit = arr2.vertices_begin();
vit != arr2.vertices_end(); ++vit, ++idx)
{
CGAL_assertion (idx < backup_inc.size());
backup_inc[idx] = vit->inc();
vit->set_inc (reinterpret_cast<void*>(idx));
for (auto vit = m_arr2.vertices_begin(); vit != m_arr2.vertices_end(); ++vit, ++idx) {
CGAL_assertion(idx < m_backup_inc.size());
m_backup_inc[idx] = vit->inc();
vit->set_inc(reinterpret_cast<void*>(idx));
}
}
// Restores state of arrangements before index squatting
void after_init() const
{
void after_init() const {
std::size_t idx = 0;
for (typename Arr1::Vertex_const_iterator vit = arr1.vertices_begin();
vit != arr1.vertices_end(); ++vit, ++idx)
{
CGAL_assertion (idx < backup_inc.size());
vit->set_inc (backup_inc[idx]);
for (auto vit = m_arr1.vertices_begin(); vit != m_arr1.vertices_end(); ++vit, ++idx) {
CGAL_assertion(idx < m_backup_inc.size());
vit->set_inc(m_backup_inc[idx]);
}
for (typename Arr2::Vertex_const_iterator vit = arr2.vertices_begin();
vit != arr2.vertices_end(); ++vit, ++idx)
{
CGAL_assertion (idx < backup_inc.size());
vit->set_inc (backup_inc[idx]);
for (auto vit = m_arr2.vertices_begin(); vit != m_arr2.vertices_end(); ++vit, ++idx) {
CGAL_assertion(idx < m_backup_inc.size());
vit->set_inc(m_backup_inc[idx]);
}
}
private:
};
/*! Compute the overlay of two input arrangements.
@ -148,64 +125,55 @@ template <typename GeometryTraitsA_2,
typename TopologyTraitsB,
typename TopologyTraitsRes,
typename OverlayTraits>
void
overlay(const Arrangement_on_surface_2<GeometryTraitsA_2, TopologyTraitsA>& arr1,
const Arrangement_on_surface_2<GeometryTraitsB_2, TopologyTraitsB>& arr2,
Arrangement_on_surface_2<GeometryTraitsRes_2, TopologyTraitsRes>& arr,
OverlayTraits& ovl_tr)
{
typedef GeometryTraitsA_2 Agt2;
typedef GeometryTraitsB_2 Bgt2;
typedef GeometryTraitsRes_2 Rgt2;
typedef TopologyTraitsA Att;
typedef TopologyTraitsB Btt;
typedef TopologyTraitsRes Rtt;
typedef OverlayTraits Overlay_traits;
void overlay(const Arrangement_on_surface_2<GeometryTraitsA_2, TopologyTraitsA>& arr1,
const Arrangement_on_surface_2<GeometryTraitsB_2, TopologyTraitsB>& arr2,
Arrangement_on_surface_2<GeometryTraitsRes_2, TopologyTraitsRes>& arr,
OverlayTraits& ovl_tr) {
using Agt2 = GeometryTraitsA_2;
using Bgt2 = GeometryTraitsB_2;
using Rgt2 = GeometryTraitsRes_2;
using Att = TopologyTraitsA;
using Btt = TopologyTraitsB;
using Rtt = TopologyTraitsRes;
using Overlay_traits = OverlayTraits;
typedef Arrangement_on_surface_2<Agt2, Att> Arr_a;
typedef Arrangement_on_surface_2<Bgt2, Btt> Arr_b;
typedef Arrangement_on_surface_2<Rgt2, Rtt> Arr_res;
typedef typename Arr_res::Allocator Allocator;
using Arr_a = Arrangement_on_surface_2<Agt2, Att>;
using Arr_b = Arrangement_on_surface_2<Bgt2, Btt>;
using Arr_res = Arrangement_on_surface_2<Rgt2, Rtt>;
using Allocator = typename Arr_res::Allocator;
// some type assertions (not all, but better than nothing).
typedef typename Agt2::Point_2 A_point;
typedef typename Bgt2::Point_2 B_point;
typedef typename Rgt2::Point_2 Res_point;
using A_point = typename Agt2::Point_2;
using B_point = typename Bgt2::Point_2;
using Res_point = typename Rgt2::Point_2;
static_assert(std::is_convertible<A_point, Res_point>::value);
static_assert(std::is_convertible<B_point, Res_point>::value);
typedef typename Agt2::X_monotone_curve_2 A_xcv;
typedef typename Bgt2::X_monotone_curve_2 B_xcv;
typedef typename Rgt2::X_monotone_curve_2 Res_xcv;
using A_xcv = typename Agt2::X_monotone_curve_2;
using B_xcv = typename Bgt2::X_monotone_curve_2;
using Res_xcv = typename Rgt2::X_monotone_curve_2;
static_assert(std::is_convertible<A_xcv, Res_xcv>::value);
static_assert(std::is_convertible<B_xcv, Res_xcv>::value);
typedef Arr_traits_basic_adaptor_2<Rgt2> Gt_adaptor_2;
typedef Arr_overlay_traits_2<Gt_adaptor_2, Arr_a, Arr_b>
Ovl_gt2;
typedef Arr_overlay_event<Ovl_gt2, Arr_res, Allocator>
Ovl_event;
typedef Arr_overlay_subcurve<Ovl_gt2, Ovl_event, Allocator>
Ovl_curve;
typedef typename TopologyTraitsRes::template
Overlay_helper<Ovl_gt2, Ovl_event, Ovl_curve, Arr_a, Arr_b>
Ovl_helper;
typedef Arr_overlay_ss_visitor<Ovl_helper, Overlay_traits>
Ovl_visitor;
using Gt_adaptor_2 = Arr_traits_basic_adaptor_2<Rgt2>;
using Ovl_gt2 = Arr_overlay_traits_2<Gt_adaptor_2, Arr_a, Arr_b>;
using Ovl_event = Arr_overlay_event<Ovl_gt2, Arr_res, Allocator>;
using Ovl_curve = Arr_overlay_subcurve<Ovl_gt2, Ovl_event, Allocator>;
using Ovl_helper = typename TopologyTraitsRes::template Overlay_helper<Ovl_gt2, Ovl_event, Ovl_curve, Arr_a, Arr_b>;
using Ovl_visitor = Arr_overlay_ss_visitor<Ovl_helper, Overlay_traits>;
typedef typename Ovl_gt2::X_monotone_curve_2 Ovl_x_monotone_curve_2;
typedef typename Ovl_gt2::Point_2 Ovl_point_2;
typedef typename Ovl_gt2::Cell_handle_red Cell_handle_red;
typedef typename Ovl_gt2::Optional_cell_red Optional_cell_red;
typedef typename Ovl_gt2::Cell_handle_blue Cell_handle_blue;
typedef typename Ovl_gt2::Optional_cell_blue Optional_cell_blue;
using Ovl_x_monotone_curve_2 = typename Ovl_gt2::X_monotone_curve_2;
using Ovl_point_2 = typename Ovl_gt2::Point_2;
using Cell_handle_red = typename Ovl_gt2::Cell_handle_red;
using Optional_cell_red = typename Ovl_gt2::Optional_cell_red;
using Cell_handle_blue = typename Ovl_gt2::Cell_handle_blue;
using Optional_cell_blue = typename Ovl_gt2::Optional_cell_blue;
CGAL_USE_TYPE(Optional_cell_red);
CGAL_USE_TYPE(Optional_cell_blue);
// The result arrangement cannot be on of the input arrangements.
CGAL_precondition(((void*)(&arr) != (void*)(&arr1)) &&
((void*)(&arr) != (void*)(&arr2)));
CGAL_precondition(((void*)(&arr) != (void*)(&arr1)) && ((void*)(&arr) != (void*)(&arr2)));
// Prepare a vector of extended x-monotone curves that represent all edges
// in both input arrangements. Each curve is associated with a halfedge
@ -216,23 +184,20 @@ overlay(const Arrangement_on_surface_2<GeometryTraitsA_2, TopologyTraitsA>& arr1
xcvs_vec(arr1.number_of_edges() + arr2.number_of_edges());
unsigned int i = 0;
typename Arr_a::Edge_const_iterator eit1;
for (eit1 = arr1.edges_begin(); eit1 != arr1.edges_end(); ++eit1, ++i) {
for (auto eit1 = arr1.edges_begin(); eit1 != arr1.edges_end(); ++eit1, ++i) {
typename Arr_a::Halfedge_const_handle he1 = eit1;
if (he1->direction() != ARR_RIGHT_TO_LEFT) he1 = he1->twin();
xcvs_vec[i] = Ovl_x_monotone_curve_2(eit1->curve(), he1, invalid_he2);
}
typename Arr_b::Edge_const_iterator eit2;
for (eit2 = arr2.edges_begin(); eit2 != arr2.edges_end(); ++eit2, ++i) {
for (auto eit2 = arr2.edges_begin(); eit2 != arr2.edges_end(); ++eit2, ++i) {
typename Arr_b::Halfedge_const_handle he2 = eit2;
if (he2->direction() != ARR_RIGHT_TO_LEFT) he2 = he2->twin();
xcvs_vec[i] = Ovl_x_monotone_curve_2(eit2->curve(), invalid_he1, he2);
}
// Obtain an extended traits-class object and define the sweep-line visitor.
const typename Arr_res::Traits_adaptor_2* traits_adaptor =
arr.traits_adaptor();
const typename Arr_res::Traits_adaptor_2* traits_adaptor = arr.traits_adaptor();
/* We would like to avoid copy construction of the geometry traits class.
* Copy construction is undesired, because it may results with data
@ -246,29 +211,22 @@ overlay(const Arrangement_on_surface_2<GeometryTraitsA_2, TopologyTraitsA>& arr1
* Use the form 'A a(*b);' and not ''A a = b;' to handle the case where A has
* only an implicit constructor, (which takes *b as a parameter).
*/
std::conditional_t<std::is_same_v<Gt_adaptor_2, Ovl_gt2>,
const Ovl_gt2&, Ovl_gt2>
ex_traits(*traits_adaptor);
std::conditional_t<std::is_same_v<Gt_adaptor_2, Ovl_gt2>, const Ovl_gt2&, Ovl_gt2> ex_traits(*traits_adaptor);
Ovl_visitor visitor(&arr1, &arr2, &arr, &ovl_tr);
Ss2::Surface_sweep_2<Ovl_visitor> surface_sweep(&ex_traits, &visitor);
// In case both arrangement do not contain isolated vertices, go on and
// overlay them.
const std::size_t total_iso_verts =
arr1.number_of_isolated_vertices() + arr2.number_of_isolated_vertices();
const std::size_t total_iso_verts = arr1.number_of_isolated_vertices() + arr2.number_of_isolated_vertices();
if (total_iso_verts == 0) {
// Clear the result arrangement and perform the sweep to construct it.
arr.clear();
if (std::is_same<typename Agt2::Bottom_side_category,
Arr_contracted_side_tag>::value)
surface_sweep.sweep (xcvs_vec.begin(), xcvs_vec.end());
if (std::is_same<typename Agt2::Bottom_side_category, Arr_contracted_side_tag>::value)
surface_sweep.sweep(xcvs_vec.begin(), xcvs_vec.end());
else
surface_sweep.indexed_sweep (xcvs_vec,
Indexed_sweep_accessor
<Arr_a, Arr_b, Ovl_x_monotone_curve_2>
(arr1, arr2));
surface_sweep.indexed_sweep(xcvs_vec, Indexed_sweep_accessor<Arr_a, Arr_b, Ovl_x_monotone_curve_2>(arr1, arr2));
xcvs_vec.clear();
return;
}
@ -278,38 +236,29 @@ overlay(const Arrangement_on_surface_2<GeometryTraitsA_2, TopologyTraitsA>& arr1
std::vector<Ovl_point_2> pts_vec(total_iso_verts);
i = 0;
typename Arr_a::Vertex_const_iterator vit1;
for (vit1 = arr1.vertices_begin(); vit1 != arr1.vertices_end(); ++vit1) {
for (auto vit1 = arr1.vertices_begin(); vit1 != arr1.vertices_end(); ++vit1) {
if (vit1->is_isolated()) {
typename Arr_a::Vertex_const_handle v1 = vit1;
pts_vec[i++] =
Ovl_point_2(vit1->point(), std::make_optional(Cell_handle_red(v1)),
std::optional<Cell_handle_blue>());
pts_vec[i++] = Ovl_point_2(vit1->point(), std::make_optional(Cell_handle_red(v1)),
std::optional<Cell_handle_blue>());
}
}
typename Arr_b::Vertex_const_iterator vit2;
for (vit2 = arr2.vertices_begin(); vit2 != arr2.vertices_end(); ++vit2) {
for (auto vit2 = arr2.vertices_begin(); vit2 != arr2.vertices_end(); ++vit2) {
if (vit2->is_isolated()) {
typename Arr_b::Vertex_const_handle v2 = vit2;
pts_vec[i++] =
Ovl_point_2(vit2->point(), std::optional<Cell_handle_red>(),
std::make_optional(Cell_handle_blue(v2)));
pts_vec[i++] = Ovl_point_2(vit2->point(), std::optional<Cell_handle_red>(),
std::make_optional(Cell_handle_blue(v2)));
}
}
// Clear the result arrangement and perform the sweep to construct it.
arr.clear();
if (std::is_same<typename Agt2::Bottom_side_category,
Arr_contracted_side_tag>::value)
surface_sweep.sweep(xcvs_vec.begin(), xcvs_vec.end(),
pts_vec.begin(), pts_vec.end());
if (std::is_same<typename Agt2::Bottom_side_category, Arr_contracted_side_tag>::value)
surface_sweep.sweep(xcvs_vec.begin(), xcvs_vec.end(), pts_vec.begin(), pts_vec.end());
else
surface_sweep.indexed_sweep (xcvs_vec,
Indexed_sweep_accessor
<Arr_a, Arr_b, Ovl_x_monotone_curve_2>
(arr1, arr2),
pts_vec.begin(), pts_vec.end());
surface_sweep.indexed_sweep(xcvs_vec, Indexed_sweep_accessor<Arr_a, Arr_b, Ovl_x_monotone_curve_2>(arr1, arr2),
pts_vec.begin(), pts_vec.end());
xcvs_vec.clear();
pts_vec.clear();
}
@ -325,20 +274,18 @@ template <typename GeometryTraitsA_2,
typename TopologyTraitsA,
typename TopologyTraitsB,
typename TopologyTraitsRes>
void
overlay(const Arrangement_on_surface_2<GeometryTraitsA_2, TopologyTraitsA>& arr1,
const Arrangement_on_surface_2<GeometryTraitsB_2, TopologyTraitsB>& arr2,
Arrangement_on_surface_2<GeometryTraitsRes_2, TopologyTraitsRes>& arr)
{
typedef GeometryTraitsA_2 Agt2;
typedef GeometryTraitsB_2 Bgt2;
typedef GeometryTraitsRes_2 Rgt2;
typedef TopologyTraitsA Att;
typedef TopologyTraitsB Btt;
typedef TopologyTraitsRes Rtt;
typedef Arrangement_on_surface_2<Agt2, Att> Arr_a;
typedef Arrangement_on_surface_2<Bgt2, Btt> Arr_b;
typedef Arrangement_on_surface_2<Rgt2, Rtt> Arr_res;
void overlay(const Arrangement_on_surface_2<GeometryTraitsA_2, TopologyTraitsA>& arr1,
const Arrangement_on_surface_2<GeometryTraitsB_2, TopologyTraitsB>& arr2,
Arrangement_on_surface_2<GeometryTraitsRes_2, TopologyTraitsRes>& arr) {
using Agt2 = GeometryTraitsA_2;
using Bgt2 = GeometryTraitsB_2;
using Rgt2 = GeometryTraitsRes_2;
using Att = TopologyTraitsA;
using Btt = TopologyTraitsB;
using Rtt = TopologyTraitsRes;
using Arr_a = Arrangement_on_surface_2<Agt2, Att>;
using Arr_b = Arrangement_on_surface_2<Bgt2, Btt>;
using Arr_res = Arrangement_on_surface_2<Rgt2, Rtt>;
_Arr_default_overlay_traits_base<Arr_a, Arr_b, Arr_res> ovl_traits;
overlay(arr1, arr2, arr, ovl_traits);

View File

@ -0,0 +1,110 @@
// Copyright (c) 2006,2007,2009,2010,2011,2025 Tel-Aviv University (Israel).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Efi Fogel <efif@post.tau.ac.il>
#ifndef CGAL_DO_INTERSECT_ARR_OVERLAY_SS_VISITOR_H
#define CGAL_DO_INTERSECT_ARR_OVERLAY_SS_VISITOR_H
#include <CGAL/license/Arrangement_on_surface_2.h>
/*! \file
*
* Definition of the Arr_do_intersect_overlay_ss_visitor class-template.
*/
#include <CGAL/Default.h>
#include <CGAL/Surface_sweep_2/Arr_overlay_ss_visitor.h>
namespace CGAL {
/*! \class Arr_do_intersect_overlay_ss_visitor
*
* A sweep-line visitor for overlaying a "red" arrangement and a "blue"
* arrangement as long as the edges do not intersect in their interiors. If
* there are no intersections, the overlay arrangement is constructed. All three
* arrangements are embedded on the same type of surface and use the same
* geometry traits. Otherwise, the process is terminated without any delay (that
* is, once an intersection is detected).
*/
template <typename OverlayHelper, typename OverlayTraits, typename Visitor_ = Default>
class Arr_do_intersect_overlay_ss_visitor :
public Arr_overlay_ss_visitor<
OverlayHelper, OverlayTraits,
typename Default::Get<Visitor_,
Arr_do_intersect_overlay_ss_visitor<OverlayHelper, OverlayTraits, Visitor_> >::type> {
private:
using Overlay_helper = OverlayHelper;
using Overlay_traits = OverlayTraits;
using Self = Arr_do_intersect_overlay_ss_visitor<Overlay_helper, Overlay_traits, Visitor_>;
using Visitor = typename Default::Get<Visitor_, Self>::type;
using Base = Arr_overlay_ss_visitor<Overlay_helper, Overlay_traits, Visitor>;
protected:
bool m_found_x;
public:
using Arrangement_red_2 = typename Base::Arrangement_red_2;
using Arrangement_blue_2 = typename Base::Arrangement_blue_2;
using Arrangement_2 = typename Base::Arrangement_2;
using Event = typename Base::Event;
using Subcurve = typename Base::Subcurve;
using Status_line_iterator = typename Base::Status_line_iterator;
using X_monotone_curve_2 = typename Base::X_monotone_curve_2;
using Point_2 = typename Base::Point_2;
using Multiplicity = typename Base::Multiplicity;
/*! Constructor */
Arr_do_intersect_overlay_ss_visitor(const Arrangement_red_2* red_arr,
const Arrangement_blue_2* blue_arr,
Arrangement_2* res_arr,
Overlay_traits* overlay_traits) :
Base(red_arr, blue_arr, res_arr, overlay_traits),
m_found_x(false)
{}
/*! Destructor */
virtual ~Arr_do_intersect_overlay_ss_visitor() {}
/*! Update an event that corresponds to a curve endpoint. */
void update_event(Event* e, const Point_2& end_point, const X_monotone_curve_2& cv, Arr_curve_end cv_end, bool is_new)
{ return Base::update_event(e, end_point, cv, cv_end, is_new); }
/*! Update an event that corresponds to a curve endpoint */
void update_event(Event* e, const X_monotone_curve_2& cv, Arr_curve_end cv_end, bool is_new )
{ return Base::update_event(e, cv, cv_end, is_new); }
/*! Update an event that corresponds to a curve endpoint */
void update_event(Event* e, const Point_2& p, bool is_new)
{ return Base::update_event(e, p, is_new); }
/*! Update an event that corresponds to an intersection */
void update_event(Event* e, Subcurve* sc) { return Base::update_event(e, sc); }
/*! Update an event that corresponds to an intersection between curves */
void update_event(Event* e, Subcurve* sc1, Subcurve* sc2, bool is_new, Multiplicity multiplicity) {
if ((multiplicity % 2) == 1) m_found_x = true;
Base::update_event(e, sc1, sc2, is_new, multiplicity);
}
bool after_handle_event(Event* e, Status_line_iterator iter, bool flag) {
auto res = Base::after_handle_event(e, iter, flag);
if (m_found_x) this->surface_sweep()->stop_sweep();
return res;
}
/*! Getter */
bool found_intersection() { return m_found_x; }
};
} // namespace CGAL
#endif

View File

@ -8,9 +8,9 @@
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s): Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
#ifndef CGAL_ARR_NO_INTERSECTION_INSERTION_SS_VISITOR_H
#define CGAL_ARR_NO_INTERSECTION_INSERTION_SS_VISITOR_H
@ -42,35 +42,33 @@ class Arr_no_intersection_insertion_ss_visitor :
public Arr_construction_ss_visitor<
Helper_,
typename Default::Get<Visitor_, Arr_no_intersection_insertion_ss_visitor<
Helper_, Visitor_> >::type>
{
Helper_, Visitor_> >::type> {
public:
typedef Helper_ Helper;
using Helper = Helper_;
typedef typename Helper::Geometry_traits_2 Geometry_traits_2;
typedef typename Helper::Event Event;
typedef typename Helper::Subcurve Subcurve;
using Geometry_traits_2 = typename Helper::Geometry_traits_2;
using Event = typename Helper::Event;
using Subcurve = typename Helper::Subcurve;
private:
typedef Geometry_traits_2 Gt2;
typedef Arr_no_intersection_insertion_ss_visitor<Helper, Visitor_>
Self;
typedef typename Default::Get<Visitor_, Self>::type Visitor;
typedef Arr_construction_ss_visitor<Helper, Visitor> Base;
using Gt2 = Geometry_traits_2;
using Self = Arr_no_intersection_insertion_ss_visitor<Helper, Visitor_>;
using Visitor = typename Default::Get<Visitor_, Self>::type;
using Base = Arr_construction_ss_visitor<Helper, Visitor>;
public:
typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Gt2::Point_2 Point_2;
using X_monotone_curve_2 = typename Gt2::X_monotone_curve_2;
using Point_2 = typename Gt2::Point_2;
using Multiplicity = typename Gt2::Multiplicity;
protected:
typedef typename Subcurve::Status_line_iterator Status_line_iterator;
typedef typename Base::Event_subcurve_reverse_iterator
Event_subcurve_reverse_iterator;
using Status_line_iterator = typename Subcurve::Status_line_iterator;
using Event_subcurve_reverse_iterator = typename Base::Event_subcurve_reverse_iterator;
typedef typename Helper::Arrangement_2 Arrangement_2;
typedef typename Arrangement_2::Vertex_handle Vertex_handle;
typedef typename Arrangement_2::Halfedge_handle Halfedge_handle;
typedef typename Arrangement_2::Face_handle Face_handle;
using Arrangement_2 = typename Helper::Arrangement_2;
using Vertex_handle = typename Arrangement_2::Vertex_handle;
using Halfedge_handle = typename Arrangement_2::Halfedge_handle;
using Face_handle = typename Arrangement_2::Face_handle;
public:
/*! Constructor. */
@ -103,13 +101,12 @@ public:
{}
void update_event(Event* /* e */, Subcurve* /* sc1 */, Subcurve* /* sc2 */,
bool /* is_new */)
bool /* is_new */, Multiplicity /* multiplicity */)
{}
void update_event(Event* /* e */, Subcurve* /* sc1 */) {}
void update_event(Event* e, const Point_2& pt, bool /* is_new */)
{
void update_event(Event* e, const Point_2& pt, bool /* is_new */) {
Vertex_handle invalid_v;
if (e->point().vertex_handle() == invalid_v)
e->point().set_vertex_handle(pt.vertex_handle());
@ -241,8 +238,7 @@ void Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::before_sweep()
//
template <typename Hlpr, typename Vis>
void Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
before_handle_event(Event* event)
{
before_handle_event(Event* event) {
// First we notify the helper class on the event.
this->m_helper.before_handle_event(event);
@ -330,8 +326,7 @@ before_handle_event(Event* event)
//
template <typename Hlpr, typename Vis>
bool Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
add_subcurve_(const X_monotone_curve_2& cv, Subcurve* sc)
{
add_subcurve_(const X_monotone_curve_2& cv, Subcurve* sc) {
const Halfedge_handle invalid_he;
if (cv.halfedge_handle() != invalid_he) return false;
// Insert the curve into the arrangement
@ -344,8 +339,7 @@ add_subcurve_(const X_monotone_curve_2& cv, Subcurve* sc)
//
template <typename Hlpr, typename Vis>
void Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
add_subcurve(const X_monotone_curve_2& cv, Subcurve* sc)
{
add_subcurve(const X_monotone_curve_2& cv, Subcurve* sc) {
if (add_subcurve_(cv, sc)) return;
Halfedge_handle next_ccw_he =
@ -359,8 +353,7 @@ add_subcurve(const X_monotone_curve_2& cv, Subcurve* sc)
template <typename Hlpr, typename Vis>
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Halfedge_handle
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
insert_in_face_interior(const X_monotone_curve_2& cv, Subcurve* sc)
{
insert_in_face_interior(const X_monotone_curve_2& cv, Subcurve* sc) {
Event* last_event = this->last_event_on_subcurve(sc);
Vertex_handle last_v = last_event->point().vertex_handle();
Vertex_handle curr_v = this->current_event()->point().vertex_handle();
@ -385,8 +378,7 @@ template <typename Hlpr, typename Vis>
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Halfedge_handle
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
insert_from_left_vertex(const X_monotone_curve_2& cv, Halfedge_handle he,
Subcurve* sc)
{
Subcurve* sc) {
Vertex_handle curr_v = this->current_event()->point().vertex_handle();
if (curr_v != Vertex_handle())
return (this->m_arr->insert_at_vertices(cv.base(), he, curr_v));
@ -400,8 +392,7 @@ template <typename Hlpr, typename Vis>
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Halfedge_handle
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
insert_from_right_vertex(const X_monotone_curve_2& cv, Halfedge_handle he,
Subcurve* sc)
{
Subcurve* sc) {
Event* last_event = this->last_event_on_subcurve(sc);
Vertex_handle last_v = last_event->point().vertex_handle();
if (last_v != Vertex_handle())
@ -426,8 +417,7 @@ insert_at_vertices(const X_monotone_curve_2& cv,
template <typename Hlpr, typename Vis>
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Vertex_handle
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
insert_isolated_vertex(const Point_2& pt, Status_line_iterator iter)
{
insert_isolated_vertex(const Point_2& pt, Status_line_iterator iter) {
// If the isolated vertex is already at the arrangement, return:
if (pt.vertex_handle() != Vertex_handle()) return Vertex_handle();
@ -443,8 +433,7 @@ insert_isolated_vertex(const Point_2& pt, Status_line_iterator iter)
template <typename Hlpr, typename Vis>
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Halfedge_handle
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
_insert_in_face_interior(const X_monotone_curve_2& cv, Subcurve* sc)
{
_insert_in_face_interior(const X_monotone_curve_2& cv, Subcurve* sc) {
// Check if the vertex to be associated with the left end of the curve has
// already been created.
Event* last_event = this->last_event_on_subcurve(sc);
@ -514,8 +503,7 @@ template <typename Hlpr, typename Vis>
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Halfedge_handle
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
_insert_from_left_vertex(const X_monotone_curve_2& cv,
Halfedge_handle prev, Subcurve* sc)
{
Halfedge_handle prev, Subcurve* sc) {
// Check if the vertex to be associated with the right end of the curve has
// already been created.
Event* curr_event = this->current_event();
@ -551,8 +539,7 @@ template <typename Hlpr, typename Vis>
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Halfedge_handle
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
_insert_from_right_vertex(const X_monotone_curve_2& cv, Halfedge_handle prev,
Subcurve* sc)
{
Subcurve* sc) {
// Check if the vertex to be associated with the left end of the curve has
// already been created.
Event* last_event = this->last_event_on_subcurve(sc);
@ -589,8 +576,7 @@ typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Halfedge_handle
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
_insert_at_vertices(const X_monotone_curve_2& cv,
Halfedge_handle prev1, Halfedge_handle prev2,
Subcurve* sc, bool& new_face_created)
{
Subcurve* sc, bool& new_face_created) {
// Perform the insertion.
new_face_created = false;
bool swapped_predecessors = false;
@ -632,8 +618,7 @@ _insert_at_vertices(const X_monotone_curve_2& cv,
template <typename Hlpr, typename Vis>
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Face_handle
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
_ray_shoot_up(Status_line_iterator iter)
{
_ray_shoot_up(Status_line_iterator iter) {
// Go up the status line and try to locate a curve which is associated
// with a valid arrangement halfedge.
const Halfedge_handle invalid_he;

View File

@ -8,9 +8,9 @@
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
#ifndef CGAL_ARR_OVERLAY_SS_VISITOR_H
#define CGAL_ARR_OVERLAY_SS_VISITOR_H
@ -40,92 +40,80 @@ namespace CGAL {
* arrangement, creating a result arrangement. All three arrangements are
* embedded on the same type of surface and use the same geometry traits.
*/
template <typename OverlayHelper, typename OverlayTraits,
typename Visitor_ = Default>
template <typename OverlayHelper, typename OverlayTraits, typename Visitor_ = Default>
class Arr_overlay_ss_visitor :
public Arr_construction_ss_visitor<
typename OverlayHelper::Construction_helper,
typename Default::Get<Visitor_,
Arr_overlay_ss_visitor<OverlayHelper, OverlayTraits,
Visitor_> >::type>
{
Arr_overlay_ss_visitor<OverlayHelper, OverlayTraits, Visitor_> >::type> {
public:
typedef OverlayHelper Overlay_helper;
typedef OverlayTraits Overlay_traits;
using Overlay_helper = OverlayHelper;
using Overlay_traits = OverlayTraits;
typedef typename Overlay_helper::Geometry_traits_2 Geometry_traits_2;
typedef typename Overlay_helper::Event Event;
typedef typename Overlay_helper::Subcurve Subcurve;
using Geometry_traits_2 = typename Overlay_helper::Geometry_traits_2;
using Event = typename Overlay_helper::Event;
using Subcurve = typename Overlay_helper::Subcurve;
typedef typename Overlay_helper::Arrangement_red_2 Arrangement_red_2;
typedef typename Overlay_helper::Arrangement_blue_2 Arrangement_blue_2;
typedef typename Overlay_helper::Construction_helper Construction_helper;
using Arrangement_red_2 = typename Overlay_helper::Arrangement_red_2;
using Arrangement_blue_2 = typename Overlay_helper::Arrangement_blue_2;
using Construction_helper = typename Overlay_helper::Construction_helper;
private:
typedef Geometry_traits_2 Gt2;
typedef Arrangement_red_2 Ar2;
typedef Arrangement_blue_2 Ab2;
using Gt2 = Geometry_traits_2;
using Ar2 = Arrangement_red_2;
using Ab2 = Arrangement_blue_2;
typedef Arr_overlay_ss_visitor<Overlay_helper, Overlay_traits, Visitor_>
Self;
typedef typename Default::Get<Visitor_, Self>::type Visitor;
typedef Arr_construction_ss_visitor<Construction_helper, Visitor>
Base;
using Self = Arr_overlay_ss_visitor<Overlay_helper, Overlay_traits, Visitor_>;
using Visitor = typename Default::Get<Visitor_, Self>::type;
using Base = Arr_construction_ss_visitor<Construction_helper, Visitor>;
public:
typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Gt2::Point_2 Point_2;
using X_monotone_curve_2 = typename Gt2::X_monotone_curve_2;
using Point_2 = typename Gt2::Point_2;
using Multiplicity = typename Gt2::Multiplicity;
// The input arrangements (the "red" and the "blue" one):
typedef typename Ar2::Halfedge_const_handle Halfedge_handle_red;
typedef typename Ar2::Face_const_handle Face_handle_red;
typedef typename Ar2::Vertex_const_handle Vertex_handle_red;
using Halfedge_handle_red = typename Ar2::Halfedge_const_handle;
using Face_handle_red = typename Ar2::Face_const_handle;
using Vertex_handle_red = typename Ar2::Vertex_const_handle;
typedef typename Ab2::Halfedge_const_handle Halfedge_handle_blue;
typedef typename Ab2::Face_const_handle Face_handle_blue;
typedef typename Ab2::Vertex_const_handle Vertex_handle_blue;
using Halfedge_handle_blue = typename Ab2::Halfedge_const_handle;
using Face_handle_blue = typename Ab2::Face_const_handle;
using Vertex_handle_blue = typename Ab2::Vertex_const_handle;
// The resulting arrangement:
typedef typename Overlay_helper::Arrangement_2 Arrangement_2;
typedef typename Arrangement_2::Halfedge_handle Halfedge_handle;
typedef typename Arrangement_2::Face_handle Face_handle;
typedef typename Arrangement_2::Vertex_handle Vertex_handle;
typedef typename Arrangement_2::Ccb_halfedge_circulator
Ccb_halfedge_circulator;
typedef typename Arrangement_2::Outer_ccb_iterator Outer_ccb_iterator;
using Arrangement_2 = typename Overlay_helper::Arrangement_2;
using Halfedge_handle = typename Arrangement_2::Halfedge_handle;
using Face_handle = typename Arrangement_2::Face_handle;
using Vertex_handle = typename Arrangement_2::Vertex_handle;
using Ccb_halfedge_circulator = typename Arrangement_2::Ccb_halfedge_circulator;
using Outer_ccb_iterator = typename Arrangement_2::Outer_ccb_iterator;
typedef typename Base::Event_subcurve_iterator
Event_subcurve_iterator;
typedef typename Base::Event_subcurve_reverse_iterator
Event_subcurve_reverse_iterator;
typedef typename Base::Status_line_iterator Status_line_iterator;
using Event_subcurve_iterator = typename Base::Event_subcurve_iterator;
using Event_subcurve_reverse_iterator = typename Base::Event_subcurve_reverse_iterator;
using Status_line_iterator = typename Base::Status_line_iterator;
protected:
typedef typename Gt2::Cell_handle_red Cell_handle_red;
typedef typename Gt2::Optional_cell_red Optional_cell_red;
typedef typename Gt2::Cell_handle_blue Cell_handle_blue;
typedef typename Gt2::Optional_cell_blue Optional_cell_blue;
using Cell_handle_red = typename Gt2::Cell_handle_red;
using Optional_cell_red = typename Gt2::Optional_cell_red;
using Cell_handle_blue = typename Gt2::Cell_handle_blue;
using Optional_cell_blue = typename Gt2::Optional_cell_blue;
typedef std::pair<Halfedge_handle_red, Halfedge_handle_blue>
Halfedge_info;
typedef Unique_hash_map<Halfedge_handle, Halfedge_info>
Halfedge_map;
using Halfedge_info = std::pair<Halfedge_handle_red, Halfedge_handle_blue>;
using Halfedge_map = Unique_hash_map<Halfedge_handle, Halfedge_info>;
typedef std::pair<Cell_handle_red, Cell_handle_blue> Handle_info;
typedef std::unordered_map<Vertex_handle, Handle_info, Handle_hash_function>
Vertex_map;
using Handle_info = std::pair<Cell_handle_red, Cell_handle_blue>;
using Vertex_map = std::unordered_map<Vertex_handle, Handle_info, Handle_hash_function>;
// Side categoties:
typedef typename Gt2::Left_side_category Left_side_category;
typedef typename Gt2::Bottom_side_category Bottom_side_category;
typedef typename Gt2::Top_side_category Top_side_category;
typedef typename Gt2::Right_side_category Right_side_category;
using Left_side_category = typename Gt2::Left_side_category;
using Bottom_side_category = typename Gt2::Bottom_side_category;
using Top_side_category = typename Gt2::Top_side_category;
using Right_side_category = typename Gt2::Right_side_category;
typedef typename Arr_has_identified_sides<Left_side_category,
Bottom_side_category>::result
Has_identified_sides_category;
using Has_identified_sides_category =
typename Arr_has_identified_sides<Left_side_category, Bottom_side_category>::result;
// Data members:
Overlay_traits* m_overlay_traits; // The overlay traits object.
@ -195,10 +183,9 @@ public:
void update_event(Event* /* e */,
Subcurve* /* c1 */,
Subcurve* /* c2 */,
bool CGAL_assertion_code(is_new))
{
CGAL_assertion(is_new == true);
}
bool CGAL_assertion_code(is_new),
Multiplicity /* multiplicity */)
{ CGAL_assertion(is_new == true); }
/*! Update an event. */
void update_event(Event* e, Subcurve* sc);
@ -407,9 +394,8 @@ protected:
//-----------------------------------------------------------------------------
// A notification issued before the sweep process starts.
//
template <typename OvlHlpr, typename OvlTr, typename Vis>
void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::before_sweep()
{
template <typename OvlHlpr, typename OvlTr, typename Vis>
void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::before_sweep() {
// Initialize the necessary fields in the base construction visitor.
// Note that the construction visitor also informs its helper class that
// the sweep process is about to start.
@ -425,8 +411,7 @@ protected:
//
template <typename OvlHlpr, typename OvlTr, typename Vis>
void
Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::before_handle_event(Event* event)
{
Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::before_handle_event(Event* event) {
// Let the base construction visitor do the work (and also inform its helper
// class on the event).
Base::before_handle_event(event);
@ -441,8 +426,7 @@ Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::before_handle_event(Event* event)
//
template <typename OvlHlpr, typename OvlTr, typename Vis>
bool Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
after_handle_event(Event* event, Status_line_iterator iter, bool flag)
{
after_handle_event(Event* event, Status_line_iterator iter, bool flag) {
// Let the base construction visitor handle the event.
bool res = Base::after_handle_event(event, iter, flag);
@ -497,8 +481,7 @@ update_event(Event* e,
const Point_2& end_point,
const X_monotone_curve_2& /* cv */,
Arr_curve_end /* cv_end */,
bool /* is_new */)
{
bool /* is_new */) {
// Nothing to do in case of an event at infinity.
CGAL_assertion(e->is_closed());
@ -513,8 +496,7 @@ update_event(Event* e,
//
template <typename OvlHlpr, typename OvlTr, typename Vis>
void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::update_event(Event* e,
Subcurve* sc)
{
Subcurve* sc) {
// Update the red and blue halfedges associated with the point as necessary.
Point_2& pt = e->point();
@ -538,8 +520,7 @@ template <typename OvlHlpr, typename OvlTr, typename Vis>
void
Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::update_event(Event* e,
const Point_2& p,
bool /* is_new */)
{
bool /* is_new */) {
// Update the red and blue objects associated with the point as necessary.
Point_2& pt = e->point();
if (pt.is_red_cell_empty()) pt.set_red_cell(p.red_cell());
@ -550,8 +531,7 @@ Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::update_event(Event* e,
// A notification issued when the sweep process has ended.
//
template <typename OvlHlpr, typename OvlTr, typename Vis>
void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::after_sweep()
{
void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::after_sweep() {
Base::after_sweep();
// Notify boundary vertices:
@ -580,8 +560,7 @@ void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::after_sweep()
template <typename OvlHlpr, typename OvlTr, typename Vis>
typename Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::Halfedge_handle
Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
insert_in_face_interior(const X_monotone_curve_2& cv, Subcurve* sc)
{
insert_in_face_interior(const X_monotone_curve_2& cv, Subcurve* sc) {
// Insert the halfedge using the base construction visitor.
Halfedge_handle new_he = Base::insert_in_face_interior(cv, sc);
_map_halfedge_and_twin(new_he,
@ -615,8 +594,7 @@ typename Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::Halfedge_handle
Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
insert_from_left_vertex(const X_monotone_curve_2& cv,
Halfedge_handle prev,
Subcurve* sc)
{
Subcurve* sc) {
_map_boundary_vertices(this->last_event_on_subcurve(sc), prev->target(),
Has_identified_sides_category());
@ -647,8 +625,7 @@ typename Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::Halfedge_handle
Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
insert_from_right_vertex(const X_monotone_curve_2& cv,
Halfedge_handle prev,
Subcurve* sc)
{
Subcurve* sc) {
_map_boundary_vertices(this->current_event(), prev->target(),
Has_identified_sides_category());
@ -680,8 +657,7 @@ insert_at_vertices(const X_monotone_curve_2& cv,
Halfedge_handle prev1,
Halfedge_handle prev2,
Subcurve* sc,
bool& new_face_created)
{
bool& new_face_created) {
// Insert the halfedge using the base construction visitor. Note that the
// resulting halfedge is always incident to the new face (if one created).
Halfedge_handle new_he =
@ -795,8 +771,7 @@ template <typename OvlHlpr, typename OvlTr, typename Vis>
typename Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::Vertex_handle
Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
insert_isolated_vertex(const Point_2& pt,
Status_line_iterator iter)
{
Status_line_iterator iter) {
// Insert the isolated vertex using the base construction visitor.
Vertex_handle new_v = Base::insert_isolated_vertex(pt, iter);
@ -897,14 +872,13 @@ template <typename OvlHlpr, typename OvlTr, typename Vis>
void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
_map_halfedge_and_twin(Halfedge_handle he,
Halfedge_handle_red red_he,
Halfedge_handle_blue blue_he)
{
Halfedge_handle_blue blue_he) {
if (he->direction() == ARR_LEFT_TO_RIGHT) he = he->twin();
// Obtain the twin red and blue halfedges (if they are valid). Note that
// the original halfedges are always directed from right to left.
Halfedge_handle_red red_he_twin;
Halfedge_handle_blue blue_he_twin;
Halfedge_handle_red red_he_twin;
Halfedge_handle_blue blue_he_twin;
if (red_he != Halfedge_handle_red()) red_he_twin = red_he->twin();
if (blue_he != Halfedge_handle_blue()) blue_he_twin = blue_he->twin();
@ -922,8 +896,7 @@ _map_halfedge_and_twin(Halfedge_handle he,
//
template <typename OvlHlpr, typename OvlTr, typename Vis>
void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
_map_boundary_vertices(Event* event, Vertex_handle v, std::bool_constant<true>)
{
_map_boundary_vertices(Event* event, Vertex_handle v, std::bool_constant<true>) {
// Update the red and blue object if the last event on sc is on the boundary.
if ((event->parameter_space_in_x() != ARR_INTERIOR) ||
(event->parameter_space_in_y() != ARR_INTERIOR))
@ -938,8 +911,7 @@ _map_boundary_vertices(Event* event, Vertex_handle v, std::bool_constant<true>)
if (red_handle_p) info.first = *red_handle_p;
if (!std::get_if<Face_handle_red>(&(info.first)) &&
!std::get_if<Face_handle_blue>(&(info.second)))
{
!std::get_if<Face_handle_blue>(&(info.second))) {
// If both, the red and blue, variants do not represent face handles,
// they must represt either vertex or edge handles. In this case it is
// safe to apply the call to the overlay traits and erase the record,
@ -974,8 +946,7 @@ void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
_create_vertex(Event* event,
Vertex_handle new_v,
Subcurve* sc,
std::bool_constant<true>)
{
std::bool_constant<true>) {
const Point_2& pt = event->point();
const Cell_handle_red* red_handle = pt.red_cell_handle();
const Cell_handle_blue* blue_handle = pt.blue_cell_handle();
@ -983,8 +954,7 @@ _create_vertex(Event* event,
// If the vertex is on the boundary, postpone the notification, but
// update the red and objects in case they are empty.
if ((event->parameter_space_in_x() != ARR_INTERIOR) ||
(event->parameter_space_in_y() != ARR_INTERIOR))
{
(event->parameter_space_in_y() != ARR_INTERIOR)) {
if (!red_handle) {
CGAL_assertion(blue_handle != nullptr);
// Obtain the red face by looking for a subcurve above.
@ -1020,8 +990,7 @@ void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
_create_vertex(Event* event,
Vertex_handle new_v,
Subcurve* sc,
std::bool_constant<false>)
{
std::bool_constant<false>) {
const Point_2& pt = event->point();
const Cell_handle_red* red_handle = pt.red_cell_handle();
const Cell_handle_blue* blue_handle = pt.blue_cell_handle();
@ -1063,8 +1032,7 @@ _create_vertex(Event* event,
template <typename OvlHlpr, typename OvlTr, typename Vis>
void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
_create_edge(Subcurve* sc,
Halfedge_handle new_he)
{
Halfedge_handle new_he) {
// Note that the "red" and "blue" halfedges are always directed from right
// to left, so we make sure the overlaid halfedge is also directed from
// right to left.

View File

@ -1563,10 +1563,10 @@ does_satisfy_link_condition(typename boost::graph_traits<Graph>::edge_descriptor
*
* After the collapse of edge `e` the following holds:
* - The edge `e` is no longer in `g`.
* - The faces incident to edge `e` are no longer in `g`.
* - The triangle faces incident to edge `e` are no longer in `g`.
* - `v0` is no longer in `g`.
* - If `h` is not a border halfedge, `p_h` is no longer in `g` and is replaced by `o_n_h`.
* - If the opposite of `h` is not a border halfedge, `p_o_h` is no longer in `g` and is replaced by `o_n_o_h`.
* - If `h` is part of a triangle face, `p_h` is no longer in `g` and is replaced by `o_n_h`.
* - If the opposite of `h` is part of a triangle face, `p_o_h` is no longer in `g` and is replaced by `o_n_o_h`.
* - The halfedges kept in `g` that had `v0` as target and source now have `v1` as target and source, respectively.
* - No other incidence information is changed in `g`.
*
@ -1595,9 +1595,8 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor e,
bool lBottomFaceExists = ! is_border(qp,g);
bool lTopLeftFaceExists = lTopFaceExists && ! is_border(pt,g);
bool lBottomRightFaceExists = lBottomFaceExists && ! is_border(qb,g);
CGAL_precondition( !lTopFaceExists || (lTopFaceExists && ( degree(target(pt, g), g) > 2 ) ) ) ;
CGAL_precondition( !lBottomFaceExists || (lBottomFaceExists && ( degree(target(qb, g), g) > 2 ) ) ) ;
bool lBottomIsTriangle = lBottomFaceExists && is_triangle(qp,g);
bool lTopIsTriangle = lTopFaceExists && is_triangle(pq,g);
vertex_descriptor q = target(pq, g);
vertex_descriptor p = source(pq, g);
@ -1605,7 +1604,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor e,
bool lP_Erased = false;
if ( lTopFaceExists )
if ( lTopIsTriangle)
{
CGAL_precondition( ! is_border(opposite(pt, g),g) ) ; // p-q-t is a face of the mesh
if ( lTopLeftFaceExists )
@ -1632,7 +1631,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor e,
}
}
if ( lBottomFaceExists )
if ( lBottomIsTriangle)
{
CGAL_precondition( ! is_border(opposite(qb, g),g) ) ; // p-q-b is a face of the mesh
if ( lBottomRightFaceExists )
@ -1679,7 +1678,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor e,
* collapses an edge in a graph having non-collapsable edges.
*
* Let `h` be the halfedge of `e`, and let `v0` and `v1` be the source and target vertices of `h`.
* Collapses the edge `e` replacing it with `v1`, as described in the paragraph above
* Collapses the edge `e` replacing it with `v1`, as described in the other overload
* and guarantees that an edge `e2`, for which `get(edge_is_constrained_map, e2)==true`,
* is not removed after the collapse.
*
@ -1689,14 +1688,14 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor e,
*
* \returns vertex `v1`.
* \pre This function requires `g` to be an oriented 2-manifold with or without boundaries.
* Furthermore, the edge `v0v1` must satisfy the link condition, which guarantees that the surface mesh is also 2-manifold after the edge collapse.
* \pre `get(edge_is_constrained_map, v0v1) == false`.
* Furthermore, the edge `e` must satisfy the link condition, which guarantees that the surface mesh is also 2-manifold after the edge collapse.
* \pre `get(edge_is_constrained_map, e) == false`.
* \pre `v0` and `v1` are not both incident to a constrained edge.
*/
template<typename Graph, typename EdgeIsConstrainedMap>
typename boost::graph_traits<Graph>::vertex_descriptor
collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor e,
Graph& g,
EdgeIsConstrainedMap Edge_is_constrained_map)
{
@ -1704,11 +1703,11 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
typedef typename Traits::vertex_descriptor vertex_descriptor;
typedef typename Traits::halfedge_descriptor halfedge_descriptor;
CGAL_precondition(is_valid_edge_descriptor(v0v1, g));
CGAL_precondition(does_satisfy_link_condition(v0v1,g));
CGAL_precondition(!get(Edge_is_constrained_map, v0v1));
CGAL_precondition(is_valid_edge_descriptor(e, g));
CGAL_precondition(does_satisfy_link_condition(e,g));
CGAL_precondition(!get(Edge_is_constrained_map, e));
halfedge_descriptor pq = halfedge(v0v1,g);
halfedge_descriptor pq = halfedge(e,g);
halfedge_descriptor qp = opposite(pq,g);
halfedge_descriptor pt = opposite(prev(pq,g),g);
@ -1718,6 +1717,8 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
bool lTopFaceExists = ! is_border(pq,g) ;
bool lBottomFaceExists = ! is_border(qp,g) ;
bool lTopIsTriangle = lTopFaceExists && is_triangle(pq,g);
bool lBottomIsTriangle = lBottomFaceExists && is_triangle(qp,g);
vertex_descriptor q = target(pq,g);
vertex_descriptor p = source(pq,g);
@ -1728,7 +1729,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
// If the top facet exists, we need to choose one out of the two edges which one disappears:
// p-t if it is not constrained and t-q otherwise
if ( lTopFaceExists )
if ( lTopIsTriangle )
{
if ( !get(Edge_is_constrained_map,edge(pt,g)) )
{
@ -1742,7 +1743,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
// If the bottom facet exists, we need to choose one out of the two edges which one disappears:
// q-b if it is not constrained and b-p otherwise
if ( lBottomFaceExists )
if ( lBottomIsTriangle )
{
if ( !get(Edge_is_constrained_map,edge(qb,g)) )
{
@ -1753,7 +1754,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
}
}
if (lTopFaceExists && lBottomFaceExists)
if (lTopIsTriangle && lBottomIsTriangle)
{
if ( face(edges_to_erase[0],g) == face(edges_to_erase[1],g)
&& (! is_border(edges_to_erase[0],g)) )
@ -1800,7 +1801,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
}
else
{
if (lTopFaceExists)
if (lTopIsTriangle)
{
if (!(is_border(edges_to_erase[0],g))){
join_face(edges_to_erase[0],g);
@ -1815,21 +1816,32 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
remove_face(opposite(edges_to_erase[0],g),g);
return q;
}
if (! (is_border(edges_to_erase[0],g))){
// q will be removed, swap it with p
internal::swap_vertices(p, q, g);
join_face(edges_to_erase[0],g);
join_vertex(qp,g);
return q;
}
if(!is_border(opposite(next(qp,g),g),g))
else
{
// q will be removed, swap it with p
internal::swap_vertices(p, q, g);
if (lBottomIsTriangle)
{
if (! (is_border(edges_to_erase[0],g))){
// q will be removed, swap it with p
internal::swap_vertices(p, q, g);
join_face(edges_to_erase[0],g);
CGAL_assertion(source(qp,g)==p);
join_vertex(qp,g);
return q;
}
if(!is_border(opposite(next(qp,g),g),g))
{
// q will be removed, swap it with p
internal::swap_vertices(p, q, g);
}
remove_face(opposite(edges_to_erase[0],g),g);
return q;
}
else
{
join_vertex(pq,g);
return q;
}
}
remove_face(opposite(edges_to_erase[0],g),g);
return q;
}
}

View File

@ -18,6 +18,7 @@
#include <CGAL/boost/graph/IO/Generic_facegraph_builder.h>
#include <CGAL/Named_function_parameters.h>
#include <CGAL/boost/graph/named_params_helper.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <fstream>
#include <string>
@ -44,7 +45,7 @@ class PLY_builder
typedef typename Base::Face_container Face_container;
public:
PLY_builder(std::istream& is) : Base(is) { }
PLY_builder(std::istream& is, std::string& comments) : Base(is), comments(comments) { }
template <typename NamedParameters>
bool read(std::istream& is,
@ -52,19 +53,22 @@ public:
Face_container& faces,
const NamedParameters& np)
{
return read_PLY(is, points, faces, np);
return read_PLY(is, points, faces, comments, np);
}
std::string& comments;
};
template <typename Graph, typename CGAL_NP_TEMPLATE_PARAMETERS>
bool read_PLY_BGL(std::istream& is,
Graph& g,
std::string& comments,
const CGAL_NP_CLASS& np = parameters::default_values())
{
typedef typename CGAL::GetVertexPointMap<Graph, CGAL_NP_CLASS>::type VPM;
typedef typename boost::property_traits<VPM>::value_type Point;
internal::PLY_builder<Graph, Point> builder(is);
internal::PLY_builder<Graph, Point> builder(is, comments);
return builder(g, np);
}
@ -84,6 +88,7 @@ bool read_PLY_BGL(std::istream& is,
\param is the input stream
\param g the graph to be built from the input data
\param comments a string included line by line in the header of the PLY stream (each line will be precedeed by "comment ")
\param np optional \ref bgl_namedparameters "Named Parameters" described below
\cgalNamedParamsBegin
@ -132,15 +137,31 @@ template <typename Graph,
typename CGAL_NP_TEMPLATE_PARAMETERS>
bool read_PLY(std::istream& is,
Graph& g,
std::string& comments,
const CGAL_NP_CLASS& np = parameters::default_values()
#ifndef DOXYGEN_RUNNING
, std::enable_if_t<!internal::is_Point_set_or_Range_or_Iterator<Graph>::value>* = nullptr
#endif
)
{
return internal::read_PLY_BGL(is, g, np);
return internal::read_PLY_BGL(is, g, comments, np);
}
template <typename Graph,
typename CGAL_NP_TEMPLATE_PARAMETERS>
bool read_PLY(std::istream& is,
Graph& g,
const CGAL_NP_CLASS& np = parameters::default_values()
#ifndef DOXYGEN_RUNNING
, std::enable_if_t<!internal::is_Point_set_or_Range_or_Iterator<Graph>::value>* = nullptr
#endif
)
{
std::string unused_comments;
return internal::read_PLY_BGL(is, g, unused_comments, np);
}
/*!
\ingroup PkgBGLIoFuncsPLY
@ -153,6 +174,7 @@ bool read_PLY(std::istream& is,
\param fname the name of the input file
\param g the graph to be built from the input data
\param comments a string included line by line in the header of the PLY stream (each line will be precedeed by "comment" )
\param np optional \ref bgl_namedparameters "Named Parameters" described below
\cgalNamedParamsBegin
@ -207,6 +229,7 @@ template <typename Graph,
typename CGAL_NP_TEMPLATE_PARAMETERS>
bool read_PLY(const std::string& fname,
Graph& g,
std::string& comments,
const CGAL_NP_CLASS& np = parameters::default_values()
#ifndef DOXYGEN_RUNNING
, std::enable_if_t<!internal::is_Point_set_or_Range_or_Iterator<Graph>::value>* = nullptr
@ -218,16 +241,29 @@ bool read_PLY(const std::string& fname,
{
std::ifstream is(fname, std::ios::binary);
CGAL::IO::set_mode(is, CGAL::IO::BINARY);
return internal::read_PLY_BGL(is, g, np);
return read_PLY(is, g, comments, np);
}
else
{
std::ifstream is(fname);
CGAL::IO::set_mode(is, CGAL::IO::ASCII);
return internal::read_PLY_BGL(is, g, np);
return read_PLY(is, g, comments, np);
}
}
template <typename Graph,
typename CGAL_NP_TEMPLATE_PARAMETERS>
bool read_PLY(const std::string& fname,
Graph& g,
const CGAL_NP_CLASS& np = parameters::default_values()
#ifndef DOXYGEN_RUNNING
, std::enable_if_t<!internal::is_Point_set_or_Range_or_Iterator<Graph>::value>* = nullptr
#endif
)
{
std::string unused_comment;
return read_PLY(fname, g, unused_comment, np);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
// Write
@ -259,6 +295,15 @@ bool read_PLY(const std::string& fname,
must be available in `Graph`.}
\cgalParamNEnd
\cgalParamNBegin{vertex_normal_map}
\cgalParamDescription{a property map associating normals to the vertices of `g`}
\cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits<Graph>::%vertex_descriptor`
as key type and `%Vector_3` as value type}
\cgalParamDefault{`boost::get(CGAL::vertex_point, g)`}
\cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t`
must be available in `Graph`.}
\cgalParamNEnd
\cgalParamNBegin{vertex_index_map}
\cgalParamDescription{a property map associating to each vertex of `graph` a unique index}
\cgalParamType{a class model of `WritablePropertyMap` with `boost::graph_traits<Graph>::%vertex_descriptor`
@ -326,6 +371,8 @@ bool write_PLY(std::ostream& os,
bool has_vcolor = !is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_color_map_t>::value;
bool has_fcolor = !is_default_parameter<CGAL_NP_CLASS, internal_np::face_color_map_t>::value;
constexpr bool has_vnormal = !is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_normal_map_t>::value;
VIMap vim = CGAL::get_initialized_vertex_index_map(g, np);
Vpm vpm = choose_parameter(get_parameter(np, internal_np::vertex_point),
get_const_property_map(boost::vertex_point, g));
@ -351,8 +398,20 @@ bool write_PLY(std::ostream& os,
}
}
os << "element vertex " << vertices(g).size() << std::endl;
internal::output_property_header(os, make_ply_point_writer (CGAL::Identity_property_map<Point_3>()));
if constexpr (std::is_same<typename Kernel_traits<Point_3>::Kernel::FT, float>::value)
{
internal::output_property_header(os, make_ply_point_writer (CGAL::Identity_property_map<Point_3>()));
}
else
{
typedef typename Kernel_traits<Point_3>::Kernel K;
typedef decltype(std::declval<CGAL::Cartesian_converter<K, Epick> >().operator()(std::declval<Point_3>())) Target_point;
auto fvpm = CGAL::make_cartesian_converter_property_map<Target_point>(vpm);
internal::output_property_header(os, make_ply_point_writer (fvpm));
}
//if vcm is not default add v:color property
if(has_vcolor)
{
@ -362,10 +421,30 @@ bool write_PLY(std::ostream& os,
<< "property uchar alpha" << std::endl;
}
if constexpr (has_vnormal)
{
auto vnm = get_parameter(np, internal_np::vertex_normal_map);
typedef decltype(vnm) Normal_map;
typedef typename Normal_map::value_type Vector_3;
typedef typename Kernel_traits<Vector_3>::Kernel K;
typedef typename K::FT FT;
if constexpr (std::is_same<FT, float>::value)
{
internal::output_property_header(os, make_ply_normal_writer (CGAL::Identity_property_map<Vector_3>()));
}
else
{
typedef decltype(std::declval<CGAL::Cartesian_converter<K, Epick> >().operator()(std::declval<Vector_3>())) Target_vector;
auto fvnm = CGAL::make_cartesian_converter_property_map<Target_vector>(vnm);
internal::output_property_header(os, make_ply_normal_writer (fvnm));
}
}
os << "element face " << faces(g).size() << std::endl;
internal::output_property_header(
os, std::make_pair(CGAL::Identity_property_map<std::vector<std::size_t> >(),
PLY_property<std::vector<int> >("vertex_indices")));
//if fcm is not default add f:color property
if(has_fcolor)
{
@ -378,8 +457,42 @@ bool write_PLY(std::ostream& os,
for(vertex_descriptor vd : vertices(g))
{
const Point_3& p = get(vpm, vd);
internal::output_properties(os, &p, make_ply_point_writer (CGAL::Identity_property_map<Point_3>()));
if constexpr (std::is_same<typename Kernel_traits<Point_3>::Kernel::FT, float>::value)
{
decltype(auto) p = get(vpm, vd);
internal::output_properties(os, &p, make_ply_point_writer (CGAL::Identity_property_map<Point_3>()));
}
else
{
typedef typename Kernel_traits<Point_3>::Kernel K;
typedef CGAL::cpp20::remove_cvref_t<decltype(std::declval<CGAL::Cartesian_converter<K, Epick> >().operator()(std::declval<Point_3>()))> Target_point;
CGAL::Cartesian_converter_property_map<Target_point, Vpm> fvpm = CGAL::make_cartesian_converter_property_map<Target_point>(vpm);
decltype(auto) fp = get(fvpm, vd);
internal::output_properties(os, &fp, make_ply_point_writer (CGAL::Identity_property_map<Target_point>()));
}
std::cout << "using generic writer" << std::endl;
if constexpr (!parameters::is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_normal_map_t>::value)
{
auto vnm = get_parameter(np, internal_np::vertex_normal_map);
typedef decltype(vnm) Normal_map;
typedef typename Normal_map::value_type Vector_3;
if constexpr (std::is_same<typename Kernel_traits<Vector_3>::Kernel::FT, float>::value)
{
decltype(auto) vec = get(vnm,vd);
internal::output_properties(os, &vec, make_ply_normal_writer (CGAL::Identity_property_map<Vector_3>()));
}
else
{
typedef typename Kernel_traits<Vector_3>::Kernel K;
typedef CGAL::cpp20::remove_cvref_t<decltype(std::declval<CGAL::Cartesian_converter<K, Epick> >().operator()(std::declval<Vector_3>()))> Target_vector;
auto fvnm = CGAL::make_cartesian_converter_property_map<Target_vector>(vnm);
decltype(auto) fvec = get(fvnm, vd);
internal::output_properties(os, &fvec, make_ply_normal_writer (CGAL::Identity_property_map<Target_vector>()));
}
}
if(has_vcolor)
{
const CGAL::IO::Color& c = get(vcm, vd);
@ -455,6 +568,15 @@ bool write_PLY(std::ostream& os, const Graph& g, const CGAL_NP_CLASS& np = param
must be available in `Graph`.}
\cgalParamNEnd
\cgalParamNBegin{vertex_normal_map}
\cgalParamDescription{a property map associating normals to the vertices of `g`}
\cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits<Graph>::%vertex_descriptor`
as key type and `%Vector_3` as value type}
\cgalParamDefault{`boost::get(CGAL::vertex_point, g)`}
\cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t`
must be available in `Graph`.}
\cgalParamNEnd
\cgalParamNBegin{vertex_index_map}
\cgalParamDescription{a property map associating to each vertex of `graph` a unique index between `0` and `num_vertices(graph) - 1`}
\cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits<Graph>::%vertex_descriptor`

View File

@ -1,13 +1,19 @@
Algebraic_foundations
Arithmetic_kernel
BGL
Cartesian_kernel
Circulator
Distance_2
Distance_3
Filtered_kernel
Homogeneous_kernel
Hash_map
Installation
Intersections_2
Intersections_3
Interval_support
Kernel_23
Kernel_d
Modular_arithmetic
Number_types
Profiling_tools
@ -15,3 +21,4 @@ Property_map
Random_numbers
STL_Extension
Stream_support
CGAL_Core

View File

@ -0,0 +1,42 @@
OFF
25 13 0
0.39160239696502686 1.3864846229553223 4.8046874923102223e-08
0.053782559931278229 1.3864846229553223 4.8046874923102223e-08
-0.94644606113433838 1.6651756763458252 4.8046874923102223e-08
-1.3082554340362549 1.7385153770446777 4.8046874923102223e-08
-1.3033660650253296 1.1860226392745972 4.8046874923102223e-08
1.61628258228302 -0.17601536214351654 4.8046874923102223e-08
0.55834579467773438 -0.19216139614582062 4.8046874923102223e-08
0.053782559931278229 -0.17601536214351654 4.8046874923102223e-08
-0.24240998923778534 -0.22679123282432556 4.8046874923102223e-08
-0.58168435096740723 -0.25845989584922791 4.8046874923102223e-08
-1.2915089130401611 -0.17601536214351654 4.8046874923102223e-08
-1.50871741771698 -0.17601536214351654 4.8046874923102223e-08
1.61628258228302 -1.7385153770446777 4.8046874923102223e-08
1.1978726387023926 -1.7385153770446777 4.8046874923102223e-08
0.71942150592803955 -1.7385153770446777 4.8046874923102223e-08
0.053782559931278229 -1.7385153770446777 4.8046874923102223e-08
-0.73973840475082397 -1.7385153770446777 4.8046874923102223e-08
1.61628258228302 0.36264327168464661 4.8046874923102223e-08
-0.26156377792358398 0.45463424921035767 4.8046874923102223e-08
-0.028661971911787987 -0.78840988874435425 4.8046874923102223e-08
0.053782559931278229 -1.2213115692138672 4.8046874923102223e-08
-1.5918357372283936 1.5331641435623169 4.8046874923102223e-08
-1.6162823438644409 0.87338578701019287 4.8046874923102223e-08
-1.50871741771698 -0.0072435899637639523 4.8046874923102223e-08
-1.50871741771698 -1.3000825643539429 4.8046874923102223e-08
7 18 2 3 4 22 9 8
3 2 18 1
7 18 7 6 5 17 0 1
7 12 5 6 7 8 19 13
6 11 24 16 15 20 10
3 9 19 8
4 10 20 19 9
3 7 18 8
3 14 20 15
4 13 19 20 14
3 3 21 4
4 9 22 23 10
3 10 23 11

View File

@ -2,7 +2,6 @@
#include <CGAL/boost/graph/Euler_operations.h>
#include <CGAL/boost/graph/IO/OFF.h>
#include <boost/range/distance.hpp>
#include <string>
@ -213,12 +212,30 @@ collapse_edge_test()
assert(found == 2);
CGAL::clear(test_mesh);
}
// Case 6 non pure triangle mesh
{
Mesh ref;
if(!CGAL::IO::read_OFF("data/polygon_mesh_to_collapse.off", ref))
{
std::cout << "Error reading file: data/polygon_mesh_to_collapse.off" << std::endl;
exit(1);
}
std::size_t nbe=halfedges(ref).size();
for (std::size_t i=0; i< nbe; ++i)
{
Mesh m = ref;
auto h = *std::next(halfedges(m).begin(), i);
if (CGAL::Euler::does_satisfy_link_condition(edge(h,m),m))
CGAL::Euler::collapse_edge(edge(h,m), m);
assert(CGAL::is_valid_polygon_mesh(m));
}
}
}
int main()
{
collapse_edge_test<Polyhedron>();
collapse_edge_test<SM>();

View File

@ -1,9 +1,7 @@
# Created by the script cgal_create_cmake_script.
# This is the CMake script for compiling a CGAL application.
project(Barycentric_coordinates_2_Benchmarks)
cmake_minimum_required(VERSION 3.12...3.31)
project(Barycentric_coordinates_2_Benchmarks)
find_package(CGAL REQUIRED COMPONENTS Core)
@ -14,8 +12,9 @@ create_single_source_cgal_program("benchmark_polygon_16_vertices.cpp")
create_single_source_cgal_program("benchmark_polygon_100_vertices.cpp")
create_single_source_cgal_program("benchmark_mv_34_vertices.cpp")
find_package(Eigen3 3.1.0 QUIET) # (3.1.0 or greater)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
if(TARGET CGAL::Eigen3_support)
create_single_source_cgal_program("benchmark_hm_4_vertices.cpp")
target_link_libraries(benchmark_hm_4_vertices PRIVATE CGAL::Eigen3_support)

View File

@ -17,8 +17,9 @@ create_single_source_cgal_program("terrain_height_modeling.cpp")
# this code is deprecated:
create_single_source_cgal_program("deprecated_coordinates.cpp")
find_package(Eigen3 3.1.0 QUIET) # (3.1.0 or greater)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
if(TARGET CGAL::Eigen3_support)
create_single_source_cgal_program("affine_coordinates.cpp")
target_link_libraries(affine_coordinates PRIVATE CGAL::Eigen3_support)

View File

@ -42,8 +42,9 @@ create_single_source_cgal_program("test_wp_deprecated_api.cpp")
create_single_source_cgal_program("test_mv_deprecated_api.cpp")
create_single_source_cgal_program("test_dh_deprecated_api.cpp")
find_package(Eigen3 3.1.0 QUIET) # (3.1.0 or greater)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
if(TARGET CGAL::Eigen3_support)
create_single_source_cgal_program("test_hm_unit_square.cpp")
target_link_libraries(test_hm_unit_square PRIVATE CGAL::Eigen3_support)

View File

@ -11,7 +11,7 @@ project(Basic_viewer_Examples)
#CGAL_Qt6 is needed for the drawing.
find_package(CGAL REQUIRED OPTIONAL_COMPONENTS Qt6)
find_package(Eigen3 3.1.0)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
create_single_source_cgal_program("draw_lcc.cpp")

View File

@ -700,15 +700,29 @@ swap its source and target points).
The traits classes `Arr_segment_traits_2`,
`Arr_non_caching_segment_traits_2`, `Arr_circle_segment_traits_2`,
`Arr_conic_traits_2` and `Arr_rational_function_traits_2`, which are
bundled in the `Arrangement_2` package and distributed with \cgal,
are all models of the refined concept
`AosDirectionalXMonotoneTraits_2`.\cgalFootnote{The \cgalFootnoteCode{Arr_polyline_traits_2} class is <I>not</I> a model of the, \cgalFootnoteCode{AosDirectionalXMonotoneTraits_2} concept, as the \f$ x\f$-monotone curve it defines is always directed from left to right. Thus, an opposite curve cannot be constructed. However, it is not very useful to construct a polygon whose edges are polylines, as an ordinary polygon with linear edges can represent the same entity.}
bundled in the `Arrangement_2` package and distributed with \cgal, are
all models of the refined concept
`AosDirectionalXMonotoneTraits_2`.\cgalFootnote{The
\cgalFootnoteCode{Arr_polyline_traits_2} class is <I>not</I> a model
of the, \cgalFootnoteCode{AosDirectionalXMonotoneTraits_2} concept, as
the \f$ x\f$-monotone curve it defines is always directed from left to
right. Thus, an opposite curve cannot be constructed. However, it is
not very useful to construct a polygon whose edges are polylines, as
an ordinary polygon with linear edges can represent the same entity.}
Just as with the case of computations using models of the
`AosXMonotoneTraits_2` concept, operations are robust only
when exact arithmetic is used. When inexact arithmetic is used,
(nearly) degenerate configurations may result in abnormal termination
of the program or even incorrect results.
Operations on polygons (or general polygons) are guaranteed to be
robust only if the operations of the geometry traits used to carry out
the high-level operations are robust. Most operations on polygons use
geometry traits constructors, as they generate new polygons; such
constructors are guaranteed to be robust only if the kernel in use
supports exact constructions, such as the EPEC (Exact Predicate Exact
Construction) kernel. The `do_intersect()` overloaded predicates that
operate on (linear) polygons are exceptions, as they only use geometry
traits predicates; such predicates are guaranteed to be robust only if
the kernel in use supports exact predicates, such as the EPIC (Exact
Predicate Inexact Construction) kernel. When inexact arithmetic is
used, (nearly) degenerate configurations may result in abnormal
termination of the program or even incorrect results.
\subsection bso_sseccirc_seg Operating on Polygons with Circular Arcs

View File

@ -19,6 +19,10 @@ namespace CGAL {
* <tr><td align="right"><b>2.</b></td><td>`void complement(const Type1& pgn, Type2& res, const GpsTraits& traits);`</td></tr>
* </table>
*
* \tparam Kernel a model of the concept `PolygonTraits_2`.
* \tparam Container a model of the concept `Container`; defaults to `std::vector<Kernel::Point_2`>.
* \tparam ArrTraits a model of the concept `AosDirectionalXMonotoneTraits_2`.
* \tparam GpsTraits a model of the concept `GeneralPolygonSetTraits_2`, which must be convertible to `ArrTraits`.
* \tparam UsePolylines determines whether the boundary of the input polygon is
* treated as a cyclic sequence of single (\f$x\f$-monotone) segments or as a
* cyclic sequence of (\f$x\f$-monotone) polylines. If substituted with
@ -28,7 +32,7 @@ namespace CGAL {
* to a standard polygon. If substituted with `CGAL::Tag_false`, the input
* polygon is used as is. Refer to \ref bso_ssectraits_sel for more information.
*
* - The types `Type` and `Type2` of the parameters must be convertible to the
* - The types `Type1` and `Type2` of the parameters must be convertible to the
* types specified in a row in the table below, respectively.
* - The types that apply to signature (<b>1.1.</b>) above are restricted to those
* listed in rows <b>1</b> and <b>2</b> in the table below.
@ -54,6 +58,8 @@ namespace CGAL {
* \sa \link boolean_join `CGAL::join()` \endlink
* \sa \link boolean_difference `CGAL::difference()` \endlink
* \sa \link boolean_symmetric_difference `CGAL::symmetric_difference()` \endlink
* \sa Polygon_2<Kernel, Container>
* \sa Polygon_with_holes_2<Kernel, Container>
*/
/// @{
@ -224,6 +230,10 @@ namespace CGAL {
* <tr><td align="right"><b>2.</b></td><td>`OutputIterator difference(const Type1& pgn1, const Type2& pgn2, OutputIterator oi, const GpsTraits& traits);`</td></tr>
* </table>
*
* \tparam Kernel a model of the concept `PolygonTraits_2`
* \tparam Container a model of the concept `Container`; defaults to `std::vector<Kernel::Point_2`>.
* \tparam ArrTraits a model of the concept `AosDirectionalXMonotoneTraits_2`
* \tparam GpsTraits a model of the concept `GeneralPolygonSetTraits_2`, which must be convertible to `ArrTraits`.
* \tparam UsePolylines determines whether the boundaries of the input polygons
* are treated as cyclic sequences of single (\f$x\f$-monotone) segments or as
* cyclic sequences of (\f$x\f$-monotone) polylines. If substituted with
@ -264,6 +274,8 @@ namespace CGAL {
* \sa \link boolean_intersection `CGAL::intersection()` \endlink
* \sa \link boolean_join `CGAL::join()` \endlink
* \sa \link boolean_symmetric_difference `CGAL::symmetric_difference()` \endlink
* \sa Polygon_2<Kernel, Container>
* \sa Polygon_with_holes_2<Kernel, Container>
*/
/// @{
@ -660,48 +672,22 @@ namespace CGAL {
* A function template in this group that accepts two input polygons has one of
* the following signatures:
* <table cellpadding=3 border="0">
* <tr><td align="right"><b>1.1.</b></td><td>`bool do_intersect(const Type1& pgn1, const Type2& pgn2, UsePolylines = Tag_true());`</td></tr>
* <tr><td align="right"><b>1.2.</b></td><td>`bool do_intersect(const Type1& pgn1, const Type2& pgn2);`</td></tr>
* <tr><td align="right"><b> 2.</b></td><td>`bool do_intersect(const Type1& pgn1, const Type2& pgn2, const GpsTraits& traits);`</td></tr>
* <tr><td align="right"><b>1.</b></td><td>`bool do_intersect(const Type1& pgn1, const Type2& pgn2);`</td></tr>
* <tr><td align="right"><b>2.</b></td><td>`bool do_intersect(const Type1& pgn1, const Type2& pgn2, const GpsTraits& traits);`</td></tr>
* </table>
*
* There are also function templates that accept one or two ranges of input polygons:
* <table cellpadding=3 border="0">
* <tr><td align="right"><b>3.1.</b></td><td>`bool do_intersect(InputIterator begin, InputIterator end, UsePolylines = Tag_true());`</td></tr>
* <tr><td align="right"><b>3.2.</b></td><td>`bool do_intersect(InputIterator begin, InputIterator end);`</td></tr>
* <tr><td align="right"><b> 4.</b></td><td>`bool do_intersect(InputIterator begin, InputIterator end, const GpsTraits& traits);`</td></tr>
* <tr><td align="right"><b>5.1.</b></td><td>`bool do_intersect(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, UsePolylines = Tag_true());`</td></tr>
* <tr><td align="right"><b>5.2.</b></td><td>`bool do_intersect(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2);`</td></tr>
* <tr><td align="right"><b> 6.</b></td><td>`bool do_intersect(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, const GpsTraits& traits);`</td></tr>
* <tr><td align="right"><b>3.</b></td><td>`bool do_intersect(InputIterator begin, InputIterator end);`</td></tr>
* <tr><td align="right"><b>4.</b></td><td>`bool do_intersect(InputIterator begin, InputIterator end, const GpsTraits& traits);`</td></tr>
* <tr><td align="right"><b>5.</b></td><td>`bool do_intersect(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2);`</td></tr>
* <tr><td align="right"><b>6.</b></td><td>`bool do_intersect(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, const GpsTraits& traits);`</td></tr>
* </table>
*
* \tparam UsePolylines determines whether the boundary of the input polygons
* are treated as a cyclic sequence of single (\f$x\f$-monotone) segments or as
* a cyclic sequence of (\f$x\f$-monotone) polylines. If substituted with
* `CGAL::Tag_true`, which is the default, the input polygons are converted to
* general polygons bounded by polylines before the operation is actually
* performed. If substituted with `CGAL::Tag_false`, the input polygons are used
* as is. Refer to \ref bso_ssectraits_sel for more information.
*
* - The types `Type1` and `Type2` of the parameters of
* `InputIterator1::value_type` and `InputIterator2::value_type` must be
* convertible to the types specified in a row in the table below,
* respectively.
*
* - The types that apply to signatures (<b>1.1.</b>) and (<b>5.1.</b>) above
* are restricted to those listed in rows <b>1&ndash;4</b> in the table
* below.
*
* - The types that apply to signatures (<b>1.2.</b>) and (<b>5.2.</b>) above
* are restricted to those listed in rows <b>5&ndash;8</b> in the table
* below.
*
* - The type of `InputIterator::value_type` in (<b>3.1.</b>) above
* must be convertible to either `Polygon_2` or `Polygon_with_holes_2`.
*
* - The type of `InputIterator::value_type` in (<b>3.2.</b>) above must be
* convertible to either `General_polygon_2` or
* `General_polygon_with_holes_2`.
* \tparam Kernel a model of the concept `PolygonTraits_2`.
* \tparam Container a model of the concept `Container`; defaults to `std::vector<Kernel::Point_2`>.
* \tparam ArrTraits a model of the concept `AosDirectionalXMonotoneTraits_2`.
* \tparam GpsTraits a model of the concept `GeneralPolygonSetTraits_2`, which must be convertible to `ArrTraits`.
*
* <div align="left">
* <table cellpadding=3 border="1">
@ -728,6 +714,8 @@ namespace CGAL {
* \sa \link boolean_join `CGAL::join()` \endlink
* \sa \link boolean_difference `CGAL::difference()` \endlink
* \sa \link boolean_symmetric_difference `CGAL::symmetric_difference()` \endlink
* \sa Polygon_2<Kernel, Container>
* \sa Polygon_with_holes_2<Kernel, Container>
*/
/// @{
@ -735,6 +723,11 @@ namespace CGAL {
//////// Traits-less
/*! determines whether two polygons intersect in their interior.
*
* The kernel used to instantiate the type of the input polygons must support
* exact predicates to guarantee correct results; however, inexact constructions
* are tolerated.
*
* \param pgn1 the 1st input polygon.
* \param pgn2 the 2nd input polygon.
* \return `true` if `pgn1` and `pgn2` intersect in their interior and `false`
@ -745,25 +738,11 @@ bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
const Polygon_2<Kernel, Container>& pgn2);
/*! determines whether two polygons intersect in their interior.
* \tparam UsePolylines determines whether the boundaries of `pgn1` and `pgn2`
* are treated as cyclic sequences of single (\f$x\f$-monotone) segments
* or as a cyclic sequences of (\f$x\f$-monotone) polylines. If
* substituted with `CGAL::Tag_true`, which is the default, `pgn1` and
* `pgn2` are converted to general polygons, bounded by polylines
* before the operation is actually performed. If substituted with
* `CGAL::Tag_false`, `pgn1` and `pgn2` are used as is. Refer to \ref
* bso_ssectraits_sel for more information.
* \param pgn1 the 1st input polygon.
* \param pgn2 the 2nd input polygon.
* \return `true` if `pgn1` and `pgn2` intersect in their interior and `false`
* otherwise.
*/
template <typename Kernel, typename Container, typename UsePolylines>
bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
const Polygon_2<Kernel, Container>& pgn2,
UsePolylines = Tag_true());
/*! determines whether two polygons intersect in their interior.
*
* The kernel used to instantiate the type of the input polygons must support
* exact predicates to guarantee correct results; however, inexact constructions
* are tolerated.
*
* \param pgn1 the 1st input polygon.
* \param pgn2 the 2nd input polygon.
* \return `true` if `pgn1` and `pgn2` intersect in their interior and `false`
@ -774,26 +753,11 @@ bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
const Polygon_with_holes_2<Kernel, Container>& pgn2);
/*! determines whether two polygons intersect in their interior.
* \tparam UsePolylines determines whether the boundaries of `pgn1` and `pgn2`
* are treated as cyclic sequences of single (\f$x\f$-monotone) segments
* or as a cyclic sequences of (\f$x\f$-monotone) polylines. If
* substituted with `CGAL::Tag_true`, which is the default, `pgn1` and
* `pgn2` are converted to a general polygon and a general polygon
* with holes, respectively, bounded by polylines before the operation
* is actually performed. If substituted with `CGAL::Tag_false`, `pgn1`
* and `pgn2` are used as is. Refer to \ref bso_ssectraits_sel for more
* information.
* \param pgn1 the 1st input polygon.
* \param pgn2 the 2nd input polygon.
* \return `true` if `pgn1` and `pgn2` intersect in their interior and `false`
* otherwise.
*/
template <typename Kernel, typename Container, typename UsePolylines>
bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
const Polygon_with_holes_2<Kernel, Container>& pgn2,
UsePolylines = Tag_true());
/*! determines whether two polygons intersect in their interior.
*
* The kernel used to instantiate the type of the input polygons must support
* exact predicates to guarantee correct results; however, inexact constructions
* are tolerated.
*
* \param pgn1 the 1st input polygon.
* \param pgn2 the 2nd input polygon.
* \return `true` if `pgn1` and `pgn2` intersect in their interior and `false`
@ -803,27 +767,12 @@ template <typename Kernel, typename Container>
bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
const Polygon_2<Kernel, Container>& pgn2);
/*! determines whether two polygons intersect in their interior.
* \tparam UsePolylines determines whether the boundaries of `pgn1` and `pgn2`
* are treated as cyclic sequences of single (\f$x\f$-monotone) segments
* or as a cyclic sequences of (\f$x\f$-monotone) polylines. If
* substituted with `CGAL::Tag_true`, which is the default, `pgn1` and
* `pgn2` are converted to a general polygon with holes and a general
* polygon, respectively, bounded by polylines before the operation
* is actually performed. If substituted with `CGAL::Tag_false`, `pgn1`
* and `pgn2` are used as is. Refer to \ref bso_ssectraits_sel for more
* information.
* \param pgn1 the 1st input polygon.
* \param pgn2 the 2nd input polygon.
* \return `true` if `pgn1` and `pgn2` intersect in their interior and `false`
* otherwise.
*/
template <typename Kernel, typename Container, typename UsePolylines>
bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
const Polygon_2<Kernel, Container>& pgn2,
UsePolylines = Tag_true());
/*! determines whether two polygons with holes intersect in their interior.
*
* The kernel used to instantiate the type of the input polygons must support
* exact predicates to guarantee correct results; however, inexact constructions
* are tolerated.
*
* \param pgn1 the 1st input polygon.
* \param pgn2 the 2nd input polygon.
* \return `true` if `pgn1` and `pgn2` intersect in their interior and `false`
@ -833,25 +782,6 @@ template <typename Kernel, typename Container>
bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
const Polygon_with_holes_2<Kernel, Container>& pgn2);
/*! determines whether two polygons with holes intersect in their interior.
* \tparam UsePolylines determines whether the boundaries of `pgn1` and `pgn2`
* are treated as cyclic sequences of single (\f$x\f$-monotone) segments
* or as a cyclic sequences of (\f$x\f$-monotone) polylines. If
* substituted with `CGAL::Tag_true`, which is the default, `pgn1` and
* `pgn2` are converted to general polygon with holes , bounded by
* polylines before the operation is actually performed. If substituted
* with `CGAL::Tag_false`, `pgn1` and `pgn2` are used as is. Refer to
* \ref bso_ssectraits_sel for more information.
* \param pgn1 the 1st input polygon.
* \param pgn2 the 2nd input polygon.
* \return `true` if `pgn1` and `pgn2` intersect in their interior and `false`
* otherwise.
*/
template <typename Kernel, typename Container, typename UsePolylines>
bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
const Polygon_with_holes_2<Kernel, Container>& pgn2,
UsePolylines = Tag_true());
/*! determines whether two general polygons intersect in their interior.
* \param pgn1 the 1st input polygon.
* \param pgn2 the 2nd input polygon.
@ -904,6 +834,13 @@ bool do_intersect(const General_polygon_with_holes_2<Polygon>& pgn1,
* of general polygons or a range of general polygons with holes) determines
* whether the open polygons (respectively general polygons) in the range have a common
* point.
*
* When the operation is applied to linear polygons (that is, the value type of
* the input iterator is either `Polygon_2` or `Polygon_with_holes_2`), the
* kernel used to instantiate the type of the input polygons must support exact
* predicates to guarantee correct results; however, inexact constructions are
* tolerated.
*
* \param begin the first iterator of the input range. Its value type is
* either `Polygon_2` (respectively `General_polygon_2`) or
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
@ -917,36 +854,16 @@ bool do_intersect(const General_polygon_with_holes_2<Polygon>& pgn1,
template <typename InputIterator>
bool do_intersect(InputIterator begin, InputIterator end);
/*! Given a range of polygons or a range of polygons with holes (respectively a range
* of general polygons or a range of general polygons with holes) determines
* whether the open polygons (respectively general polygons) in the range have a common
* point.
* \tparam UsePolylines determines whether the boundaries of the polygons in the
* input range are treated as cyclic sequences of single
* (\f$x\f$-monotone) segments or as a cyclic sequences of
* (\f$x\f$-monotone) polylines. If substituted with `CGAL::Tag_true`,
* which is the default, the input polygons are converted to general
* polygon with holes , bounded by polylines before the operation is
* actually performed. If substituted with `CGAL::Tag_false`, `pgn1` and
* `pgn2` are used as is. Refer to \ref bso_ssectraits_sel for more
* information.
* \param begin the first iterator of the input range. Its value type is
* either `Polygon_2` (respectively `General_polygon_2`) or
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
* \param end the past-the-end iterator of the input range. Its value type is
* either `Polygon_2` (respectively `General_polygon_2`) or
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
* \return `true` if the pairwise intersections of all open polygons or polygons
* with holes (respectively general polygons or general polygons with holes) in
* the range [*begin,*end) overlap, and `false` otherwise.
*/
template <typename InputIterator, typename UsePolylines>
bool do_intersect(InputIterator begin, InputIterator end,
UsePolylines = Tag_true());
/*! Given a range of polygons (respectively general polygons) and a range of polygons
* with holes (respectively general polygons with holes) determines whether the open
* polygons (respectively general polygons) in the two ranges have a common point.
*
* When the operation is applied to linear polygons (that is, the value type of
* any input iterator is either `Polygon_2` or `Polygon_with_holes_2`), the
* kernel used to instantiate the type of the input polygons must support exact
* predicates to guarantee correct results; however, inexact constructions are
* tolerated.
*
* \param begin1 the first iterator of the 1st input range. Its value type is
* `Polygon_2` (respectively `General_polygon_2`).
* \param end1 the past-the-end iterator of the 1st input range. Its value
@ -964,40 +881,14 @@ template <typename InputIterator1, typename InputIterator2>
bool do_intersect(InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2);
/*! Given a range of polygons (respectively general polygons) and a range of polygons
* with holes (respectively general polygons with holes) determines whether the open
* polygons (respectively general polygons) in the two ranges have a common point.
* \tparam UsePolylines determines whether the boundaries of the polygons in the
* input ranges are treated as cyclic sequences of single
* (\f$x\f$-monotone) segments or as a cyclic sequences of
* (\f$x\f$-monotone) polylines. If substituted with `CGAL::Tag_true`,
* which is the default, the input polygons are converted to general
* polygon with holes , bounded by polylines before the operation is
* actually performed. If substituted with `CGAL::Tag_false`, `pgn1` and
* `pgn2` are used as is. Refer to \ref bso_ssectraits_sel for more
* information.
* \param begin1 the first iterator of the 1st input range. Its value type is
* `Polygon_2` (respectively `General_polygon_2`).
* \param end1 the past-the-end iterator of the 1st input range. Its value
* type is `Polygon_2` (respectively `General_polygon_2`).
* \param begin2 the first iterator of the 2nd input range. Its value type
* is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
* \param end2 the past-the-end iterator of the 2nd input range. Its value
* type is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
* \return `true` if the pairwise intersections of all open polygons (respectively
* general polygons) and polygons with holes (respectively general polygons with
* holes) in the ranges [*begin1,*end1) and [*begin2,*end2),
* respectively, overlap, and `false` otherwise.
*/
template <typename InputIterator1, typename InputIterator2,
typename UsePolylines>
bool do_intersect(InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
UsePolylines = Tag_true());
//////// With Traits
/*! determines whether two polygons intersect in their interior.
*
* The kernel used to instantiate the type of the input polygons must support
* exact predicates to guarantee correct results; however, inexact constructions
* are tolerated.
*
* \param pgn1 the 1st input polygon.
* \param pgn2 the 2nd input polygon.
* \param traits a traits object.
@ -1011,6 +902,11 @@ bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
const GpsTraits& traits);
/*! determines whether two polygons intersect in their interior.
*
* The kernel used to instantiate the type of the input polygons must support
* exact predicates to guarantee correct results; however, inexact constructions
* are tolerated.
*
* \param pgn1 the 1st input polygon.
* \param pgn2 the 2nd input polygon.
* \param traits a traits object.
@ -1021,10 +917,14 @@ bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
template <typename Kernel, typename Container, typename GpsTraits>
bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
const Polygon_with_holes_2<Kernel, Container>& pgn2,
const GpsTraits& traits,
const GpsTraits& traits);
/*! determines whether two polygons intersect in their interior.
*
* The kernel used to instantiate the type of the input polygons must support
* exact predicates to guarantee correct results; however, inexact constructions
* are tolerated.
*
* \param pgn1 the 1st input polygon.
* \param pgn2 the 2nd input polygon.
* \param traits a traits object.
@ -1038,6 +938,11 @@ bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
const GpsTraits& traits);
/*! determines whether two polygons with holes intersect in their interior.
*
* The kernel used to instantiate the type of the input polygons must support
* exact predicates to guarantee correct results; however, inexact constructions
* are tolerated.
*
* \param pgn1 the 1st input polygon.
* \param pgn2 the 2nd input polygon.
* \param traits a traits object.
@ -1116,6 +1021,12 @@ bool do_intersect(const General_polygon_with_holes_2<Polygon>& pgn1,
* of general polygons or a range of general polygons with holes) determines
* whether the open polygons (respectively general polygons) in the range have a common
* point.
*
* When the operation is applied to linear polygons (that is, the value type of
* the input iterator is either `Polygon_2` or `Polygon_with_holes_2`), the
* traits parameter `GpsTraits` must support exact predicates to guarantee
* correct results; however, inexact constructions are tolerated.
*
* \param begin the first iterator of the input range. Its value type is
* either `Polygon_2` (respectively `General_polygon_2`) or
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
@ -1135,6 +1046,12 @@ bool do_intersect(InputIterator begin, InputIterator end,
/*! Given a range of polygons (respectively general polygons) and a range of polygons
* with holes (respectively general polygons with holes) determines whether the open
* polygons (respectively general polygons) in the two ranges have a common point.
*
* When the operation is applied to linear polygons (that is, the value type of
* any input iterator is either `Polygon_2` or `Polygon_with_holes_2`), the
* traits parameter `GpsTraits` must support exact predicates to guarantee
* correct results; however, inexact constructions are tolerated.
*
* \param begin1 the first iterator of the 1st input range. Its value type is
* `Polygon_2` (respectively `General_polygon_2`).
* \param end1 the past-the-end iterator of the 1st input range. Its value
@ -1186,6 +1103,10 @@ namespace CGAL {
* <tr><td align="right"><b>6.</b></td><td>`OutputIterator intersection(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, OutputIterator oi, const GpsTraits& traits);`</td></tr>
* </table>
*
* \tparam Kernel a model of the concept `PolygonTraits_2`.
* \tparam Container a model of the concept `Container`; defaults to `std::vector<Kernel::Point_2`>.
* \tparam ArrTraits a model of the concept `AosDirectionalXMonotoneTraits_2`.
* \tparam GpsTraits a model of the concept `GeneralPolygonSetTraits_2`, which must be convertible to `ArrTraits`.
* \tparam UsePolylines determines whether the boundaries of the input polygons
* are treated as cyclic sequences of single (\f$x\f$-monotone) segments or as
* cyclic sequences of (\f$x\f$-monotone) polylines. If substituted with
@ -1244,6 +1165,8 @@ namespace CGAL {
* \sa \link boolean_join `CGAL::join()` \endlink
* \sa \link boolean_difference `CGAL::difference()` \endlink
* \sa \link boolean_symmetric_difference `CGAL::symmetric_difference()` \endlink
* \sa Polygon_2<Kernel, Container>
* \sa Polygon_with_holes_2<Kernel, Container>
*/
/// @{
@ -1825,6 +1748,10 @@ namespace CGAL {
* <tr><td align="right"><b>6.</b></td><td>`OutputIterator join(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, OutputIterator oi, const GpsTraits& traits);`</td></tr>
* </table>
*
* \tparam Kernel a model of the concept `PolygonTraits_2`.
* \tparam Container a model of the concept `Container`; defaults to `std::vector<Kernel::Point_2`>.
* \tparam ArrTraits a model of the concept `AosDirectionalXMonotoneTraits_2`.
* \tparam GpsTraits a model of the concept `GeneralPolygonSetTraits_2`, which must be convertible to `ArrTraits`.
* \tparam UsePolylines determines whether the boundaries of the input polygons
* are treated as cyclic sequences of single (\f$x\f$-monotone) segments or as
* cyclic sequences of (\f$x\f$-monotone) polylines. If substituted with
@ -1882,6 +1809,8 @@ namespace CGAL {
* \sa \link boolean_intersection `CGAL::intersection()` \endlink
* \sa \link boolean_difference `CGAL::difference()` \endlink
* \sa \link boolean_symmetric_difference `CGAL::symmetric_difference()` \endlink
* \sa Polygon_2<Kernel, Container>
* \sa Polygon_with_holes_2<Kernel, Container>
*/
/// @{
@ -2407,6 +2336,10 @@ namespace CGAL {
* <tr><td align="right"><b> 4.</b></td><td>`Oriented_side oriented_side(const Point_2& p, const Type& pgn, const GpsTraits& traits);`</td></tr>
* </table>
*
* \tparam Kernel a model of the concept `PolygonTraits_2`.
* \tparam Container a model of the concept `Container`; defaults to `std::vector<Kernel::Point_2`>.
* \tparam ArrTraits a model of the concept `AosDirectionalXMonotoneTraits_2`.
* \tparam GpsTraits a model of the concept `GeneralPolygonSetTraits_2`, which must be convertible to `ArrTraits`.
* \tparam UsePolylines determines whether the boundaries of the input polygons
* are treated as cyclic sequences of single (\f$x\f$-monotone) segments or as
* cyclic sequences of (\f$x\f$-monotone) polylines. If substituted with
@ -2446,6 +2379,8 @@ namespace CGAL {
* \param traits an optional traits object.
*
* \sa \link boolean_do_intersect `CGAL::do_intersect()` \endlink
* \sa Polygon_2<Kernel, Container>
* \sa Polygon_with_holes_2<Kernel, Container>
*/
/// @{
@ -2823,6 +2758,10 @@ namespace CGAL {
* <tr><td align="right"><b>6.</b></td><td>`OutputIterator symmetric_difference(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, OutputIterator oi, const GpsTraits& traits);`</td></tr>
* </table>
*
* \tparam Kernel a model of the concept `PolygonTraits_2`.
* \tparam Container a model of the concept `Container`; defaults to `std::vector<Kernel::Point_2`>.
* \tparam ArrTraits a model of the concept `AosDirectionalXMonotoneTraits_2`.
* \tparam GpsTraits a model of the concept `GeneralPolygonSetTraits_2`, which must be convertible to `ArrTraits`.
* \tparam UsePolylines determines whether the boundaries of the input polygons
* are treated as cyclic sequences of single (\f$x\f$-monotone) segments or as
* cyclic sequences of (\f$x\f$-monotone) polylines. If substituted with
@ -2879,6 +2818,8 @@ namespace CGAL {
* \sa \link boolean_intersection `CGAL::intersection()` \endlink
* \sa \link boolean_join `CGAL::join()` \endlink
* \sa \link boolean_difference `CGAL::difference()` \endlink
* \sa Polygon_2<Kernel, Container>
* \sa Polygon_with_holes_2<Kernel, Container>
*/
/// @{

View File

@ -5,27 +5,26 @@
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Boolean_set_operations_2.h>
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef Kernel::Point_2 Point_2;
typedef CGAL::Polygon_2<Kernel> Polygon_2;
using Kernel = CGAL::Exact_predicates_exact_constructions_kernel;
using Point_2 = Kernel::Point_2;
using Polygon_2 = CGAL::Polygon_2<Kernel>;
#include "print_utils.h"
int main ()
{
int main() {
Polygon_2 P;
P.push_back (Point_2 (-1,1));
P.push_back (Point_2 (0,-1));
P.push_back (Point_2 (1,1));
std::cout << "P = "; print_polygon (P);
P.push_back(Point_2(-1, 1));
P.push_back(Point_2(0, -1));
P.push_back(Point_2(1, 1));
std::cout << "P = "; print_polygon(P);
Polygon_2 Q;
Q.push_back(Point_2 (-1,-1));
Q.push_back(Point_2 (1,-1));
Q.push_back(Point_2 (0,1));
std::cout << "Q = "; print_polygon (Q);
Q.push_back(Point_2(-1, -1));
Q.push_back(Point_2(1, -1));
Q.push_back(Point_2(0, 1));
std::cout << "Q = "; print_polygon(Q);
if ((CGAL::do_intersect (P, Q)))
if ((CGAL::do_intersect(P, Q)))
std::cout << "The two polygons intersect in their interior." << std::endl;
else
std::cout << "The two polygons do not intersect." << std::endl;

View File

@ -8,10 +8,10 @@
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s): Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Simon Giraudot <simon.giraudot@geometryfactory.com>
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Simon Giraudot <simon.giraudot@geometryfactory.com>
#ifndef CGAL_BSO_INTERNAL_FUNCTIONS_H
#define CGAL_BSO_INTERNAL_FUNCTIONS_H
@ -33,7 +33,7 @@ namespace CGAL {
// Single
// With Traits
template <typename Pgn1, class Pgn2, typename Traits>
template <typename Pgn1, typename Pgn2, typename Traits>
inline bool s_do_intersect(const Pgn1& pgn1, const Pgn2& pgn2, Traits& traits) {
General_polygon_set_2<Traits> gps(pgn1, traits);
return gps.do_intersect(pgn2);
@ -52,7 +52,7 @@ inline bool s_do_intersect(const Pgn1& pgn1, const Pgn2& pgn2) {
// With Traits
template <typename InputIterator, typename Traits>
inline bool r_do_intersect(InputIterator begin, InputIterator end,
Traits& traits, unsigned int k=5) {
Traits& traits, std::size_t k = 5) {
if (begin == end) return false;
General_polygon_set_2<Traits> gps(*begin, traits);
return gps.do_intersect(std::next(begin), end, k);
@ -61,8 +61,8 @@ inline bool r_do_intersect(InputIterator begin, InputIterator end,
// Without Traits
template <typename InputIterator>
inline bool r_do_intersect(InputIterator begin, InputIterator end,
unsigned int k=5) {
typedef typename std::iterator_traits<InputIterator>::value_type Pgn;
std::size_t k = 5) {
using Pgn = typename std::iterator_traits<InputIterator>::value_type;
typename Gps_polyline_traits<Pgn>::Traits traits;
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
return r_do_intersect(convert_polygon_iterator(begin, ptraits),
@ -74,7 +74,7 @@ inline bool r_do_intersect(InputIterator begin, InputIterator end,
template <typename InputIterator1, typename InputIterator2, typename Traits>
inline bool r_do_intersect(InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
Traits& traits, unsigned int k=5) {
Traits& traits, std::size_t k = 5) {
if (begin1 == end1) return do_intersect(begin2, end2, traits, k);
General_polygon_set_2<Traits> gps(*begin1, traits);
return gps.do_intersect(std::next(begin1), end1, begin2, end2, k);
@ -84,8 +84,8 @@ inline bool r_do_intersect(InputIterator1 begin1, InputIterator1 end1,
template <typename InputIterator1, typename InputIterator2>
inline bool r_do_intersect (InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
unsigned int k=5) {
typedef typename std::iterator_traits<InputIterator1>::value_type Pgn;
std::size_t k = 5) {
using Pgn = typename std::iterator_traits<InputIterator1>::value_type;
typename Gps_polyline_traits<Pgn>::Traits traits;
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
return r_do_intersect(convert_polygon_iterator(begin1, ptraits),
@ -119,8 +119,7 @@ inline Oriented_side _oriented_side(const Point_2<Kernel>& point,
// Without Traits (polygon, polygon)
template <typename Pgn1, typename Pgn2>
inline Oriented_side _oriented_side(const Pgn1& pgn1, const Pgn2& pgn2)
{
inline Oriented_side _oriented_side(const Pgn1& pgn1, const Pgn2& pgn2) {
// Use the first polygon to determine the (default) traits
typename Gps_polyline_traits<Pgn1>::Traits traits;
const typename Gps_polyline_traits<Pgn1>::Polyline_traits& ptraits(traits);
@ -149,7 +148,7 @@ template <typename Kernel, typename Container,
inline OutputIterator s_intersection(const Pgn1& pgn1, const Pgn2& pgn2,
OutputIterator oi) {
// Use the first polygon to determine the (default) traits
typedef typename Gps_polyline_traits<Pgn1>::Polyline_traits Polyline_traits;
using Polyline_traits = typename Gps_polyline_traits<Pgn1>::Polyline_traits;
typename Gps_polyline_traits<Pgn1>::Traits traits;
const Polyline_traits& ptraits(traits);
@ -163,7 +162,7 @@ inline OutputIterator s_intersection(const Pgn1& pgn1, const Pgn2& pgn2,
template <typename InputIterator, typename OutputIterator, typename Traits>
inline OutputIterator r_intersection(InputIterator begin, InputIterator end,
OutputIterator oi, Traits& traits,
unsigned int k=5) {
std::size_t k = 5) {
if (begin == end) return (oi);
General_polygon_set_2<Traits> gps(*begin, traits);
gps.intersection(std::next(begin), end, k);
@ -173,8 +172,8 @@ inline OutputIterator r_intersection(InputIterator begin, InputIterator end,
// Without Traits
template <typename InputIterator, typename OutputIterator>
inline OutputIterator r_intersection(InputIterator begin, InputIterator end,
OutputIterator oi, unsigned int k=5) {
typedef typename std::iterator_traits<InputIterator>::value_type Pgn;
OutputIterator oi, std::size_t k = 5) {
using Pgn = typename std::iterator_traits<InputIterator>::value_type;
typename Gps_polyline_traits<Pgn>::Traits traits;
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
if (begin == end) return (oi);
@ -190,7 +189,7 @@ template <typename InputIterator1, typename InputIterator2,
inline OutputIterator r_intersection(InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
OutputIterator oi, Traits& traits,
unsigned int k=5) {
std::size_t k = 5) {
if (begin1 == end1) return r_intersection(begin2, end2, oi, traits, k);
General_polygon_set_2<Traits> gps(*begin1, traits);
gps.intersection(std::next(begin1), end1, begin2, end2, k);
@ -203,8 +202,8 @@ template <typename InputIterator1, typename InputIterator2,
inline OutputIterator
r_intersection(InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
OutputIterator oi, unsigned int k=5) {
typedef typename std::iterator_traits<InputIterator1>::value_type Pgn;
OutputIterator oi, std::size_t k = 5) {
using Pgn = typename std::iterator_traits<InputIterator1>::value_type;
typename Gps_polyline_traits<Pgn>::Traits traits;
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
if (begin1 == end1) {
@ -228,7 +227,7 @@ r_intersection(InputIterator1 begin1, InputIterator1 end1,
// Polygon_2
template <typename Traits>
inline bool _is_empty(const typename Traits::Polygon_2& pgn, Traits& traits) {
typedef typename Traits::Curve_const_iterator Curve_const_iterator;
using Curve_const_iterator = typename Traits::Curve_const_iterator;
const std::pair<Curve_const_iterator, Curve_const_iterator>& itr_pair =
traits.construct_curves_2_object()(pgn);
return (itr_pair.first == itr_pair.second);
@ -268,9 +267,9 @@ template <typename Kernel, typename Container,
typename Pgn1, typename Pgn2, typename Pwh>
inline bool s_join(const Pgn1& pgn1, const Pgn2& pgn2, Pwh& pwh) {
// Use the first polygon to determine the (default) traits
typedef typename Gps_polyline_traits<Pgn1>::Polyline_traits Polyline_traits;
typedef General_polygon_2<Polyline_traits> General_pgn;
typedef General_polygon_with_holes_2<General_pgn> General_pwh;
using Polyline_traits = typename Gps_polyline_traits<Pgn1>::Polyline_traits;
using General_pgn = General_polygon_2<Polyline_traits>;
using General_pwh = General_polygon_with_holes_2<General_pgn>;
General_pwh general_pwh;
typename Gps_polyline_traits<Pgn1>::Traits traits;
@ -287,7 +286,7 @@ inline bool s_join(const Pgn1& pgn1, const Pgn2& pgn2, Pwh& pwh) {
template <typename InputIterator, typename OutputIterator, typename Traits>
inline OutputIterator r_join(InputIterator begin, InputIterator end,
OutputIterator oi, Traits& traits,
unsigned int k=5) {
std::size_t k = 5) {
if (begin == end) return oi;
General_polygon_set_2<Traits> gps(*begin, traits);
gps.join(std::next(begin), end, k);
@ -297,8 +296,8 @@ inline OutputIterator r_join(InputIterator begin, InputIterator end,
// Without traits
template <typename InputIterator, typename OutputIterator>
inline OutputIterator r_join(InputIterator begin, InputIterator end,
OutputIterator oi, unsigned int k=5) {
typedef typename std::iterator_traits<InputIterator>::value_type Pgn;
OutputIterator oi, std::size_t k = 5) {
using Pgn = typename std::iterator_traits<InputIterator>::value_type;
typename Gps_polyline_traits<Pgn>::Traits traits;
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
@ -316,7 +315,7 @@ template <typename InputIterator1, typename InputIterator2,
inline OutputIterator r_join(InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
OutputIterator oi, Traits& traits,
unsigned int k=5) {
std::size_t k = 5) {
if (begin1 == end1) return r_join(begin2, end2, oi, traits, k);
General_polygon_set_2<Traits> gps(*begin1, traits);
gps.join(std::next(begin1), end1, begin2, end2, k);
@ -328,8 +327,8 @@ template <typename InputIterator1, typename InputIterator2,
typename OutputIterator>
inline OutputIterator r_join(InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
OutputIterator oi, unsigned int k=5) {
typedef typename std::iterator_traits<InputIterator1>::value_type Pgn;
OutputIterator oi, std::size_t k = 5) {
using Pgn = typename std::iterator_traits<InputIterator1>::value_type;
typename Gps_polyline_traits<Pgn>::Traits traits;
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
if (begin1 == end1) {
@ -361,10 +360,9 @@ inline OutputIterator _difference(const Pgn1& pgn1, const Pgn2& pgn2,
template <typename Kernel, typename Container,
typename Pgn1, typename Pgn2, typename OutputIterator>
inline OutputIterator _difference(const Pgn1& pgn1, const Pgn2& pgn2,
OutputIterator oi)
{
OutputIterator oi) {
// Use the first polygon to determine the (default) traits
typedef typename Gps_polyline_traits<Pgn1>::Polyline_traits Polyline_traits;
using Polyline_traits = typename Gps_polyline_traits<Pgn1>::Polyline_traits;
typename Gps_polyline_traits<Pgn1>::Traits traits;
const Polyline_traits& ptraits(traits);
@ -394,7 +392,7 @@ template <typename Kernel, typename Container,
inline OutputIterator s_symmetric_difference(const Pgn1& pgn1, const Pgn2& pgn2,
OutputIterator oi) {
// Use the first polygon to determine the (default) traits
typedef typename Gps_polyline_traits<Pgn1>::Polyline_traits Polyline_traits;
using Polyline_traits = typename Gps_polyline_traits<Pgn1>::Polyline_traits;
typename Gps_polyline_traits<Pgn1>::Traits traits;
const Polyline_traits& ptraits(traits);
s_symmetric_difference(convert_polygon(pgn1, ptraits),
@ -409,7 +407,7 @@ template <typename InputIterator, typename OutputIterator, typename Traits>
inline
OutputIterator r_symmetric_difference(InputIterator begin, InputIterator end,
OutputIterator oi, Traits& traits,
unsigned int k=5) {
std::size_t k = 5) {
if (begin == end) return (oi);
General_polygon_set_2<Traits> gps(*begin, traits);
gps.symmetric_difference(std::next(begin), end, k);
@ -421,9 +419,8 @@ template <typename InputIterator, typename OutputIterator>
inline OutputIterator r_symmetric_difference(InputIterator begin,
InputIterator end,
OutputIterator oi,
unsigned int k=5)
{
typedef typename std::iterator_traits<InputIterator>::value_type Pgn;
std::size_t k = 5) {
using Pgn = typename std::iterator_traits<InputIterator>::value_type;
typename Gps_polyline_traits<Pgn>::Traits traits;
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
if (begin == end) return (oi);
@ -441,8 +438,7 @@ inline OutputIterator r_symmetric_difference(InputIterator1 begin1,
InputIterator2 begin2,
InputIterator2 end2,
OutputIterator oi, Traits& traits,
unsigned int k=5)
{
std::size_t k = 5) {
if (begin1 == end1) return r_symmetric_difference(begin2, end2, oi, traits, k);
General_polygon_set_2<Traits> gps(*begin1, traits);
gps.symmetric_difference(std::next(begin1), end1, begin2, end2, k);
@ -457,8 +453,8 @@ inline OutputIterator r_symmetric_difference(InputIterator1 begin1,
InputIterator2 begin2,
InputIterator2 end2,
OutputIterator oi,
unsigned int k=5) {
typedef typename std::iterator_traits<InputIterator1>::value_type Pgn;
std::size_t k = 5) {
using Pgn = typename std::iterator_traits<InputIterator1>::value_type;
typename Gps_polyline_traits<Pgn>::Traits traits;
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
if (begin1 == end1){
@ -522,10 +518,10 @@ OutputIterator _complement(const General_polygon_with_holes_2<Pgn>& pgn,
template <typename Kernel, typename Container, typename Pwh>
void _complement(const Polygon_2<Kernel, Container>& pgn, Pwh& pwh) {
// Use the polygon to determine the (default) traits
typedef Polygon_2<Kernel, Container> Pgn;
typedef typename Gps_polyline_traits<Pgn>::Polyline_traits Polyline_traits;
typedef General_polygon_2<Polyline_traits> General_pgn;
typedef General_polygon_with_holes_2<General_pgn> General_pwh;
using Pgn = Polygon_2<Kernel, Container>;
using Polyline_traits = typename Gps_polyline_traits<Pgn>::Polyline_traits;
using General_pgn = General_polygon_2<Polyline_traits>;
using General_pwh = General_polygon_with_holes_2<General_pgn>;
General_pwh general_pwh;
typename Gps_polyline_traits<Pgn>::Traits traits;
@ -539,8 +535,8 @@ template <typename Kernel, typename Container, typename OutputIterator>
OutputIterator _complement(const Polygon_with_holes_2<Kernel, Container>& pgn,
OutputIterator oi) {
// Use the polygon with holes to determine the (default) traits
typedef Polygon_with_holes_2<Kernel, Container> Pgn;
typedef typename Gps_polyline_traits<Pgn>::Polyline_traits Polyline_traits;
using Pgn = Polygon_with_holes_2<Kernel, Container>;
using Polyline_traits = typename Gps_polyline_traits<Pgn>::Polyline_traits;
typename Gps_polyline_traits<Pgn>::Traits traits;
const Polyline_traits& ptraits(traits);

View File

@ -7,12 +7,11 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s): Baruch Zukerman <baruchzu@post.tau.ac.il>
// Efi Fogel <efifogel@gmail.com>
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Efi Fogel <efifogel@gmail.com>
#ifndef CGAL_BSO_2_GPS_AGG_META_TRAITS_H
#define CGAL_BSO_2_GPS_AGG_META_TRAITS_H
#ifndef CGAL_GPS_AGG_META_TRAITS_H
#define CGAL_GPS_AGG_META_TRAITS_H
#include <CGAL/license/Boolean_set_operations_2.h>
@ -24,18 +23,17 @@
namespace CGAL {
template <typename Arrangement_>
class Gps_agg_curve_data : public Curve_with_halfedge<Arrangement_>
{
class Gps_agg_curve_data : public Curve_with_halfedge<Arrangement_> {
protected:
typedef Arrangement_ Arrangement;
typedef typename Arrangement::Halfedge_handle Halfedge_handle;
typedef Curve_with_halfedge<Arrangement_> Base;
using Arrangement = Arrangement_;
using Halfedge_handle = typename Arrangement::Halfedge_handle;
using Base = Curve_with_halfedge<Arrangement_>;
const Arrangement* m_arr; // pointer to the arrangement containing the edge.
unsigned int m_bc; // the boundary counter of the halfedge with the same
std::size_t m_bc; // the boundary counter of the halfedge with the same
// direction as the curve
unsigned int m_twin_bc; // the boundary counter of the halfedge with the same
std::size_t m_twin_bc; // the boundary counter of the halfedge with the same
// direction as the curve
public:
@ -47,24 +45,24 @@ public:
{}
Gps_agg_curve_data(const Arrangement* arr, Halfedge_handle he,
unsigned int bc, unsigned int twin_bc) :
std::size_t bc, std::size_t twin_bc) :
Base(he),
m_arr(arr),
m_bc(bc),
m_twin_bc(twin_bc)
{}
unsigned int bc() const { return m_bc; }
std::size_t bc() const { return m_bc; }
unsigned int twin_bc() const { return m_twin_bc; }
std::size_t twin_bc() const { return m_twin_bc; }
unsigned int& bc() { return m_bc; }
std::size_t& bc() { return m_bc; }
unsigned int& twin_bc() { return m_twin_bc; }
std::size_t& twin_bc() { return m_twin_bc; }
void set_bc(unsigned int bc) { m_bc = bc; }
void set_bc(std::size_t bc) { m_bc = bc; }
void set_twin_bc(unsigned int twin_bc) { m_twin_bc = twin_bc; }
void set_twin_bc(std::size_t twin_bc) { m_twin_bc = twin_bc; }
const Arrangement* arr() const { return m_arr; }
};
@ -73,54 +71,50 @@ template <typename Arrangement_>
class Gps_agg_meta_traits :
public Gps_traits_decorator<typename Arrangement_::Traits_adaptor_2,
Gps_agg_curve_data<Arrangement_>,
Point_with_vertex<Arrangement_> >
{
typedef Arrangement_ Arrangement;
typedef Arrangement Arr;
Point_with_vertex<Arrangement_>> {
using Arrangement = Arrangement_;
using Arr = Arrangement;
typedef typename Arr::Traits_adaptor_2 Traits;
typedef Traits Gt2;
using Traits = typename Arr::Traits_adaptor_2;
using Gt2 = Traits;
typedef typename Gt2::X_monotone_curve_2 Base_x_monotone_curve_2;
typedef typename Gt2::Point_2 Base_point_2;
typedef typename Gt2::Construct_min_vertex_2 Base_Construct_min_vertex_2;
typedef typename Gt2::Construct_max_vertex_2 Base_Construct_max_vertex_2;
typedef typename Gt2::Compare_endpoints_xy_2 Base_Compare_endpoints_xy_2;
typedef typename Gt2::Compare_xy_2 Base_Compare_xy_2;
typedef typename Gt2::Compare_y_at_x_right_2 Base_Compare_y_at_x_right_2;
typedef typename Gt2::Compare_y_at_x_2 Base_Compare_y_at_x_2;
typedef typename Gt2::Intersect_2 Base_Intersect_2;
typedef typename Gt2::Split_2 Base_Split_2;
using Base_x_monotone_curve_2 = typename Gt2::X_monotone_curve_2;
using Base_point_2 = typename Gt2::Point_2;
using Base_Construct_min_vertex_2 = typename Gt2::Construct_min_vertex_2;
using Base_Construct_max_vertex_2 = typename Gt2::Construct_max_vertex_2;
using Base_Compare_endpoints_xy_2 = typename Gt2::Compare_endpoints_xy_2;
using Base_Compare_xy_2 = typename Gt2::Compare_xy_2;
using Base_Compare_y_at_x_right_2 = typename Gt2::Compare_y_at_x_right_2;
using Base_Compare_y_at_x_2 = typename Gt2::Compare_y_at_x_2;
using Base_Intersect_2 = typename Gt2::Intersect_2;
using Base_Split_2 = typename Gt2::Split_2;
typedef typename Gt2::Parameter_space_in_x_2 Base_Parameter_space_in_x_2;
typedef typename Gt2::Compare_y_near_boundary_2
Base_Compare_y_near_boundary_2;
using Base_Parameter_space_in_x_2 = typename Gt2::Parameter_space_in_x_2;
using Base_Compare_y_near_boundary_2 = typename Gt2::Compare_y_near_boundary_2;
typedef typename Gt2::Parameter_space_in_y_2 Base_Parameter_space_in_y_2;
typedef typename Gt2::Compare_x_near_boundary_2
Base_Compare_x_near_boundary_2;
using Base_Parameter_space_in_y_2 = typename Gt2::Parameter_space_in_y_2;
using Base_Compare_x_near_boundary_2 = typename Gt2::Compare_x_near_boundary_2;
public:
typedef typename Gt2::Multiplicity Multiplicity;
typedef Gps_agg_curve_data<Arr> Curve_data;
typedef Point_with_vertex<Arr> Point_data;
using Multiplicity = typename Gt2::Multiplicity;
using Curve_data = Gps_agg_curve_data<Arr>;
using Point_data = Point_with_vertex<Arr>;
private:
typedef Gps_agg_meta_traits<Arrangement> Self;
typedef Gps_traits_decorator<Gt2, Curve_data, Point_data> Base;
using Self = Gps_agg_meta_traits<Arrangement>;
using Base = Gps_traits_decorator<Gt2, Curve_data, Point_data>;
public:
typedef typename Base::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Base::Point_2 Point_2;
typedef typename Gt2::Has_left_category Has_left_category;
typedef typename Gt2::Has_merge_category Has_merge_category;
typedef typename Gt2::Has_do_intersect_category
Has_do_intersect_category;
using X_monotone_curve_2 = typename Base::X_monotone_curve_2;
using Point_2 = typename Base::Point_2;
using Has_left_category = typename Gt2::Has_left_category;
using Has_merge_category = typename Gt2::Has_merge_category;
using Has_do_intersect_category = typename Gt2::Has_do_intersect_category;
typedef typename Arr::Left_side_category Left_side_category;
typedef typename Arr::Bottom_side_category Bottom_side_category;
typedef typename Arr::Top_side_category Top_side_category;
typedef typename Arr::Right_side_category Right_side_category;
using Left_side_category = typename Arr::Left_side_category;
using Bottom_side_category = typename Arr::Bottom_side_category;
using Top_side_category = typename Arr::Top_side_category;
using Right_side_category = typename Arr::Right_side_category;
// a side is either oblivious or open (unbounded)
static_assert(std::is_same<Left_side_category, Arr_oblivious_side_tag>::value ||
@ -132,8 +126,8 @@ public:
static_assert(std::is_same<Right_side_category, Arr_oblivious_side_tag>::value ||
std::is_same<Right_side_category, Arr_open_side_tag>::value);
typedef typename Arr::Halfedge_handle Halfedge_handle;
typedef typename Arr::Vertex_handle Vertex_handle;
using Halfedge_handle = typename Arr::Halfedge_handle;
using Vertex_handle = typename Arr::Vertex_handle;
Gps_agg_meta_traits() {}
@ -152,16 +146,13 @@ public:
template <typename OutputIterator>
OutputIterator operator()(const X_monotone_curve_2& cv1,
const X_monotone_curve_2& cv2,
OutputIterator oi) const
{
OutputIterator oi) const {
// Check whether the curves are already in the same arrangement, and thus
// must be interior-disjoint
if (cv1.data().arr() == cv2.data().arr()) return oi;
typedef const std::pair<Base_point_2, Multiplicity>
Intersection_base_point;
typedef std::variant<Intersection_base_point, Base_x_monotone_curve_2>
Intersection_base_result;
using Intersection_base_point = const std::pair<Base_point_2, Multiplicity>;
using Intersection_base_result = std::variant<Intersection_base_point, Base_x_monotone_curve_2>;
const auto* base_traits = m_traits.m_base_traits;
auto base_cmp_xy = base_traits->compare_xy_2_object();
@ -191,8 +182,8 @@ public:
const Base_x_monotone_curve_2* overlap_cv =
std::get_if<Base_x_monotone_curve_2>(&xection);
CGAL_assertion(overlap_cv != nullptr);
unsigned int ov_bc;
unsigned int ov_twin_bc;
std::size_t ov_bc;
std::size_t ov_twin_bc;
if (base_cmp_endpoints(cv1) == base_cmp_endpoints(cv2)) {
// cv1 and cv2 have the same directions
ov_bc = cv1.data().bc() + cv2.data().bc();
@ -230,8 +221,7 @@ public:
Split_2(const Base_Split_2& base) : m_base_split(base) {}
void operator()(const X_monotone_curve_2& cv, const Point_2 & p,
X_monotone_curve_2& c1, X_monotone_curve_2& c2) const
{
X_monotone_curve_2& c1, X_monotone_curve_2& c2) const {
m_base_split(cv.base(), p.base(), c1.base(), c2.base());
const Curve_data& cv_data = cv.data();
c1.set_data(Curve_data(cv_data.arr(), Halfedge_handle(), cv_data.bc(),
@ -259,8 +249,7 @@ public:
* \param cv The curve.
* \return The left endpoint.
*/
Point_2 operator()(const X_monotone_curve_2 & cv) const
{
Point_2 operator()(const X_monotone_curve_2 & cv) const {
if (cv.data().halfedge() == Halfedge_handle())
return (Point_2(m_base(cv.base())));
@ -272,8 +261,7 @@ public:
};
/*! Get a Construct_min_vertex_2 functor object. */
Construct_min_vertex_2 construct_min_vertex_2_object() const
{
Construct_min_vertex_2 construct_min_vertex_2_object() const {
return Construct_min_vertex_2(this->m_base_traits->
construct_min_vertex_2_object());
}
@ -285,15 +273,14 @@ public:
public:
Construct_max_vertex_2(const Base_Construct_max_vertex_2& base) :
m_base(base)
m_base(base)
{}
/*! Obtain the right endpoint of the x-monotone curve (segment).
* \param cv The curve.
* \return The right endpoint.
*/
Point_2 operator()(const X_monotone_curve_2& cv) const
{
Point_2 operator()(const X_monotone_curve_2& cv) const {
if (cv.data().halfedge() == Halfedge_handle())
return (Point_2(m_base(cv.base())));
@ -304,8 +291,7 @@ public:
};
/*! Get a Construct_min_vertex_2 functor object. */
Construct_max_vertex_2 construct_max_vertex_2_object() const
{
Construct_max_vertex_2 construct_max_vertex_2_object() const {
return Construct_max_vertex_2(this->m_base_traits->
construct_max_vertex_2_object());
}
@ -321,8 +307,7 @@ public:
* \param cv The curve.
* \return The left endpoint.
*/
Comparison_result operator()(const Point_2& p1, const Point_2& p2) const
{
Comparison_result operator()(const Point_2& p1, const Point_2& p2) const {
const Point_data& inf1 = p1.data();
const Point_data& inf2 = p2.data();
@ -390,8 +375,7 @@ public:
};
/*! Obtain a Construct_min_vertex_2 functor object. */
Compare_y_near_boundary_2 compare_y_near_boundary_2_object() const
{
Compare_y_near_boundary_2 compare_y_near_boundary_2_object() const {
return Compare_y_near_boundary_2(this->m_base_traits->
compare_y_near_boundary_2_object()
);
@ -429,8 +413,7 @@ public:
};
/*! Obtain a Construct_min_vertex_2 functor object. */
Parameter_space_in_y_2 parameter_space_in_y_2_object() const
{
Parameter_space_in_y_2 parameter_space_in_y_2_object() const {
return Parameter_space_in_y_2(this->m_base_traits->
parameter_space_in_y_2_object());
}
@ -462,8 +445,7 @@ public:
};
/*! Obtain a Construct_min_vertex_2 functor object. */
Compare_x_near_boundary_2 compare_x_near_boundary_2_object() const
{
Compare_x_near_boundary_2 compare_x_near_boundary_2_object() const {
return Compare_x_near_boundary_2(this->m_base_traits->
compare_x_near_boundary_2_object());
}

View File

@ -7,11 +7,12 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ophir Setter <ophir.setter@cs.tau.ac.il>
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ophir Setter <ophir.setter@cs.tau.ac.il>
// Efi Fogel <efifogel@gmail.com>
#ifndef CGAL_BSO_2_GPS_AGG_OP_H
#define CGAL_BSO_2_GPS_AGG_OP_H
#ifndef CGAL_GPS_AGG_OP_H
#define CGAL_GPS_AGG_OP_H
#include <CGAL/license/Boolean_set_operations_2.h>
@ -19,8 +20,8 @@
*
* The class Gps_agg_op is responsible for aggregated Boolean set operations
* depending on a visitor template parameter. It uses the surface-sweep
* algorithm from the arrangement packages to overlay all the polygon sets, and
* then it uses a BFS that determines which of the faces is contained in the
* algorithm from the surface-sweep package to overlay all the polygon sets, and
* then it uses a BFS that determines which of the faces are contained in the
* result using the visitor.
*/
@ -37,31 +38,31 @@
namespace CGAL {
template <typename Arrangement_, typename BfsVisitor>
template <typename Arrangement_, typename BfsVisitor, template <typename, typename, typename> class SweepVisitor>
class Gps_agg_op {
typedef Arrangement_ Arrangement_2;
typedef BfsVisitor Bfs_visitor;
using Arrangement_2 = Arrangement_;
using Bfs_visitor = BfsVisitor;
typedef typename Arrangement_2::Traits_adaptor_2 Geometry_traits_2;
typedef typename Arrangement_2::Topology_traits Topology_traits;
using Geometry_traits_2 = typename Arrangement_2::Traits_adaptor_2;
using Topology_traits = typename Arrangement_2::Topology_traits;
typedef Arrangement_2 Arr;
typedef Geometry_traits_2 Gt2;
typedef Topology_traits Tt;
using Arr = Arrangement_2;
using Gt2 = Geometry_traits_2;
using Tt = Topology_traits;
typedef typename Gt2::Curve_const_iterator Curve_const_iterator;
typedef Gps_agg_meta_traits<Arr> Mgt2;
typedef typename Mgt2::Curve_data Curve_data;
typedef typename Mgt2::X_monotone_curve_2 Meta_X_monotone_curve_2;
using Curve_const_iterator = typename Gt2::Curve_const_iterator;
using Mgt2 = Gps_agg_meta_traits<Arr>;
using Curve_data = typename Mgt2::Curve_data;
using Meta_X_monotone_curve_2 = typename Mgt2::X_monotone_curve_2;
typedef typename Arr::Halfedge_handle Halfedge_handle;
typedef typename Arr::Halfedge_iterator Halfedge_iterator;
typedef typename Arr::Face_handle Face_handle;
typedef typename Arr::Edge_iterator Edge_iterator;
typedef typename Arr::Vertex_handle Vertex_handle;
typedef typename Arr::Allocator Allocator;
using Halfedge_handle = typename Arr::Halfedge_handle;
using Halfedge_iterator = typename Arr::Halfedge_iterator;
using Face_handle = typename Arr::Face_handle;
using Edge_iterator = typename Arr::Edge_iterator;
using Vertex_handle = typename Arr::Vertex_handle;
using Allocator = typename Arr::Allocator;
typedef std::pair<Arr*, std::vector<Vertex_handle> *> Arr_entry;
using Arr_entry = std::pair<Arr*, std::vector<Vertex_handle> *>;
// We obtain a proper helper type from the topology traits of the arrangement.
// However, the arrangement is parametrized with the Gt2 geometry traits,
@ -70,21 +71,16 @@ class Gps_agg_op {
// We cannot parameterized the arrangement with the Mgt2 geometry
// traits to start with, because it extends the curve type with arrangement
// dependent types. (It is parameterized with the arrangement type.)
typedef Indexed_event<Mgt2, Arr, Allocator> Event;
typedef Arr_construction_subcurve<Mgt2, Event, Allocator>
Subcurve;
typedef typename Tt::template Construction_helper<Event, Subcurve>
Helper_tmp;
typedef typename Helper_tmp::template rebind<Mgt2, Arr, Event, Subcurve>::other
Helper;
typedef Gps_agg_op_visitor<Helper, Arr> Visitor;
typedef Gps_agg_op_surface_sweep_2<Arr, Visitor> Surface_sweep_2;
using Event = Indexed_event<Mgt2, Arr, Allocator>;
using Subcurve = Arr_construction_subcurve<Mgt2, Event, Allocator>;
using Helper_tmp = typename Tt::template Construction_helper<Event, Subcurve>;
using Helper = typename Helper_tmp::template rebind<Mgt2, Arr, Event, Subcurve>::other;
using Visitor = SweepVisitor<Helper, Arr, Default>;
using Surface_sweep_2 = Gps_agg_op_surface_sweep_2<Arr, Visitor>;
typedef Unique_hash_map<Halfedge_handle, unsigned int>
Edges_hash;
typedef Unique_hash_map<Face_handle, unsigned int> Faces_hash;
typedef Gps_bfs_scanner<Arr, Bfs_visitor> Bfs_scanner;
using Edges_hash = Unique_hash_map<Halfedge_handle, std::size_t>;
using Faces_hash = Unique_hash_map<Face_handle, std::size_t>;
using Bfs_scanner = Gps_bfs_scanner<Arr, Bfs_visitor>;
protected:
Arr* m_arr;
@ -95,7 +91,7 @@ protected:
Faces_hash m_faces_hash; // maps face to its IC (inside count)
public:
/*! Constructor. */
/*! constructs. */
Gps_agg_op(Arr& arr, std::vector<Vertex_handle>& vert_vec, const Gt2& tr) :
m_arr(&arr),
m_traits(new Mgt2(tr)),
@ -103,40 +99,40 @@ public:
m_surface_sweep(m_traits, &m_visitor)
{}
void sweep_arrangements(unsigned int lower, unsigned int upper,
unsigned int jump, std::vector<Arr_entry>& arr_vec)
{
std::list<Meta_X_monotone_curve_2> curves_list;
unsigned int n_inf_pgn = 0; // number of infinite polygons (arrangement
std::pair<std::size_t, std::size_t>
prepare(std::size_t lower, std::size_t upper, std::size_t jump,
std::vector<Arr_entry>& arr_vec, std::list<Meta_X_monotone_curve_2>& curves_list) {
std::size_t n_inf_pgn = 0; // number of infinite polygons (arrangement
// with a contained unbounded face
unsigned int n_pgn = 0; // number of polygons (arrangements)
unsigned int i;
for (i = lower; i <= upper; i += jump, ++n_pgn) {
std::size_t n_pgn = 0; // number of polygons (arrangements)
for (auto i = lower; i <= upper; i += jump, ++n_pgn) {
// The BFS scan (after the loop) starts in the reference face,
// so we count the number of polygons that contain the reference face.
Arr* arr = (arr_vec[i]).first;
if (arr->reference_face()->contained()) ++n_inf_pgn;
Edge_iterator itr = arr->edges_begin();
for(; itr != arr->edges_end(); ++itr) {
for (auto itr = arr->edges_begin(); itr != arr->edges_end(); ++itr) {
// take only relevant edges (which separate between contained and
// non-contained faces.
Halfedge_iterator he = itr;
if(he->face()->contained() == he->twin()->face()->contained())
continue;
if ((Arr_halfedge_direction)he->direction() == ARR_RIGHT_TO_LEFT)
he = he->twin();
Halfedge_handle he = itr;
if (he->face()->contained() == he->twin()->face()->contained()) continue;
if ((Arr_halfedge_direction)he->direction() == ARR_RIGHT_TO_LEFT) he = he->twin();
Curve_data cv_data(arr, he, 1, 0);
curves_list.push_back(Meta_X_monotone_curve_2(he->curve(), cv_data));
}
}
return std::make_pair(n_inf_pgn, n_pgn);
}
m_surface_sweep.sweep(curves_list.begin(), curves_list.end(),
lower, upper, jump, arr_vec);
/*! sweeps the plane without interceptions.
*/
void sweep_arrangements(std::size_t lower, std::size_t upper, std::size_t jump,
std::vector<Arr_entry>& arr_vec) {
std::size_t n_inf_pgn, n_pgn;
std::list<Meta_X_monotone_curve_2> curves_list;
std::tie(n_inf_pgn, n_pgn) = prepare(lower, upper, jump, arr_vec, curves_list);
m_surface_sweep.sweep(curves_list.begin(), curves_list.end(), lower, upper, jump, arr_vec);
m_faces_hash[m_arr->reference_face()] = n_inf_pgn;
Bfs_visitor visitor(&m_edges_hash, &m_faces_hash, n_pgn);
visitor.visit_ubf(m_arr->faces_begin(), n_inf_pgn);
@ -145,7 +141,69 @@ public:
visitor.after_scan(*m_arr);
}
/*! Destruct.
/*! sweeps the plane without interceptions, but stop when an intersection occurs.
*/
bool sweep_intercept_arrangements(std::size_t lower, std::size_t upper, std::size_t jump,
std::vector<Arr_entry>& arr_vec) {
std::size_t n_inf_pgn, n_pgn;
std::list<Meta_X_monotone_curve_2> curves_list;
std::tie(n_inf_pgn, n_pgn) = prepare(lower, upper, jump, arr_vec, curves_list);
auto res = m_surface_sweep.sweep_intercept(curves_list.begin(), curves_list.end(), lower, upper, jump, arr_vec);
if (res) return true;
m_faces_hash[m_arr->reference_face()] = n_inf_pgn;
Bfs_visitor visitor(&m_edges_hash, &m_faces_hash, n_pgn);
visitor.visit_ubf(m_arr->faces_begin(), n_inf_pgn);
Bfs_scanner scanner(visitor);
scanner.scan(*m_arr);
visitor.after_scan(*m_arr);
return false;
}
template <typename InputIterator>
std::size_t prepare2(InputIterator begin, InputIterator end, std::list<Meta_X_monotone_curve_2>& curves_list) {
std::size_t n_inf_pgn = 0; // number of infinite polygons (arrangement
// with a contained unbounded face
for (auto it = begin; it != end; ++it) {
// The BFS scan (after the loop) starts in the reference face,
// so we count the number of polygons that contain the reference face.
Arr* arr = it->first;
if (arr->reference_face()->contained()) ++n_inf_pgn;
for (auto ite = arr->edges_begin(); ite != arr->edges_end(); ++ite) {
// take only relevant edges (which separate between contained and
// non-contained faces.
Halfedge_handle he = ite;
if (he->face()->contained() == he->twin()->face()->contained()) continue;
if ((Arr_halfedge_direction)he->direction() == ARR_RIGHT_TO_LEFT) he = he->twin();
Curve_data cv_data(arr, he, 1, 0);
curves_list.push_back(Meta_X_monotone_curve_2(he->curve(), cv_data));
}
}
return n_inf_pgn;
}
/*! sweeps the plane without interceptions, but stop when an intersection occurs.
*/
template <typename InputIterator>
bool sweep_intercept_arrangements2(InputIterator begin, InputIterator end) {
std::list<Meta_X_monotone_curve_2> curves_list;
auto n_inf_pgn = prepare2(begin, end, curves_list);
auto res = m_surface_sweep.sweep_intercept2(curves_list.begin(), curves_list.end(), begin, end);
if (res) return true;
m_faces_hash[m_arr->reference_face()] = n_inf_pgn;
std::size_t n_pgn = std::distance(begin, end); // number of polygons (arrangements)
Bfs_visitor visitor(&m_edges_hash, &m_faces_hash, n_pgn);
visitor.visit_ubf(m_arr->faces_begin(), n_inf_pgn);
Bfs_scanner scanner(visitor);
scanner.scan(*m_arr);
visitor.after_scan(*m_arr);
return false;
}
/*! destructs.
*/
~Gps_agg_op() { delete m_traits; }
};

View File

@ -7,11 +7,12 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efifogel@gmail.com>
#ifndef CGAL_BSO_2_GSP_AGG_OP_SURFACE_SWEEP_2_H
#define CGAL_BSO_2_GSP_AGG_OP_SURFACE_SWEEP_2_H
#ifndef CGAL_GSP_AGG_OP_SURFACE_SWEEP_2_H
#define CGAL_GSP_AGG_OP_SURFACE_SWEEP_2_H
#include <vector>
@ -27,34 +28,34 @@ namespace Ss2 = Surface_sweep_2;
template <typename Arrangement_, typename Visitor_>
class Gps_agg_op_surface_sweep_2 : public Ss2::Surface_sweep_2<Visitor_> {
public:
typedef Arrangement_ Arrangement_2;
typedef Visitor_ Visitor;
using Arrangement_2 = Arrangement_;
using Visitor = Visitor_;
typedef typename Visitor::Geometry_traits_2 Geometry_traits_2;
using Geometry_traits_2 = typename Visitor::Geometry_traits_2;
typedef Arrangement_2 Arr;
typedef Geometry_traits_2 Gt2;
using Arr = Arrangement_2;
using Gt2 = Geometry_traits_2;
typedef typename Gt2::Point_2 Point_2;
typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2;
using Point_2 = typename Gt2::Point_2;
using X_monotone_curve_2 = typename Gt2::X_monotone_curve_2;
typedef typename Arr::Vertex_handle Vertex_handle;
typedef typename Arr::Halfedge_handle Halfedge_handle;
using Vertex_handle = typename Arr::Vertex_handle;
using Halfedge_handle = typename Arr::Halfedge_handle;
typedef std::pair<Arr*, std::vector<Vertex_handle> *> Arr_entry;
using Arr_entry = std::pair<Arr*, std::vector<Vertex_handle> *>;
typedef Ss2::Surface_sweep_2<Visitor> Base;
using Base = Ss2::Surface_sweep_2<Visitor>;
typedef typename Visitor::Event Event;
typedef typename Visitor::Subcurve Subcurve;
using Event = typename Visitor::Event;
using Subcurve = typename Visitor::Subcurve;
typedef typename Base::Event_queue_iterator EventQueueIter;
typedef typename Event::Subcurve_iterator EventCurveIter;
using EventQueueIter = typename Base::Event_queue_iterator;
using EventCurveIter = typename Event::Subcurve_iterator;
typedef typename Event::Attribute Attribute;
using Attribute = typename Event::Attribute;
typedef std::list<Subcurve*> SubCurveList;
typedef typename SubCurveList::iterator SubCurveListIter;
using SubCurveList = std::list<Subcurve*>;
using SubCurveListIter = typename SubCurveList::iterator;
public:
/*! Constructor.
@ -70,21 +71,17 @@ public:
Base(traits, visitor)
{}
/*! Perform the sweep. */
template <class CurveInputIterator>
void sweep(CurveInputIterator curves_begin, CurveInputIterator curves_end,
unsigned int lower, unsigned int upper, unsigned int jump,
std::vector<Arr_entry>& arr_vec)
{
template <typename CurveInputIterator>
void pre_process(CurveInputIterator curves_begin, CurveInputIterator curves_end,
std::size_t lower, std::size_t upper, std::size_t jump,
std::vector<Arr_entry>& arr_vec) {
CGAL_assertion(this->m_queue->empty() && this->m_statusLine.size() == 0);
typedef Unique_hash_map<Vertex_handle, Event*> Vertices_map;
typedef typename Gt2::Compare_xy_2 Compare_xy_2;
using Vertices_map = Unique_hash_map<Vertex_handle, Event*>;
using Compare_xy_2 = typename Gt2::Compare_xy_2;
this->m_visitor->before_sweep();
// Allocate all of the Subcurve objects as one block.
this->m_num_of_subCurves =
static_cast<unsigned int>(std::distance(curves_begin, curves_end));
this->m_num_of_subCurves = static_cast<unsigned int>(std::distance(curves_begin, curves_end));
if (this->m_num_of_subCurves > 0)
this->m_subCurves =
this->m_subCurveAlloc.allocate(this->m_num_of_subCurves);
@ -95,9 +92,9 @@ public:
Vertices_map vert_map;
Vertex_handle vh;
Vertex_handle invalid_v;
unsigned int i = lower;
unsigned int n = static_cast<unsigned int>((arr_vec[i].second)->size());
unsigned int j;
std::size_t i = lower;
auto n = (arr_vec[i].second)->size();
std::size_t j;
EventQueueIter q_iter;
bool first = true;
Attribute event_type;
@ -135,7 +132,7 @@ public:
for (i += jump; i <= upper; i += jump) {
// Merge the vertices of the other vectors into the existing queue.
q_iter = this->m_queue->begin();
n = static_cast<unsigned int>((arr_vec[i].second)->size());
n = (arr_vec[i].second)->size();
for (j = 0; j < n && (vh = (*(arr_vec[i].second))[j]) != invalid_v; j++) {
event_type = _type_of_vertex(vh);
@ -170,7 +167,7 @@ public:
// Go over all curves (which are associated with halfedges) and associate
// them with the events we have just created.
unsigned int index = 0;
std::size_t index = 0;
CurveInputIterator iter;
Halfedge_handle he;
Event* e_left;
@ -194,9 +191,10 @@ public:
}
// Create the subcurve object.
typedef decltype(this->m_subCurveAlloc) Subcurve_alloc;
std::allocator_traits<Subcurve_alloc>::construct(this->m_subCurveAlloc, this->m_subCurves + index,
this->m_masterSubcurve);
using Subcurve_alloc = decltype(this->m_subCurveAlloc);
std::allocator_traits<Subcurve_alloc>::construct(this->m_subCurveAlloc,
this->m_subCurves + index,
this->m_masterSubcurve);
(this->m_subCurves + index)->init(*iter);
(this->m_subCurves + index)->set_left_event(e_left);
(this->m_subCurves + index)->set_right_event(e_right);
@ -204,13 +202,174 @@ public:
e_right->add_curve_to_left(this->m_subCurves + index);
this->_add_curve_to_right(e_left, this->m_subCurves + index);
}
}
// Perform the sweep:
template <typename CurveInputIterator, typename InputIterator>
void pre_process2(CurveInputIterator curves_begin, CurveInputIterator curves_end,
InputIterator begin, InputIterator end) {
CGAL_assertion(this->m_queue->empty() && this->m_statusLine.size() == 0);
using Vertices_map = Unique_hash_map<Vertex_handle, Event*>;
using Compare_xy_2 = typename Gt2::Compare_xy_2;
// Allocate all of the Subcurve objects as one block.
this->m_num_of_subCurves = std::distance(curves_begin, curves_end);
if (this->m_num_of_subCurves > 0)
this->m_subCurves =
this->m_subCurveAlloc.allocate(this->m_num_of_subCurves);
// Initialize the event queue using the vertices vectors. Note that these
// vertices are already sorted, we simply have to merge them
Vertices_map vert_map;
Vertex_handle vh;
Vertex_handle invalid_v;
// std::size_t i = lower;
auto it = begin;
auto n = it->second->size();
std::size_t j;
EventQueueIter q_iter;
bool first = true;
Attribute event_type;
Event* event;
for (j = 0; j < n && (vh = (*(it->second))[j]) != invalid_v; j++) {
// Insert the vertices of the first vector one after the other.
event_type = _type_of_vertex(vh);
if (event_type == Event::DEFAULT) continue;
event = this->_allocate_event(vh->point(), event_type,
ARR_INTERIOR, ARR_INTERIOR);
// \todo When the boolean set operations are extended to support
// unbounded curves, we will need here a special treatment.
#ifndef CGAL_ARRANGEMENT_ON_SURFACE_2_H
event->set_finite();
#endif
if (! first) {
q_iter = this->m_queue->insert_after(q_iter, event);
}
else {
q_iter = this->m_queue->insert(event);
first = false;
}
vert_map[vh] = event;
}
Comparison_result res = LARGER;
Compare_xy_2 comp_xy = this->m_traits->compare_xy_2_object();
EventQueueIter q_end = this->m_queue->end();
for (++it; it != end; ++it) {
// Merge the vertices of the other vectors into the existing queue.
q_iter = this->m_queue->begin();
n = it->second->size();
for (j = 0; j < n && (vh = (*(it->second))[j]) != invalid_v; j++) {
event_type = _type_of_vertex(vh);
if (event_type == Event::DEFAULT) continue;
while ((q_iter != q_end) &&
(res = comp_xy(vh->point(), (*q_iter)->point())) == LARGER)
{
++q_iter;
}
if (res == SMALLER || q_iter == q_end) {
event = this->_allocate_event(vh->point(), event_type,
ARR_INTERIOR, ARR_INTERIOR);
// \todo When the boolean set operations are extended to support
// unbounded curves, we will need here a special treatment.
#ifndef CGAL_ARRANGEMENT_ON_SURFACE_2_H
event->set_finite();
#endif
this->m_queue->insert_before(q_iter, event);
vert_map[vh] = event;
}
else if (res == EQUAL) {
// In this case q_iter points to an event already associated with
// the vertex, so we just update the map:
vert_map[vh] = *q_iter;
}
}
}
// Go over all curves (which are associated with halfedges) and associate
// them with the events we have just created.
std::size_t index = 0;
CurveInputIterator iter;
Halfedge_handle he;
Event* e_left;
Event* e_right;
for (iter = curves_begin; iter != curves_end; ++iter, index++) {
// Get the events associated with the end-vertices of the current
// halfedge.
he = iter->data().halfedge();
CGAL_assertion(vert_map.is_defined(he->source()));
CGAL_assertion(vert_map.is_defined(he->target()));
if ((Arr_halfedge_direction)he->direction() == ARR_LEFT_TO_RIGHT) {
e_left = vert_map[he->source()];
e_right = vert_map[he->target()];
}
else {
e_left = vert_map[he->target()];
e_right = vert_map[he->source()];
}
// Create the subcurve object.
using Subcurve_alloc = decltype(this->m_subCurveAlloc);
std::allocator_traits<Subcurve_alloc>::construct(this->m_subCurveAlloc,
this->m_subCurves + index,
this->m_masterSubcurve);
(this->m_subCurves + index)->init(*iter);
(this->m_subCurves + index)->set_left_event(e_left);
(this->m_subCurves + index)->set_right_event(e_right);
e_right->add_curve_to_left(this->m_subCurves + index);
this->_add_curve_to_right(e_left, this->m_subCurves + index);
}
}
/*! Perform the sweep. */
template <typename CurveInputIterator>
void sweep(CurveInputIterator curves_begin, CurveInputIterator curves_end,
std::size_t lower, std::size_t upper, std::size_t jump, std::vector<Arr_entry>& arr_vec) {
this->m_visitor->before_sweep();
pre_process(curves_begin, curves_end,lower, upper, jump, arr_vec);
this->_sweep();
this->_complete_sweep();
this->m_visitor->after_sweep();
}
return;
/*! Perform the sweep. */
template <typename CurveInputIterator>
bool sweep_intercept(CurveInputIterator curves_begin, CurveInputIterator curves_end,
std::size_t lower, std::size_t upper, std::size_t jump, std::vector<Arr_entry>& arr_vec) {
this->m_visitor->before_sweep();
pre_process(curves_begin, curves_end,lower, upper, jump, arr_vec);
this->_sweep();
this->_complete_sweep();
this->m_visitor->after_sweep();
return this->m_visitor->found_intersection();
}
/*! Perform the sweep. */
template <typename CurveInputIterator, typename InputIterator>
bool sweep_intercept2(CurveInputIterator curves_begin, CurveInputIterator curves_end,
InputIterator begin, InputIterator end) {
this->m_visitor->before_sweep();
pre_process2(curves_begin, curves_end, begin, end);
this->_sweep();
this->_complete_sweep();
this->m_visitor->after_sweep();
return this->m_visitor->found_intersection();
}
private:
@ -218,8 +377,7 @@ private:
* Check if the given vertex is an endpoint of an edge we are going
* to use in the sweep.
*/
Attribute _type_of_vertex(Vertex_handle v)
{
Attribute _type_of_vertex(Vertex_handle v) {
typename Arr::Halfedge_around_vertex_circulator first, circ;
circ = first = v->incident_halfedges();
@ -232,7 +390,6 @@ private:
else return (Event::LEFT_END);
}
++circ;
} while (circ != first);
// If we reached here, we should not keep this vertex.

View File

@ -7,12 +7,12 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efifogel@gmail.com>
#ifndef CGAL_BSO_2_GSP_AGG_OP_VISITOR_H
#define CGAL_BSO_2_GSP_AGG_OP_VISITOR_H
#ifndef CGAL_GSP_AGG_OP_VISITOR_H
#define CGAL_GSP_AGG_OP_VISITOR_H
#include <CGAL/license/Boolean_set_operations_2.h>
@ -31,33 +31,29 @@ class Gps_agg_op_base_visitor :
Helper_,
typename Default::Get<Visitor_, Gps_agg_op_base_visitor<Helper_,
Arrangement_,
Visitor_> >::type>
{
Visitor_>>::type> {
public:
typedef Helper_ Helper;
typedef Arrangement_ Arrangement_2;
using Helper = Helper_;
using Arrangement_2 = Arrangement_;
typedef typename Helper::Geometry_traits_2 Geometry_traits_2;
typedef typename Helper::Event Event;
typedef typename Helper::Subcurve Subcurve;
using Geometry_traits_2 = typename Helper::Geometry_traits_2;
using Event = typename Helper::Event;
using Subcurve = typename Helper::Subcurve;
private:
typedef Geometry_traits_2 Gt2;
typedef Arrangement_2 Arr;
typedef Gps_agg_op_base_visitor<Helper, Arr, Visitor_>
Self;
typedef typename Default::Get<Visitor_, Self>::type Visitor;
typedef Arr_construction_ss_visitor<Helper, Visitor> Base;
using Gt2 = Geometry_traits_2;
using Arr = Arrangement_2;
using Self = Gps_agg_op_base_visitor<Helper, Arr, Visitor_>;
using Visitor = typename Default::Get<Visitor_, Self>::type;
using Base = Arr_construction_ss_visitor<Helper, Visitor>;
public:
typedef typename Arr::Halfedge_handle Halfedge_handle;
typedef typename Arr::Vertex_handle Vertex_handle;
typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Gt2::Point_2 Point_2;
using Halfedge_handle = typename Arr::Halfedge_handle;
using Vertex_handle = typename Arr::Vertex_handle;
using X_monotone_curve_2 = typename Gt2::X_monotone_curve_2;
using Point_2 = typename Gt2::Point_2;
typedef Unique_hash_map<Halfedge_handle, unsigned int>
Edges_hash;
using Edges_hash = Unique_hash_map<Halfedge_handle, std::size_t>;
protected:
Edges_hash* m_edges_hash; // maps halfedges to their BC (coundary counter)
@ -72,8 +68,7 @@ public:
// TODO add mpl-warning
virtual Halfedge_handle insert_in_face_interior(const X_monotone_curve_2& cv,
Subcurve* sc)
{
Subcurve* sc) {
Halfedge_handle he = Base::insert_in_face_interior(cv, sc);
insert_edge_to_hash(he, cv);
return he;
@ -83,8 +78,7 @@ public:
Halfedge_handle hhandle,
Halfedge_handle prev,
Subcurve* sc,
bool& new_face_created)
{
bool& new_face_created) {
Halfedge_handle res_he =
Base::insert_at_vertices(cv, hhandle, prev, sc, new_face_created);
insert_edge_to_hash(res_he, cv);
@ -93,8 +87,7 @@ public:
virtual Halfedge_handle insert_from_right_vertex(const X_monotone_curve_2& cv,
Halfedge_handle he,
Subcurve* sc)
{
Subcurve* sc) {
Halfedge_handle res_he = Base::insert_from_right_vertex(cv, he, sc);
insert_edge_to_hash(res_he, cv);
return res_he;
@ -102,16 +95,14 @@ public:
virtual Halfedge_handle insert_from_left_vertex(const X_monotone_curve_2& cv,
Halfedge_handle he,
Subcurve* sc)
{
Subcurve* sc) {
Halfedge_handle res_he = Base::insert_from_left_vertex(cv, he, sc);
insert_edge_to_hash(res_he, cv);
return res_he;
}
private:
void insert_edge_to_hash(Halfedge_handle he, const X_monotone_curve_2& cv)
{
void insert_edge_to_hash(Halfedge_handle he, const X_monotone_curve_2& cv) {
const Comparison_result he_dir =
((Arr_halfedge_direction)he->direction() == ARR_LEFT_TO_RIGHT) ?
SMALLER : LARGER;
@ -133,54 +124,53 @@ private:
template <typename Helper_, typename Arrangement_, typename Visitor_ = Default>
class Gps_agg_op_visitor :
public Gps_agg_op_base_visitor<Helper_, Arrangement_,
Gps_agg_op_visitor<Helper_, Arrangement_,
Visitor_> >
{
public Gps_agg_op_base_visitor<
Helper_, Arrangement_,
typename Default::Get<Visitor_,
Gps_agg_op_visitor<Helper_, Arrangement_, Visitor_>>::type> {
public:
typedef Helper_ Helper;
typedef Arrangement_ Arrangement_2;
using Helper = Helper_;
using Arrangement_2 = Arrangement_;
typedef typename Helper::Geometry_traits_2 Geometry_traits_2;
typedef typename Helper::Event Event;
typedef typename Helper::Subcurve Subcurve;
using Geometry_traits_2 = typename Helper::Geometry_traits_2;
using Event = typename Helper::Event;
using Subcurve = typename Helper::Subcurve;
private:
typedef Geometry_traits_2 Gt2;
typedef Arrangement_2 Arr;
using Gt2 = Geometry_traits_2;
using Arr = Arrangement_2;
typedef Gps_agg_op_visitor<Helper, Arr, Visitor_> Self;
typedef typename Default::Get<Visitor_, Self>::type Visitor;
typedef Gps_agg_op_base_visitor<Helper, Arr, Visitor> Base;
using Self = Gps_agg_op_visitor<Helper, Arr, Visitor_>;
using Visitor = typename Default::Get<Visitor_, Self>::type;
using Base = Gps_agg_op_base_visitor<Helper, Arr, Visitor>;
public:
typedef typename Base::Halfedge_handle Halfedge_handle;
typedef typename Base::Vertex_handle Vertex_handle;
typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Gt2::Point_2 Point_2;
using Edges_hash = typename Base::Edges_hash;
using Halfedge_handle = typename Base::Halfedge_handle;
using Vertex_handle = typename Base::Vertex_handle;
using X_monotone_curve_2 = typename Gt2::X_monotone_curve_2;
using Point_2 = typename Gt2::Point_2;
protected:
unsigned int m_event_count; // The number of events so far.
std::size_t m_event_count; // The number of events so far.
std::vector<Vertex_handle>* m_vertices_vec; // The vertices, sorted in
// ascending order.
public:
Gps_agg_op_visitor(Arr* arr, typename Base::Edges_hash* hash,
Gps_agg_op_visitor(Arr* arr, Edges_hash* hash,
std::vector<Vertex_handle>* vertices_vec) :
Base(arr, hash),
m_event_count(0),
m_vertices_vec(vertices_vec)
{}
void before_handle_event(Event* event)
{
void before_handle_event(Event* event) {
event->set_index(m_event_count);
m_event_count++;
}
virtual Halfedge_handle
insert_in_face_interior(const X_monotone_curve_2& cv, Subcurve* sc)
{
insert_in_face_interior(const X_monotone_curve_2& cv, Subcurve* sc) {
Halfedge_handle res_he = Base::insert_in_face_interior(cv, sc);
// We now have a halfedge whose source vertex is associated with the
@ -198,8 +188,7 @@ public:
virtual Halfedge_handle insert_from_right_vertex(const X_monotone_curve_2& cv,
Halfedge_handle he,
Subcurve* sc)
{
Subcurve* sc) {
Halfedge_handle res_he = Base::insert_from_right_vertex(cv, he, sc);
// We now have a halfedge whose target vertex is associated with the
@ -213,9 +202,8 @@ public:
virtual Halfedge_handle insert_from_left_vertex(const X_monotone_curve_2& cv,
Halfedge_handle he,
Subcurve* sc)
{
Halfedge_handle res_he = Base::insert_from_left_vertex(cv, he, sc);
Subcurve* sc) {
Halfedge_handle res_he = Base::insert_from_left_vertex(cv, he, sc);
// We now have a halfedge whose target vertex is associated with the
// current event(we have already dealt with its source vertex).
@ -223,18 +211,16 @@ public:
CGAL_assertion((Arr_halfedge_direction)res_he->direction() ==
ARR_LEFT_TO_RIGHT);
_insert_vertex (curr_event, res_he->target());
_insert_vertex(curr_event, res_he->target());
return res_he;
}
private:
void _insert_vertex(const Event* event, Vertex_handle v)
{
const unsigned int index = event->index();
void _insert_vertex(const Event* event, Vertex_handle v) {
const auto index = event->index();
if (index >= m_vertices_vec->size()) m_vertices_vec->resize(2 * (index + 1));
(*m_vertices_vec)[index] = v;
}
};
} // namespace CGAL

View File

@ -8,90 +8,83 @@
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ophir Setter <ophir.setter@cs.tau.ac.il>
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ophir Setter <ophir.setter@cs.tau.ac.il>
#ifndef CGAL_GPS_BPS_BASE_VISITOR_H
#define CGAL_GPS_BPS_BASE_VISITOR_H
#include <CGAL/license/Boolean_set_operations_2.h>
#include <CGAL/Unique_hash_map.h>
namespace CGAL {
//! Gps_bfs_base_visitor
/*! This is a base class for all visitors that are responsible for merging
polygon sets.
We use DerivedVisitor for static polymorphism for using contained_criteria
which determines if we should mark the face as contained given the inside
count of the face.
*/
template <class Arrangement_, class DerivedVisitor>
class Gps_bfs_base_visitor
{
typedef Arrangement_ Arrangement;
typedef typename Arrangement::Face_iterator Face_iterator;
typedef typename Arrangement::Halfedge_iterator Halfedge_iterator;
* polygon sets.
* We use DerivedVisitor for static polymorphism for using contained_criteria
* which determines if we should mark the face as contained given the inside
* count of the face.
*/
template <typename Arrangement_, typename DerivedVisitor>
class Gps_bfs_base_visitor {
using Arrangement = Arrangement_;
using Face_iterator = typename Arrangement::Face_iterator;
using Halfedge_iterator = typename Arrangement::Halfedge_iterator;
public:
typedef Unique_hash_map<Halfedge_iterator, unsigned int> Edges_hash;
typedef Unique_hash_map<Face_iterator, unsigned int> Faces_hash;
using Edges_hash = Unique_hash_map<Halfedge_iterator, std::size_t>;
using Faces_hash = Unique_hash_map<Face_iterator, std::size_t>;
protected:
Edges_hash* m_edges_hash;
Faces_hash* m_faces_hash;
unsigned int m_num_of_polygons; // number of polygons
Edges_hash* m_edges_hash;
Faces_hash* m_faces_hash;
std::size_t m_num_of_polygons; // number of polygons
public:
Gps_bfs_base_visitor(Edges_hash* edges_hash,
Faces_hash* faces_hash,
unsigned int n_pgn):
std::size_t n_pgn):
m_edges_hash(edges_hash),
m_faces_hash(faces_hash),
m_num_of_polygons(n_pgn)
{}
//! discovered_face
/*! discovered_face is called by Gps_bfs_scanner when it reveals a new face
during a BFS scan. In the BFS traversal we are going from old_face to
new_face through the half-edge he.
\param old_face The face that was already revealed
\param new_face The face that we have just now revealed
\param he The half-edge that is used to traverse between them.
*/
//! discovered_face
/*! discovered_face is called by Gps_bfs_scanner when it reveals a new face
* during a BFS scan. In the BFS traversal we are going from old_face to
* new_face through the half-edge he.
* \param old_face The face that was already revealed
* \param new_face The face that we have just now revealed
* \param he The half-edge that is used to traverse between them.
*/
void discovered_face(Face_iterator old_face,
Face_iterator new_face,
Halfedge_iterator he)
{
unsigned int ic = compute_ic(old_face, new_face, he);
Halfedge_iterator he) {
std::size_t ic = compute_ic(old_face, new_face, he);
if (static_cast<DerivedVisitor*>(this)->contained_criteria(ic))
new_face->set_contained(true);
}
// mark the unbounded_face (true iff contained)
void visit_ubf(Face_iterator ubf, unsigned int ubf_ic)
{
void visit_ubf(Face_iterator ubf, std::size_t ubf_ic) {
CGAL_assertion(ubf->is_unbounded());
if(static_cast<DerivedVisitor*>(this)->contained_criteria(ubf_ic))
if (static_cast<DerivedVisitor*>(this)->contained_criteria(ubf_ic))
ubf->set_contained(true);
}
protected:
// compute the inside count of a face
unsigned int compute_ic(Face_iterator f1,
Face_iterator f2,
Halfedge_iterator he)
{
std::size_t compute_ic(Face_iterator f1,
Face_iterator f2,
Halfedge_iterator he) {
CGAL_assertion(m_edges_hash->is_defined(he) &&
m_edges_hash->is_defined(he->twin()) &&
m_faces_hash->is_defined(f1) &&
!m_faces_hash->is_defined(f2));
unsigned int ic_f2 =
! m_faces_hash->is_defined(f2));
std::size_t ic_f2 =
(*m_faces_hash)[f1] - (*m_edges_hash)[he] + (*m_edges_hash)[he->twin()];
(*m_faces_hash)[f2] = ic_f2;

View File

@ -7,59 +7,50 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ophir Setter <ophir.setter@cs.tau.ac.il>
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ophir Setter <ophir.setter@cs.tau.ac.il>
// Efi Fogel <efifogel@gmail.com>
#ifndef CGAL_GPS_BFS_INTERSECTION_VISITOR_H
#define CGAL_GPS_BFS_INTERSECTION_VISITOR_H
#include <CGAL/license/Boolean_set_operations_2.h>
#include <CGAL/Boolean_set_operations_2/Gps_bfs_base_visitor.h>
namespace CGAL {
template <class Arrangement_>
template <typename Arrangement_>
class Gps_bfs_intersection_visitor :
public Gps_bfs_base_visitor<Arrangement_, Gps_bfs_intersection_visitor<Arrangement_> >
{
typedef Arrangement_ Arrangement;
typedef typename Arrangement::Face_iterator Face_iterator;
typedef typename Arrangement::Halfedge_iterator Halfedge_iterator;
typedef Gps_bfs_intersection_visitor<Arrangement> Self;
typedef Gps_bfs_base_visitor<Arrangement, Self> Base;
typedef typename Base::Edges_hash Edges_hash;
typedef typename Base::Faces_hash Faces_hash;
public Gps_bfs_base_visitor<Arrangement_, Gps_bfs_intersection_visitor<Arrangement_>> {
using Arrangement = Arrangement_;
using Face_iterator = typename Arrangement::Face_iterator;
using Halfedge_iterator = typename Arrangement::Halfedge_iterator;
using Self = Gps_bfs_intersection_visitor<Arrangement>;
using Base = Gps_bfs_base_visitor<Arrangement, Self>;
using Edges_hash = typename Base::Edges_hash;
using Faces_hash = typename Base::Faces_hash;
public:
Gps_bfs_intersection_visitor(Edges_hash* edges_hash,
Faces_hash* faces_hash,
unsigned int n_polygons):
std::size_t n_polygons):
Base(edges_hash, faces_hash, n_polygons)
{}
//! contained_criteria
/*! contained_criteria is used to the determine if the face which has
inside count should be marked as contained.
\param ic the inner count of the talked-about face.
\return true if the face of ic, otherwise false.
*/
bool contained_criteria(unsigned int ic)
{
//! contained_criteria
/*! contained_criteria is used to the determine if the face which has
* inside count should be marked as contained.
* \param ic the inner count of the talked-about face.
* \return true if the face of ic, otherwise false.
*/
bool contained_criteria(std::size_t ic) {
// intersection means that all polygons contain the face.
CGAL_assertion(ic <= this->m_num_of_polygons);
return (ic == this->m_num_of_polygons);
}
void after_scan(Arrangement&)
{}
void after_scan(Arrangement&) {}
};
} //namespace CGAL

View File

@ -8,52 +8,46 @@
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ophir Setter <ophir.setter@cs.tau.ac.il>
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ophir Setter <ophir.setter@cs.tau.ac.il>
#ifndef CGAL_GPS_BFS_JOIN_VISITOR_H
#define CGAL_GPS_BFS_JOIN_VISITOR_H
#include <CGAL/license/Boolean_set_operations_2.h>
#include <CGAL/Boolean_set_operations_2/Gps_bfs_base_visitor.h>
namespace CGAL {
template <class Arrangement_>
template <typename Arrangement_>
class Gps_bfs_join_visitor :
public Gps_bfs_base_visitor<Arrangement_, Gps_bfs_join_visitor<Arrangement_> >
{
typedef Arrangement_ Arrangement;
typedef typename Arrangement::Face_iterator Face_iterator;
typedef typename Arrangement::Halfedge_iterator Halfedge_iterator;
typedef Gps_bfs_join_visitor<Arrangement> Self;
typedef Gps_bfs_base_visitor<Arrangement, Self> Base;
typedef typename Base::Edges_hash Edges_hash;
typedef typename Base::Faces_hash Faces_hash;
public Gps_bfs_base_visitor<Arrangement_, Gps_bfs_join_visitor<Arrangement_>> {
using Arrangement = Arrangement_;
using Face_iterator = typename Arrangement::Face_iterator;
using Halfedge_iterator = typename Arrangement::Halfedge_iterator;
using Self = Gps_bfs_join_visitor<Arrangement>;
using Base = Gps_bfs_base_visitor<Arrangement, Self>;
using Edges_hash = typename Base::Edges_hash;
using Faces_hash = typename Base::Faces_hash;
public:
Gps_bfs_join_visitor(Edges_hash* edges_hash, Faces_hash* faces_hash, unsigned int n_pgn):
Gps_bfs_join_visitor(Edges_hash* edges_hash, Faces_hash* faces_hash, std::size_t n_pgn):
Base(edges_hash, faces_hash, n_pgn)
{}
//! contained_criteria
/*! contained_criteria is used to the determine if the face which has
inside count should be marked as contained.
\param ic the inner count of the talked-about face.
\return true if the face of ic, otherwise false.
*/
bool contained_criteria(unsigned int ic)
{
//! contained_criteria
/*! contained_criteria is used to the determine if the face which has
* inside count should be marked as contained.
* \param ic the inner count of the talked-about face.
* \return true if the face of ic, otherwise false.
*/
bool contained_criteria(std::size_t ic) {
// at least one polygon contains the face.
return (ic > 0);
}
void after_scan(Arrangement&)
{}
void after_scan(Arrangement&) {}
};
} //namespace CGAL

View File

@ -8,8 +8,8 @@
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ophir Setter <ophir.setter@cs.tau.ac.il>
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ophir Setter <ophir.setter@cs.tau.ac.il>
#ifndef CGAL_GPS_BFS_XOR_VISITOR_H
#define CGAL_GPS_BFS_XOR_VISITOR_H
@ -21,73 +21,61 @@
namespace CGAL {
template <class Arrangement_>
template <typename Arrangement_>
class Gps_bfs_xor_visitor :
public Gps_bfs_base_visitor<Arrangement_, Gps_bfs_xor_visitor<Arrangement_> >
{
typedef Arrangement_ Arrangement;
typedef typename Arrangement::Face_iterator Face_iterator;
typedef typename Arrangement::Halfedge_iterator Halfedge_iterator;
typedef Gps_bfs_xor_visitor<Arrangement> Self;
typedef Gps_bfs_base_visitor<Arrangement, Self> Base;
typedef typename Base::Edges_hash Edges_hash;
typedef typename Base::Faces_hash Faces_hash;
public Gps_bfs_base_visitor<Arrangement_, Gps_bfs_xor_visitor<Arrangement_>> {
using Arrangement = Arrangement_;
using Face_iterator = typename Arrangement::Face_iterator;
using Halfedge_iterator = typename Arrangement::Halfedge_iterator;
using Self = Gps_bfs_xor_visitor<Arrangement>;
using Base = Gps_bfs_base_visitor<Arrangement, Self>;
using Edges_hash = typename Base::Edges_hash;
using Faces_hash = typename Base::Faces_hash;
public:
Gps_bfs_xor_visitor(Edges_hash* edges_hash, Faces_hash* faces_hash,
unsigned int n_pgn) :
std::size_t n_pgn) :
Base(edges_hash, faces_hash, n_pgn)
{}
//! contained_criteria
//! contained_criteria
/*! contained_criteria is used to the determine if the face which has
inside count should be marked as contained.
\param ic the inner count of the talked-about face.
\return true if the face of ic, otherwise false.
*/
bool contained_criteria(unsigned int ic)
{
bool contained_criteria(std::size_t ic) {
// xor means odd number of polygons.
return (ic % 2) == 1;
}
//! after_scan postprocessing after bfs scan.
/*! The function fixes some of the curves, to be in the same direction as the
half-edges.
\param arr The given arrangement.
*/
void after_scan(Arrangement& arr)
{
typedef typename Arrangement::Geometry_traits_2 Traits;
typedef typename Traits::Compare_endpoints_xy_2 Compare_endpoints_xy_2;
typedef typename Traits::Construct_opposite_2 Construct_opposite_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Arrangement::Edge_iterator Edge_iterator;
/*! The function fixes some of the curves, to be in the same direction as the
* half-edges.
*
* \param arr The given arrangement.
*/
void after_scan(Arrangement& arr) {
using Traits = typename Arrangement::Geometry_traits_2;
using X_monotone_curve_2 = typename Traits::X_monotone_curve_2;
Traits tr;
Compare_endpoints_xy_2 cmp_endpoints =
tr.compare_endpoints_xy_2_object();
Construct_opposite_2 ctr_opp = tr.construct_opposite_2_object();
auto cmp_endpoints = tr.compare_endpoints_xy_2_object();
auto ctr_opp = tr.construct_opposite_2_object();
for(Edge_iterator eit = arr.edges_begin();
eit != arr.edges_end();
++eit)
{
Halfedge_iterator he = eit;
for (auto eit = arr.edges_begin(); eit != arr.edges_end(); ++eit) {
Halfedge_iterator he = eit;
const X_monotone_curve_2& cv = he->curve();
const bool is_cont = he->face()->contained();
const Comparison_result he_res =
const bool is_cont = he->face()->contained();
const Comparison_result he_res =
((Arr_halfedge_direction)he->direction() == ARR_LEFT_TO_RIGHT) ?
SMALLER : LARGER;
SMALLER : LARGER;
const bool has_same_dir = (cmp_endpoints(cv) == he_res);
if ((is_cont && !has_same_dir) || (!is_cont && has_same_dir))
arr.modify_edge(he, ctr_opp(cv));
}
}
};
} //namespace CGAL

View File

@ -0,0 +1,93 @@
// Copyright (c) 2005 Tel-Aviv University (Israel).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Efi Fogel <efifogel@gmail.com>
#ifndef CGAL_GSP_DO_INTERSECT_AGG_OP_VISITOR_H
#define CGAL_GSP_DO_INTERSECT_AGG_OP_VISITOR_H
#include <vector>
#include <CGAL/license/Boolean_set_operations_2.h>
#include <CGAL/Boolean_set_operations_2/Gps_agg_op_visitor.h>
#include <CGAL/Default.h>
namespace CGAL {
template <typename Helper_, typename Arrangement_, typename Visitor_ = Default>
class Gps_do_intersect_agg_op_visitor :
public Gps_agg_op_visitor<
Helper_, Arrangement_,
typename Default::Get<Visitor_, Gps_do_intersect_agg_op_visitor<Helper_, Arrangement_, Visitor_>>::type> {
public:
using Helper = Helper_;
using Arrangement_2 = Arrangement_;
using Geometry_traits_2 = typename Helper::Geometry_traits_2;
using Event = typename Helper::Event;
using Subcurve = typename Helper::Subcurve;
private:
using Gt2 = Geometry_traits_2;
using Arr = Arrangement_2;
using Self = Gps_do_intersect_agg_op_visitor<Helper, Arr, Visitor_>;
using Visitor = typename Default::Get<Visitor_, Self>::type;
using Base = Gps_agg_op_visitor<Helper, Arr, Visitor>;
protected:
bool m_found_x;
public:
using Edges_hash = typename Base::Edges_hash;
using Vertex_handle = typename Base::Vertex_handle;
using Status_line_iterator = typename Base::Status_line_iterator;
using X_monotone_curve_2 = typename Base::X_monotone_curve_2;
using Point_2 = typename Base::Point_2;
using Multiplicity = typename Base::Multiplicity;
Gps_do_intersect_agg_op_visitor(Arr* arr, Edges_hash* hash,
std::vector<Vertex_handle>* vertices_vec) :
Base(arr, hash, vertices_vec),
m_found_x(false)
{}
/*! Update an event that corresponds to a curve endpoint. */
void update_event(Event* e, const Point_2& end_point, const X_monotone_curve_2& cv, Arr_curve_end cv_end, bool is_new)
{ Base::update_event(e, end_point, cv, cv_end, is_new); }
/*! Update an event that corresponds to a curve endpoint */
void update_event(Event* e, const X_monotone_curve_2& cv, Arr_curve_end cv_end, bool is_new )
{ Base::update_event(e, cv, cv_end, is_new); }
/*! Update an event that corresponds to a curve endpoint */
void update_event(Event* e, const Point_2& p, bool is_new)
{ Base::update_event(e, p, is_new); }
/*! Update an event that corresponds to an intersection */
void update_event(Event* e, Subcurve* sc) { Base::update_event(e, sc); }
/*! Update an event that corresponds to an intersection between curves */
void update_event(Event* e, Subcurve* sc1, Subcurve* sc2, bool is_new, Multiplicity multiplicity) {
if ((multiplicity % 2) == 1) m_found_x = true;
Base::update_event(e, sc1, sc2, is_new, multiplicity);
}
//!
bool after_handle_event(Event* e, Status_line_iterator iter, bool flag) {
auto res = Base::after_handle_event(e, iter, flag);
if (m_found_x) this->surface_sweep()->stop_sweep();
return res;
}
/*! Getter */
bool found_intersection() { return m_found_x; }
};
} // namespace CGAL
#endif

View File

@ -15,112 +15,61 @@
#include <CGAL/license/Boolean_set_operations_2.h>
namespace CGAL {
template <class Arrangement_>
class Gps_do_intersect_functor
{
template <typename Arrangement_>
class Gps_do_intersect_functor {
public:
using Arrangement_2 = Arrangement_;
typedef Arrangement_ Arrangement_2;
using Face_const_handle = typename Arrangement_2::Face_const_handle;
using Vertex_const_handle = typename Arrangement_2::Vertex_const_handle;
using Halfedge_const_handle = typename Arrangement_2::Halfedge_const_handle;
typedef typename Arrangement_2::Face_const_handle Face_const_handle;
typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle;
typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
typedef typename Arrangement_2::Face_handle Face_handle;
typedef typename Arrangement_2::Halfedge_handle Halfedge_handle;
typedef typename Arrangement_2::Vertex_handle Vertex_handle;
using Face_handle = typename Arrangement_2::Face_handle;
using Halfedge_handle = typename Arrangement_2::Halfedge_handle;
using Vertex_handle = typename Arrangement_2::Vertex_handle;
// default constructor
Gps_do_intersect_functor() : m_found_reg_intersection(false),
m_found_boudary_intersection(false)
Gps_do_intersect_functor() :
m_found_reg_intersection(false),
m_found_boudary_intersection(false)
{}
void create_face (Face_const_handle f1,
Face_const_handle f2,
Face_handle )
{
if(f1->contained() && f2->contained())
// found intersection
m_found_reg_intersection = true;
}
void create_face(Face_const_handle f1, Face_const_handle f2, Face_handle)
{ if (f1->contained() && f2->contained()) m_found_reg_intersection = true; }
void create_vertex(Vertex_const_handle, Vertex_const_handle, Vertex_handle)
{ m_found_boudary_intersection = true; }
void create_vertex(Vertex_const_handle ,
Vertex_const_handle ,
Vertex_handle )
{
m_found_boudary_intersection = true;
}
void create_vertex(Vertex_const_handle, Halfedge_const_handle, Vertex_handle)
{ m_found_boudary_intersection = true; }
void create_vertex(Vertex_const_handle ,
Halfedge_const_handle ,
Vertex_handle )
{
m_found_boudary_intersection = true;
}
void create_vertex(Halfedge_const_handle, Vertex_const_handle, Vertex_handle)
{ m_found_boudary_intersection = true; }
void create_vertex(Halfedge_const_handle ,
Vertex_const_handle ,
Vertex_handle )
{
m_found_boudary_intersection = true;
}
void create_vertex(Halfedge_const_handle, Halfedge_const_handle, Vertex_handle) {}
void create_vertex(Halfedge_const_handle ,
Halfedge_const_handle ,
Vertex_handle )
{}
void create_vertex(Face_const_handle, Vertex_const_handle, Vertex_handle) {}
void create_vertex(Vertex_const_handle, Face_const_handle, Vertex_handle) {}
void create_vertex(Face_const_handle ,
Vertex_const_handle ,
Vertex_handle )
{}
void create_edge(Halfedge_const_handle, Halfedge_const_handle, Halfedge_handle)
{ m_found_boudary_intersection = true; }
void create_vertex(Vertex_const_handle ,
Face_const_handle ,
Vertex_handle )
{}
void create_edge(Halfedge_const_handle, Face_const_handle, Halfedge_handle) {}
void create_edge(Halfedge_const_handle ,
Halfedge_const_handle ,
Halfedge_handle )
{
m_found_boudary_intersection = true;
}
void create_edge(Face_const_handle, Halfedge_const_handle, Halfedge_handle) {}
void create_edge(Halfedge_const_handle ,
Face_const_handle ,
Halfedge_handle )
{}
bool found_reg_intersection() const { return m_found_reg_intersection; }
void create_edge(Face_const_handle ,
Halfedge_const_handle ,
Halfedge_handle )
{}
bool found_boundary_intersection() const { return m_found_boudary_intersection; }
bool found_reg_intersection() const
{
return m_found_reg_intersection;
}
bool found_boundary_intersection() const
{
return m_found_boudary_intersection;
}
protected:
bool m_found_reg_intersection;
bool m_found_boudary_intersection;
protected:
bool m_found_reg_intersection;
bool m_found_boudary_intersection;
};
} //namespace CGAL
#endif

View File

@ -7,15 +7,17 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Efi Fogel <efifogel@gmail.com>
#ifndef CGAL_GPS_MERGE_H
#define CGAL_GPS_MERGE_H
#include <CGAL/license/Boolean_set_operations_2.h>
#include <CGAL/Boolean_set_operations_2/Gps_agg_op.h>
#include <CGAL/Boolean_set_operations_2/Gps_agg_op_visitor.h>
#include <CGAL/Boolean_set_operations_2/Gps_do_intersect_agg_op_visitor.h>
#include <CGAL/Boolean_set_operations_2/Gps_bfs_join_visitor.h>
#include <CGAL/Boolean_set_operations_2/Gps_bfs_xor_visitor.h>
#include <CGAL/Boolean_set_operations_2/Gps_bfs_intersection_visitor.h>
@ -23,50 +25,40 @@
namespace CGAL {
/*!
\file Gps_merge.h
\brief This file contains classes that are responsible for merging
two sets of polygons in the divide-and-conquer algorithm.
The file contains 3 mergers: Join_merge, Intersection_merge and
Xor_merge. Join_merge is used when we want to merge the two sets,
Intersection_merge is used for intersection, and Xor_merge is used
for symmetric difference.
*/
//! Base_merge
/*! Base_merge is the base class for all merger classes.
All merges used BFS algorithm with a different visitor when discovering
a new face.
/*! \file Gps_merge.h
*
* This file contains classes that are responsible for merging two sets of
* polygons in the divide-and-conquer algorithm. The file contains 3 mergers:
* Join_merge, Intersection_merge and Xor_merge. Join_merge is used when we want
* to merge the two sets, Intersection_merge is used for intersection, and
* Xor_merge is used for symmetric difference.
*/
template <class Arrangement_, class Visitor_>
class Base_merge
{
typedef Arrangement_ Arrangement_2;
typedef Visitor_ Visitor;
typedef typename Arrangement_2::Vertex_handle Vertex_handle;
typedef std::pair<Arrangement_2 *,
std::vector<Vertex_handle> *> Arr_entry;
/*! Base_merge
* Base_merge is the base class for all merger classes.
* All merges used BFS algorithm with a different visitor when discovering
* a new face.
*/
template <typename Arrangement_, typename Visitor_>
class Base_merge {
using Arrangement_2 = Arrangement_;
using Visitor = Visitor_;
using Vertex_handle = typename Arrangement_2::Vertex_handle;
using Arr_entry = std::pair<Arrangement_2*, std::vector<Vertex_handle>*>;
public:
void operator()(unsigned int i,
unsigned int j,
unsigned int jump,
std::vector<Arr_entry>& arr_vec)
{
if(i==j)
return;
void operator()(std::size_t i, std::size_t j, std::size_t jump, std::vector<Arr_entry>& arr_vec) {
if (i == j) return;
const typename Arrangement_2::Geometry_traits_2 * tr =
arr_vec[i].first->geometry_traits();
Arrangement_2 *res = new Arrangement_2(tr);
std::vector<Vertex_handle> *verts = new std::vector<Vertex_handle>;
const auto* tr = arr_vec[i].first->geometry_traits();
Arrangement_2* res = new Arrangement_2(tr);
std::vector<Vertex_handle>* verts = new std::vector<Vertex_handle>;
Gps_agg_op<Arrangement_2, Visitor>
agg_op(*res, *verts, *(res->traits_adaptor()));
using Agg_op = Gps_agg_op<Arrangement_2, Visitor, Gps_agg_op_visitor>;
Agg_op agg_op(*res, *verts, *(res->traits_adaptor()));
agg_op.sweep_arrangements(i, j, jump, arr_vec);
for(unsigned int count=i; count<=j; count+=jump)
{
for (std::size_t count = i; count <= j; count += jump) {
delete (arr_vec[count].first);
delete (arr_vec[count].second);
}
@ -74,38 +66,92 @@ public:
arr_vec[i].first = res;
arr_vec[i].second = verts;
}
};
//! Join_merge
/*! Join_merge is used to join two sets of polygons together in the D&C
algorithm. It is a base merge with a visitor that joins faces.
/*! Base_intercepted_merge
* Base_intercepted_merge is the base class for all merger classes that can be
* interceted (e.g., when an intersection is detected). All merges used BFS
* algorithm with a different visitor when discovering a new face.
*/
template <class Arrangement_>
class Join_merge : public Base_merge<Arrangement_,
Gps_bfs_join_visitor<Arrangement_> >
{};
template <typename Arrangement_, typename Visitor_>
class Base_intercepted_merge {
using Arrangement_2 = Arrangement_;
using Visitor = Visitor_;
using Vertex_handle = typename Arrangement_2::Vertex_handle;
using Arr_entry = std::pair<Arrangement_2*, std::vector<Vertex_handle>*>;
public:
template <typename InputIterator>
bool operator()(InputIterator begin, InputIterator end) {
CGAL_assertion(begin != end);
//! Intersection_merge
/*! Intersection_merge is used to merge two sets of polygons creating their
intersection.
*/
template <class Arrangement_>
class Intersection_merge : public Base_merge<Arrangement_,
Gps_bfs_intersection_visitor<Arrangement_> >
{};
const auto* tr = begin->first->geometry_traits();
Arrangement_2* arr = new Arrangement_2(tr);
std::vector<Vertex_handle>* verts = new std::vector<Vertex_handle>;
//! Xor_merge
/*! Xor_merge is used to merge two sets of polygons creating their
symmetric difference.
*/
template <class Arrangement_>
class Xor_merge : public Base_merge<Arrangement_,
Gps_bfs_xor_visitor<Arrangement_> >
{
using Agg_op = Gps_agg_op<Arrangement_2, Visitor, Gps_do_intersect_agg_op_visitor>;
Agg_op agg_op(*arr, *verts, *(arr->traits_adaptor()));
auto res = agg_op.sweep_intercept_arrangements2(begin, end);
begin->first = arr;
begin->second = verts;
return res;
}
bool operator()(std::size_t i, std::size_t j, std::size_t jump, std::vector<Arr_entry>& arr_vec) {
if (i == j) return false;
const auto* tr = arr_vec[i].first->geometry_traits();
Arrangement_2* arr = new Arrangement_2(tr);
std::vector<Vertex_handle>* verts = new std::vector<Vertex_handle>;
using Agg_op = Gps_agg_op<Arrangement_2, Visitor, Gps_do_intersect_agg_op_visitor>;
Agg_op agg_op(*arr, *verts, *(arr->traits_adaptor()));
auto res = agg_op.sweep_intercept_arrangements(i, j, jump, arr_vec);
for (auto count = i; count <= j; count += jump) {
delete (arr_vec[count].first);
arr_vec[count].first = nullptr;
delete (arr_vec[count].second);
arr_vec[count].second = nullptr;
}
arr_vec[i].first = arr;
arr_vec[i].second = verts;
return res;
}
};
/*! Join_merge
* Join_merge is used to join two sets of polygons together in the D&C
* algorithm. It is a base merge with a visitor that joins faces.
*/
template <typename Arrangement_>
class Join_merge : public Base_merge<Arrangement_, Gps_bfs_join_visitor<Arrangement_>>{};
/*! Intersection_merge
* Intersection_merge is used to merge two sets of polygons creating their
* intersection.
*/
template <typename Arrangement_>
class Intersection_merge : public Base_merge<Arrangement_, Gps_bfs_intersection_visitor<Arrangement_>>{};
/*! Do_intersect_merge
* Do_intersect_merge is used to merge two sets of polygons creating their
* intersection. When an intersection in the interior of the boundary curves
* is detected, the sweep is intercepted.
*/
template <typename Arrangement_>
class Do_intersect_merge : public Base_intercepted_merge<Arrangement_, Gps_bfs_intersection_visitor<Arrangement_>>{};
/*! Xor_merge
* Xor_merge is used to merge two sets of polygons creating their
* symmetric difference.
*/
template <typename Arrangement_>
class Xor_merge : public Base_merge<Arrangement_, Gps_bfs_xor_visitor<Arrangement_>>{};
} //namespace CGAL
#endif

View File

@ -7,11 +7,10 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
#ifndef CGAL_BSO_2_GPS_POLYGON_SIMPILFIER_H
#define CGAL_BSO_2_GPS_POLYGON_SIMPILFIER_H
#ifndef CGAL_GPS_POLYGON_SIMPILFIER_H
#define CGAL_GPS_POLYGON_SIMPILFIER_H
#include <CGAL/license/Boolean_set_operations_2.h>
@ -31,34 +30,33 @@ namespace Ss2 = Surface_sweep_2;
template <typename Arrangement_>
class Gps_polygon_simplifier {
typedef Arrangement_ Arrangement_2;
using Arrangement_2 = Arrangement_;
typedef typename Arrangement_2::Geometry_traits_2 Geometry_traits_2;
typedef typename Arrangement_2::Topology_traits Topology_traits;
using Geometry_traits_2 = typename Arrangement_2::Geometry_traits_2;
using Topology_traits = typename Arrangement_2::Topology_traits;
typedef Arrangement_2 Arr;
typedef Geometry_traits_2 Gt2;
typedef Topology_traits Tt;
using Arr = Arrangement_2;
using Gt2 = Geometry_traits_2;
using Tt = Topology_traits;
typedef typename Gt2::Curve_const_iterator Curve_const_iterator;
typedef typename Gt2::Polygon_2 Polygon_2;
typedef typename Gt2::Polygon_with_holes_2 Polygon_with_holes_2;
typedef typename Gt2::Construct_curves_2 Construct_curves_2;
using Curve_const_iterator = typename Gt2::Curve_const_iterator;
using Polygon_2 = typename Gt2::Polygon_2;
using Polygon_with_holes_2 = typename Gt2::Polygon_with_holes_2;
using Construct_curves_2 = typename Gt2::Construct_curves_2;
typedef Gps_simplifier_traits<Gt2> Mgt2;
typedef typename Mgt2::Curve_data Curve_data;
typedef typename Mgt2::X_monotone_curve_2 Meta_X_monotone_curve_2;
using Mgt2 = Gps_simplifier_traits<Gt2>;
using Curve_data = typename Mgt2::Curve_data;
using Meta_X_monotone_curve_2 = typename Mgt2::X_monotone_curve_2;
typedef typename Arr::Halfedge_handle Halfedge_handle;
typedef typename Arr::Halfedge_iterator Halfedge_iterator;
typedef typename Arr::Face_handle Face_handle;
typedef typename Arr::Face_iterator Face_iterator;
typedef typename Arr::Edge_iterator Edge_iterator;
typedef typename Arr::Vertex_handle Vertex_handle;
typedef typename Arr::Ccb_halfedge_const_circulator
Ccb_halfedge_const_circulator;
typedef typename Arr::Ccb_halfedge_circulator Ccb_halfedge_circulator;
typedef typename Arr::Allocator Allocator;
using Halfedge_handle = typename Arr::Halfedge_handle;
using Halfedge_iterator = typename Arr::Halfedge_iterator;
using Face_handle = typename Arr::Face_handle;
using Face_iterator = typename Arr::Face_iterator;
using Edge_iterator = typename Arr::Edge_iterator;
using Vertex_handle = typename Arr::Vertex_handle;
using Ccb_halfedge_const_circulator = typename Arr::Ccb_halfedge_const_circulator;
using Ccb_halfedge_circulator = typename Arr::Ccb_halfedge_circulator;
using Allocator = typename Arr::Allocator;
// We obtain a proper helper type from the topology traits of the arrangement.
// However, the arrangement is parametrized with the Gt2 geometry traits,
@ -67,22 +65,18 @@ class Gps_polygon_simplifier {
// We cannot parameterized the arrangement with the Mgt2 geometry
// traits to start with, because it extends the curve type with arrangement
// dependent types. (It is parameterized with the arrangement type.)
typedef Indexed_event<Mgt2, Arr, Allocator> Event;
typedef Arr_construction_subcurve<Mgt2, Event, Allocator>
Subcurve;
typedef typename Tt::template Construction_helper<Event, Subcurve>
Helper_tmp;
typedef typename Helper_tmp::template rebind<Mgt2, Arr, Event, Subcurve>::other
Helper;
typedef Gps_agg_op_base_visitor<Helper, Arr> Visitor;
typedef Ss2::Surface_sweep_2<Visitor> Surface_sweep_2;
using Event = Indexed_event<Mgt2, Arr, Allocator>;
using Subcurve = Arr_construction_subcurve<Mgt2, Event, Allocator>;
using Helper_tmp = typename Tt::template Construction_helper<Event, Subcurve>;
using Helper = typename Helper_tmp::template rebind<Mgt2, Arr, Event, Subcurve>::other;
using Visitor = Gps_agg_op_base_visitor<Helper, Arr>;
using Surface_sweep_2 = Ss2::Surface_sweep_2<Visitor>;
typedef Unique_hash_map<Halfedge_handle, unsigned int>
Edges_hash;
using Edges_hash = Unique_hash_map<Halfedge_handle, std::size_t>;
typedef Unique_hash_map<Face_handle, unsigned int> Faces_hash;
typedef Gps_bfs_join_visitor<Arr> Bfs_visitor;
typedef Gps_bfs_scanner<Arr, Bfs_visitor> Bfs_scanner;
using Faces_hash = Unique_hash_map<Face_handle, std::size_t>;
using Bfs_visitor = Gps_bfs_join_visitor<Arr>;
using Bfs_scanner = Gps_bfs_scanner<Arr, Bfs_visitor>;
protected:
Arr* m_arr;
@ -104,16 +98,14 @@ public:
{}
/*! Destructor. */
~Gps_polygon_simplifier()
{
~Gps_polygon_simplifier() {
if (m_own_traits && (m_traits != nullptr)) {
delete m_traits;
m_traits = nullptr;
}
}
void simplify(const Polygon_2& pgn)
{
void simplify(const Polygon_2& pgn) {
Construct_curves_2 ctr_curves =
reinterpret_cast<const Gt2*>(m_traits)->construct_curves_2_object();
@ -122,14 +114,13 @@ public:
std::pair<Curve_const_iterator, Curve_const_iterator> itr_pair =
ctr_curves(pgn);
unsigned int index = 0;
std::size_t index = 0;
for (Curve_const_iterator itr = itr_pair.first; itr != itr_pair.second;
++itr, ++index)
{
++itr, ++index) {
Curve_data cv_data(1, 0, index);
curves_list.push_back(Meta_X_monotone_curve_2(*itr, cv_data));
}
m_traits->set_polygon_size(static_cast<unsigned int>(curves_list.size()));
m_traits->set_polygon_size(curves_list.size());
m_surface_sweep.sweep(curves_list.begin(), curves_list.end());

View File

@ -7,14 +7,13 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s): Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Boris Kozorovitzky <boriskoz@post.tau.ac.il>
// Guy Zucker <guyzucke@post.tau.ac.il>
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Boris Kozorovitzky <boriskoz@post.tau.ac.il>
// Guy Zucker <guyzucke@post.tau.ac.il>
#ifndef CGAL_BSO_2_GPS_POLYGON_VALIDATION_2_H
#define CGAL_BSO_2_GPS_POLYGON_VALIDATION_2_H
#ifndef CGAL_GPS_POLYGON_VALIDATION_2_H
#define CGAL_GPS_POLYGON_VALIDATION_2_H
#include <CGAL/license/Boolean_set_operations_2.h>

View File

@ -7,9 +7,8 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s): Baruch Zukerman <baruchzu@post.tau.ac.il>
// Efi Fogel <efifogel@gmail.com>
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Efi Fogel <efifogel@gmail.com>
#ifndef CGAL_GPS_SIMPLIFIER_TRAITS_H
#define CGAL_GPS_SIMPLIFIER_TRAITS_H
@ -23,97 +22,94 @@ namespace CGAL {
class Gps_simplifier_curve_data {
protected:
unsigned int m_bc;
unsigned int m_twin_bc;
unsigned int m_index;
std::size_t m_bc;
std::size_t m_twin_bc;
std::size_t m_index;
public:
Gps_simplifier_curve_data() {}
Gps_simplifier_curve_data(unsigned int bc, unsigned int twin_bc,
unsigned int index):
Gps_simplifier_curve_data(std::size_t bc, std::size_t twin_bc,
std::size_t index):
m_bc(bc),
m_twin_bc(twin_bc),
m_index(index)
{}
unsigned int bc() const { return m_bc; }
std::size_t bc() const { return m_bc; }
unsigned int twin_bc() const { return m_twin_bc; }
std::size_t twin_bc() const { return m_twin_bc; }
unsigned int index() const { return m_index; }
std::size_t index() const { return m_index; }
unsigned int& index() { return m_index; }
std::size_t& index() { return m_index; }
unsigned int& twin_bc() { return m_twin_bc; }
std::size_t& twin_bc() { return m_twin_bc; }
void set_bc(unsigned int bc) { m_bc = bc; }
void set_bc(std::size_t bc) { m_bc = bc; }
void set_twin_bc(unsigned int twin_bc) { m_twin_bc = twin_bc; }
void set_twin_bc(std::size_t twin_bc) { m_twin_bc = twin_bc; }
void set_index(unsigned int index) { m_index = index; }
void set_index(std::size_t index) { m_index = index; }
};
struct Gps_simplifier_point_data {
protected:
unsigned int m_index;
std::size_t m_index;
public:
Gps_simplifier_point_data() {}
Gps_simplifier_point_data(unsigned int index) : m_index(index) {}
Gps_simplifier_point_data(std::size_t index) : m_index(index) {}
unsigned int index() const { return m_index; }
std::size_t index() const { return m_index; }
void set_index(unsigned int index) { m_index = index; }
void set_index(std::size_t index) { m_index = index; }
};
template <typename Traits_>
class Gps_simplifier_traits :
public Gps_traits_decorator<Traits_,
Gps_simplifier_curve_data,
Gps_simplifier_point_data>
{
Gps_simplifier_point_data> {
public:
typedef Traits_ Traits;
typedef Gps_traits_decorator<Traits_,
Gps_simplifier_curve_data,
Gps_simplifier_point_data> Base;
typedef Gps_simplifier_traits<Traits> Self;
typedef typename Traits::X_monotone_curve_2 Base_x_monotone_curve_2;
typedef typename Traits::Point_2 Base_point_2;
typedef typename Traits::Construct_min_vertex_2 Base_Construct_min_vertex_2;
typedef typename Traits::Construct_max_vertex_2 Base_Construct_max_vertex_2;
typedef typename Traits::Compare_endpoints_xy_2 Base_Compare_endpoints_xy_2;
typedef typename Traits::Compare_xy_2 Base_Compare_xy_2;
typedef typename Traits::Compare_y_at_x_right_2 Base_Compare_y_at_x_right_2;
typedef typename Traits::Compare_y_at_x_2 Base_Compare_y_at_x_2;
typedef typename Traits::Intersect_2 Base_Intersect_2;
typedef typename Traits::Split_2 Base_Split_2;
using Traits = Traits_;
using Base = Gps_traits_decorator<Traits_, Gps_simplifier_curve_data, Gps_simplifier_point_data>;
using Self = Gps_simplifier_traits<Traits>;
using Base_x_monotone_curve_2 = typename Traits::X_monotone_curve_2;
using Base_point_2 = typename Traits::Point_2;
using Base_Construct_min_vertex_2 = typename Traits::Construct_min_vertex_2;
using Base_Construct_max_vertex_2 = typename Traits::Construct_max_vertex_2;
using Base_Compare_endpoints_xy_2 = typename Traits::Compare_endpoints_xy_2;
using Base_Compare_xy_2 = typename Traits::Compare_xy_2;
using Base_Compare_y_at_x_right_2 = typename Traits::Compare_y_at_x_right_2;
using Base_Compare_y_at_x_2 = typename Traits::Compare_y_at_x_2;
using Base_Intersect_2 = typename Traits::Intersect_2;
using Base_Split_2 = typename Traits::Split_2;
protected:
mutable unsigned int m_pgn_size;
mutable std::size_t m_pgn_size;
public:
typedef typename Base::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Base::Point_2 Point_2;
typedef typename Base::Multiplicity Multiplicity;
using X_monotone_curve_2 = typename Base::X_monotone_curve_2;
using Point_2 = typename Base::Point_2;
using Multiplicity = typename Base::Multiplicity;
typedef typename Base::Curve_data Curve_data;
typedef typename Base::Point_data Point_data;
using Curve_data = typename Base::Curve_data;
using Point_data = typename Base::Point_data;
Gps_simplifier_traits() {}
Gps_simplifier_traits(const Traits& tr) : Base(tr) {}
unsigned int polygon_size() const { return m_pgn_size; }
std::size_t polygon_size() const { return m_pgn_size; }
void set_polygon_size(unsigned int pgn_size) const { m_pgn_size = pgn_size; }
void set_polygon_size(std::size_t pgn_size) const { m_pgn_size = pgn_size; }
bool is_valid_index(unsigned int index) const
bool is_valid_index(std::size_t index) const
{ return (index < m_pgn_size); }
unsigned int invalid_index() const { return (m_pgn_size); }
std::size_t invalid_index() const { return (m_pgn_size); }
class Intersect_2 {
private:
@ -129,12 +125,9 @@ public:
template <typename OutputIterator>
OutputIterator operator()(const X_monotone_curve_2& cv1,
const X_monotone_curve_2& cv2,
OutputIterator oi) const
{
typedef const std::pair<Base_point_2, Multiplicity>
Intersection_base_point;
typedef std::variant<Intersection_base_point, Base_x_monotone_curve_2>
Intersection_base_result;
OutputIterator oi) const {
using Intersection_base_point = const std::pair<Base_point_2, Multiplicity>;
using Intersection_base_result = std::variant<Intersection_base_point, Base_x_monotone_curve_2>;
const auto* base_traits = m_traits.m_base_traits;
auto base_cmp_xy = base_traits->compare_xy_2_object();
@ -146,7 +139,7 @@ public:
//if (m_traits.is_valid_index(cv1.data().index()) &&
// m_traits.is_valid_index(cv2.data().index()))
//{
// unsigned int index_diff =
// std::size_t index_diff =
// (cv1.data().index() > cv2.data().index()) ?
// (cv1.data().index() - cv2.data().index()):
// (cv2.data().index() - cv1.data().index());
@ -180,8 +173,8 @@ public:
std::get_if<Base_x_monotone_curve_2>(&xection);
CGAL_assertion(overlap_cv != nullptr);
unsigned int ov_bc;
unsigned int ov_twin_bc;
std::size_t ov_bc;
std::size_t ov_twin_bc;
if (base_cmp_endpoints(cv1) == base_cmp_endpoints(cv2)) {
// cv1 and cv2 have the same directions
ov_bc = cv1.data().bc() + cv2.data().bc();
@ -207,7 +200,7 @@ public:
};
/*! Obtain an Intersect_2 functor object. */
Intersect_2 intersect_2_object () const { return Intersect_2(*this); }
Intersect_2 intersect_2_object() const { return Intersect_2(*this); }
class Split_2 {
private:
@ -220,8 +213,7 @@ public:
public:
void operator()(const X_monotone_curve_2& cv, const Point_2 & p,
X_monotone_curve_2& c1, X_monotone_curve_2& c2) const
{
X_monotone_curve_2& c1, X_monotone_curve_2& c2) const {
const auto* base_traits = m_traits.m_base_traits;
auto base_split = base_traits->split_2_object();
base_split(cv.base(), p.base(), c1.base(), c2.base());
@ -250,8 +242,7 @@ public:
* \param cv The curve.
* \return The left endpoint.
*/
Point_2 operator()(const X_monotone_curve_2 & cv) const
{
Point_2 operator()(const X_monotone_curve_2 & cv) const {
const auto* base_traits = m_traits.m_base_traits;
auto base_ctr_min_vertex = base_traits->construct_min_vertex_2_object();
@ -290,8 +281,7 @@ public:
* \param cv The curve.
* \return The left endpoint.
*/
Point_2 operator() (const X_monotone_curve_2 & cv) const
{
Point_2 operator() (const X_monotone_curve_2 & cv) const {
const auto* base_traits = m_traits.m_base_traits;
auto base_ctr_max_vertex = base_traits->construct_max_vertex_2_object();
if (! m_traits.is_valid_index(cv.data().index()))
@ -329,8 +319,7 @@ public:
* \param cv The curve.
* \return The left endpoint.
*/
Comparison_result operator()(const Point_2& p1, const Point_2& p2) const
{
Comparison_result operator()(const Point_2& p1, const Point_2& p2) const {
const auto* base_traits = m_traits.m_base_traits;
auto base_cmp_xy = base_traits->compare_xy_2_object();

View File

@ -11,8 +11,8 @@
// Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efifogel@gmail.com>
#ifndef CGAL_BSO_2_INDEXED_VISITOR_H
#define CGAL_BSO_2_INDEXED_VISITOR_H
#ifndef CGAL_INDEXED_VISITOR_H
#define CGAL_INDEXED_VISITOR_H
#include <CGAL/license/Boolean_set_operations_2.h>
@ -32,17 +32,16 @@ class Indexed_event :
Arrangement_,
Allocator_>,
Allocator_>,
Arrangement_>
{
Arrangement_> {
private:
unsigned int m_index;
std::size_t m_index;
public:
Indexed_event() : m_index (0) {}
unsigned int index() const { return (m_index); }
std::size_t index() const { return (m_index); }
void set_index(unsigned int index) { m_index = index; }
void set_index(std::size_t index) { m_index = index; }
};
} // namespace CGAL

View File

@ -31,9 +31,9 @@ namespace CGAL {
// Utility struct
template <typename Polygon>
struct Gps_polyline_traits {
typedef typename Gps_default_traits<Polygon>::Arr_traits Segment_traits;
typedef Arr_polyline_traits_2<Segment_traits> Polyline_traits;
typedef Gps_traits_2<Polyline_traits> Traits;
using Segment_traits = typename Gps_default_traits<Polygon>::Arr_traits;
using Polyline_traits = Arr_polyline_traits_2<Segment_traits>;
using Traits = Gps_traits_2<Polyline_traits>;
};
// Helper to map Polygon_2 -> General_polygon_2 / PWH_2 -> General_PWH_2
@ -85,9 +85,7 @@ using Disable_if_Polygon_2_iterator =
// Convert Polygon_2 to General_polygon_2<Polyline_traits>
template <typename Kernel, typename Container, typename ArrTraits>
General_polygon_2<ArrTraits>
convert_polygon(const Polygon_2<Kernel, Container>& polygon,
const ArrTraits& traits)
{
convert_polygon(const Polygon_2<Kernel, Container>& polygon, const ArrTraits& traits) {
auto ctr = traits.construct_curve_2_object();
if (polygon.is_empty()) return General_polygon_2<ArrTraits>();
using Point = typename ArrTraits::Point_2;
@ -99,22 +97,20 @@ convert_polygon(const Polygon_2<Kernel, Container>& polygon,
General_polygon_2<ArrTraits> gpgn;
auto make_x_mtn = traits.make_x_monotone_2_object();
make_x_mtn(cv,
boost::make_function_output_iterator
([&](const Make_x_monotone_result& obj)
{ gpgn.push_back(*(std::get_if<X_monotone_curve>(&obj))); }));
boost::make_function_output_iterator([&](const Make_x_monotone_result& obj)
{ gpgn.push_back(*(std::get_if<X_monotone_curve>(&obj))); }));
return gpgn;
}
// Convert Polygon_with_holes_2 to General_polygon_with_holes_2<Polyline_traits>
template <typename Kernel, typename Container, typename ArrTraits>
General_polygon_with_holes_2<General_polygon_2<ArrTraits> >
General_polygon_with_holes_2<General_polygon_2<ArrTraits>>
convert_polygon(const Polygon_with_holes_2<Kernel, Container>& pwh,
const ArrTraits& traits) {
typedef General_polygon_2<ArrTraits> General_pgn;
typedef Polygon_2<Kernel, Container> Pgn;
auto converter = [&](const Pgn& pgn)->General_pgn {
return convert_polygon(pgn, traits);
};
using General_pgn = General_polygon_2<ArrTraits>;
using Pgn = Polygon_2<Kernel, Container>;
auto converter = [&](const Pgn& pgn)->General_pgn
{ return convert_polygon(pgn, traits); };
return General_polygon_with_holes_2<General_polygon_2<ArrTraits>>
(convert_polygon(pwh.outer_boundary(), traits),
boost::make_transform_iterator(pwh.holes().begin(), converter),
@ -137,14 +133,11 @@ convert_polygon_back(const General_polygon_2<ArrTraits>& gpgn) {
// Convert General_polygon_with_holes_2<Polyline_traits> to Polygon_with_holes_2
template <typename Kernel, typename Container, typename ArrTraits>
Polygon_with_holes_2<Kernel, Container>
convert_polygon_back(const General_polygon_with_holes_2
<General_polygon_2<ArrTraits> >& gpwh)
{
convert_polygon_back(const General_polygon_with_holes_2<General_polygon_2<ArrTraits>>& gpwh) {
using Pgn = Polygon_2<Kernel, Container>;
using General_pgn = General_polygon_2<ArrTraits>;
auto converter = [](const General_pgn& gpgn)->Pgn {
return convert_polygon_back<Kernel, Container>(gpgn);
};
auto converter = [](const General_pgn& gpgn)->Pgn
{ return convert_polygon_back<Kernel, Container>(gpgn); };
return Polygon_with_holes_2<Kernel, Container>
(convert_polygon_back<Kernel, Container>(gpwh.outer_boundary()),
boost::make_transform_iterator(gpwh.holes().begin(), converter),
@ -155,21 +148,17 @@ convert_polygon_back(const General_polygon_with_holes_2
// Polygon_2 to General_polygon_2<Polyline_traits>, or
// Polygon_with_holes_2 to General_polygon_with_holes_2<Polyline_traits>
template <typename InputIterator, typename Traits>
boost::transform_iterator
<std::function
<typename General_polygon_of_polygon<typename std::iterator_traits
<InputIterator>::value_type>::type
(typename std::iterator_traits<InputIterator>::reference)>,
InputIterator>
convert_polygon_iterator(InputIterator it, const Traits& traits)
{
boost::transform_iterator<std::function<
typename General_polygon_of_polygon<typename std::iterator_traits<
InputIterator>::value_type>::type
(typename std::iterator_traits<InputIterator>::reference)>, InputIterator>
convert_polygon_iterator(InputIterator it, const Traits& traits) {
using Input_type = typename std::iterator_traits<InputIterator>::value_type;
using Return_type = typename General_polygon_of_polygon<Input_type>::type;
using Function_type = std::function<Return_type(Input_type)>;
Function_type func =
[&traits](const Input_type& p)->Return_type
{ return convert_polygon(p, traits); };
Function_type func = [&traits](const Input_type& p)->Return_type
{ return convert_polygon(p, traits); };
return boost::transform_iterator<Function_type, InputIterator>(it, func);
}
@ -186,8 +175,7 @@ struct Polygon_converter {
// Convert and export to output iterator.
template <typename ArrTraits>
void operator()(const General_polygon_with_holes_2
<General_polygon_2<ArrTraits> >& gpwh) const
void operator()(const General_polygon_with_holes_2<General_polygon_2<ArrTraits>>& gpwh) const
{ *m_output++ = convert_polygon_back<Kernel, Container>(gpwh); }
};
@ -195,9 +183,7 @@ struct Polygon_converter {
// OutputIterator
template <typename Kernel, typename Container, typename OutputIterator>
struct Polygon_converter_output_iterator :
boost::function_output_iterator<Polygon_converter
<Kernel, Container, OutputIterator> >
{
boost::function_output_iterator<Polygon_converter<Kernel, Container, OutputIterator>> {
using Converter = Polygon_converter<Kernel, Container, OutputIterator>;
using Base = boost::function_output_iterator<Converter>;
@ -214,11 +200,8 @@ struct Polygon_converter_output_iterator :
// (indirection with Polygon_2)
template <typename OutputIterator, typename Kernel, typename Container>
Polygon_converter_output_iterator<Kernel, Container, OutputIterator>
convert_polygon_back(OutputIterator& output,
const Polygon_2<Kernel, Container>&)
{
return Polygon_converter_output_iterator
<Kernel, Container, OutputIterator>(output);
convert_polygon_back(OutputIterator& output, const Polygon_2<Kernel, Container>&) {
return Polygon_converter_output_iterator<Kernel, Container, OutputIterator>(output);
}
// Converts General_polygon_with_holes_2<Polyline_traits> to Polygon_with_holes_2
@ -226,10 +209,8 @@ convert_polygon_back(OutputIterator& output,
template <typename OutputIterator, typename Kernel, typename Container>
Polygon_converter_output_iterator<Kernel, Container, OutputIterator>
convert_polygon_back(OutputIterator& output,
const Polygon_with_holes_2<Kernel, Container>&)
{
return Polygon_converter_output_iterator
<Kernel, Container, OutputIterator>(output);
const Polygon_with_holes_2<Kernel, Container>&) {
return Polygon_converter_output_iterator<Kernel, Container, OutputIterator>(output);
}
template <typename InputIterator>
@ -238,7 +219,6 @@ struct Iterator_to_gps_traits {
typedef typename Gps_default_traits<InputPolygon>::Traits Traits;
};
}
#endif // CGAL_BSO_POLYGON_CONVERSIONS_H
#endif

View File

@ -8,10 +8,10 @@
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s): Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Simon Giraudot <simon.giraudot@geometryfactory.com>
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Simon Giraudot <simon.giraudot@geometryfactory.com>
#ifndef CGAL_BOOLEAN_SET_OPERATIONS_2_DO_INTERSECT_H
#define CGAL_BOOLEAN_SET_OPERATIONS_2_DO_INTERSECT_H
@ -33,12 +33,18 @@
#include <CGAL/Boolean_set_operations_2/Polygon_conversions.h>
#include <CGAL/type_traits/is_iterator.h>
namespace CGAL
{
namespace CGAL {
/// \name do_intersect() functions.
//@{
/*! We do not use polyline for do_intersect), as we rely on the overlay traits
* to only intercept intersections between the interiors of segments that
* comprise the boundary of polygons. Observe that The intersections between the
* interiors of polylines that comprise the boundary of polygons may include an
* endpoint of a segment, and we do not want that.
*/
// Polygon_2, Polygon_2 ========================================================
// With Traits
template <typename Kernel, typename Container, typename Traits>
@ -47,24 +53,24 @@ inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
Traits& traits)
{ return s_do_intersect(pgn1, pgn2, traits); }
// With Tag_true
// without traits
template <typename Kernel, typename Container>
inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
const Polygon_2<Kernel, Container>& pgn2,
Tag_true = Tag_true())
{ return s_do_intersect(pgn1, pgn2); }
// With Tag_false
template <typename Kernel, typename Container>
inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
const Polygon_2<Kernel, Container>& pgn2,
Tag_false)
{
typedef Polygon_2<Kernel, Container> Polygon;
const Polygon_2<Kernel, Container>& pgn2) {
using Polygon = Polygon_2<Kernel, Container>;
typename Gps_default_traits<Polygon>::Traits traits;
return s_do_intersect(pgn1, pgn2, traits);
}
#ifndef CGAL_NO_DEPRECATED_CODE
template <typename Kernel, typename Container, bool b>
inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
const Polygon_2<Kernel, Container>& pgn2,
std::bool_constant<b>) {
return do_intersect(pgn1, pgn2);
}
#endif
// Polygon_2, Polygon_with_hole_2 ==============================================
// With Traits
template <typename Kernel, typename Container, typename Traits>
@ -73,25 +79,25 @@ inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
Traits& traits)
{ return s_do_intersect(pgn1, pgn2, traits); }
// With Tag_true
// Without traits
template <typename Kernel, typename Container>
inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
const Polygon_with_holes_2<Kernel, Container>& pgn2,
Tag_true = Tag_true())
{ return s_do_intersect(pgn1, pgn2); }
// With Tag_false
template <typename Kernel, typename Container>
inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
const Polygon_with_holes_2<Kernel, Container>& pgn2,
Tag_false)
{
const Polygon_with_holes_2<Kernel, Container>& pgn2) {
// Use the first polygon to determine the (default) traits
typedef Polygon_2<Kernel, Container> Polygon;
using Polygon = Polygon_2<Kernel, Container>;
typename Gps_default_traits<Polygon>::Traits traits;
return s_do_intersect(pgn1, pgn2, traits);
}
#ifndef CGAL_NO_DEPRECATED_CODE
template <typename Kernel, typename Container, bool b>
inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
const Polygon_with_holes_2<Kernel, Container>& pgn2,
std::bool_constant<b>) {
return do_intersect(pgn1, pgn2);
}
#endif
// Polygon_with_hole_2, Polygon_2 ==============================================
// With Traits
template <typename Kernel, typename Container, typename Traits>
@ -100,25 +106,25 @@ inline bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
Traits& traits)
{ return s_do_intersect(pgn1, pgn2, traits); }
// With Tag_true
// Without traits
template <typename Kernel, typename Container>
inline bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
const Polygon_2<Kernel, Container>& pgn2,
Tag_true = Tag_true())
{ return s_do_intersect(pgn1, pgn2); }
// With Tag_false
template <typename Kernel, typename Container>
inline bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
const Polygon_2<Kernel, Container>& pgn2,
Tag_false)
{
const Polygon_2<Kernel, Container>& pgn2) {
// Use the first polygon to determine the (default) traits
typedef Polygon_with_holes_2<Kernel, Container> Polygon_with_holes;
using Polygon_with_holes = Polygon_with_holes_2<Kernel, Container>;
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
return s_do_intersect(pgn1, pgn2, traits);
}
#ifndef CGAL_NO_DEPRECATED_CODE
template <typename Kernel, typename Container, bool b>
inline bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
const Polygon_2<Kernel, Container>& pgn2,
std::bool_constant<b>) {
return do_intersect(pgn1, pgn2);
}
#endif
// Polygon_with_hole_2, Polygon_with_hole_2 ====================================
// With Traits
template <typename Kernel, typename Container, typename Traits>
@ -127,25 +133,25 @@ inline bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
Traits& traits)
{ return s_do_intersect(pgn1, pgn2, traits); }
// With Tag_true
// Without traits
template <typename Kernel, typename Container>
inline bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
const Polygon_with_holes_2<Kernel, Container>& pgn2,
Tag_true = Tag_true())
{ return s_do_intersect(pgn1, pgn2); }
// With Tag_false
template <typename Kernel, typename Container>
inline bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
const Polygon_with_holes_2<Kernel, Container>& pgn2,
Tag_false)
{
const Polygon_with_holes_2<Kernel, Container>& pgn2) {
// Use the first polygon to determine the (default) traits
typedef Polygon_with_holes_2<Kernel, Container> Polygon_with_holes;
using Polygon_with_holes = Polygon_with_holes_2<Kernel, Container>;
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
return s_do_intersect(pgn1, pgn2, traits);
}
#ifndef CGAL_NO_DEPRECATED_CODE
template <typename Kernel, typename Container, bool b>
inline bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
const Polygon_with_holes_2<Kernel, Container>& pgn2,
std::bool_constant<b>) {
return do_intersect(pgn1, pgn2);
}
#endif
// General_polygon_2, General_polygon_2 ========================================
// With Traits
template <typename ArrTraits, typename GpsTraits>
@ -157,14 +163,22 @@ inline bool do_intersect(const General_polygon_2<ArrTraits>& pgn1,
// Without Traits
template <typename ArrTraits>
inline bool do_intersect(const General_polygon_2<ArrTraits>& pgn1,
const General_polygon_2<ArrTraits>& pgn2)
{
const General_polygon_2<ArrTraits>& pgn2) {
// Use the first polygon to determine the (default) traits
typedef General_polygon_2<ArrTraits> Polygon;
using Polygon = General_polygon_2<ArrTraits>;
typename Gps_default_traits<Polygon>::Traits traits;
return s_do_intersect(pgn1, pgn2, traits);
}
#ifndef CGAL_NO_DEPRECATED_CODE
template <typename ArrTraits, bool b>
inline bool do_intersect(const General_polygon_2<ArrTraits>& pgn1,
const General_polygon_2<ArrTraits>& pgn2,
std::bool_constant<b>) {
return do_intersect(pgn1, pgn2);
}
#endif
// General_polygon_2, General_polygon_with_holes_2 =============================
// With Traits
template <typename ArrTraits, typename GpsTraits>
@ -178,14 +192,23 @@ inline bool do_intersect(const General_polygon_2<ArrTraits>& pgn1,
template <typename ArrTraits>
inline bool do_intersect(const General_polygon_2<ArrTraits>& pgn1,
const General_polygon_with_holes_2
<General_polygon_2<ArrTraits> >& pgn2)
{
<General_polygon_2<ArrTraits> >& pgn2) {
// Use the first polygon to determine the (default) traits
typedef General_polygon_2<ArrTraits> Polygon;
using Polygon = General_polygon_2<ArrTraits>;
typename Gps_default_traits<Polygon>::Traits traits;
return s_do_intersect(pgn1, pgn2, traits);
}
#ifndef CGAL_NO_DEPRECATED_CODE
template <typename ArrTraits, bool b>
inline bool do_intersect(const General_polygon_2<ArrTraits>& pgn1,
const General_polygon_with_holes_2
<General_polygon_2<ArrTraits> >& pgn2,
std::bool_constant<b>) {
return do_intersect(pgn1, pgn2);
}
#endif
// General_polygon_with_holes_2, General_polygon_2 =============================
// With Traits
template <typename ArrTraits, typename GpsTraits>
@ -199,15 +222,25 @@ inline bool do_intersect(const General_polygon_with_holes_2
template <typename ArrTraits>
inline bool do_intersect(const General_polygon_with_holes_2
<General_polygon_2<ArrTraits> >& pgn1,
const General_polygon_2<ArrTraits>& pgn2)
{
const General_polygon_2<ArrTraits>& pgn2) {
// Use the first polygon to determine the (default) traits
typedef General_polygon_2<ArrTraits> Polygon;
typedef General_polygon_with_holes_2<Polygon> Polygon_with_holes;
using Polygon = General_polygon_2<ArrTraits>;
using Polygon_with_holes = General_polygon_with_holes_2<Polygon>;
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
return s_do_intersect(pgn1, pgn2, traits);
}
#ifndef CGAL_NO_DEPRECATED_CODE
template <typename ArrTraits, bool b>
inline bool do_intersect(const General_polygon_with_holes_2
<General_polygon_2<ArrTraits> >& pgn1,
const General_polygon_2<ArrTraits>& pgn2,
std::bool_constant<b>) {
return do_intersect(pgn1, pgn2);
}
#endif
// General_polygon_with_holes_2, General_polygon_with_holes_2 ==================
// With Traits
template <typename Polygon_, typename Traits>
@ -219,14 +252,22 @@ inline bool do_intersect(const General_polygon_with_holes_2<Polygon_>& pgn1,
// Without Traits
template <typename Polygon_>
inline bool do_intersect(const General_polygon_with_holes_2<Polygon_>& pgn1,
const General_polygon_with_holes_2<Polygon_>& pgn2)
{
const General_polygon_with_holes_2<Polygon_>& pgn2) {
// Use the first polygon to determine the (default) traits
typedef General_polygon_with_holes_2<Polygon_> Polygon_with_holes;
using Polygon_with_holes = General_polygon_with_holes_2<Polygon_>;
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
return s_do_intersect(pgn1, pgn2, traits);
}
#ifndef CGAL_NO_DEPRECATED_CODE
template <typename Polygon_, bool b>
inline bool do_intersect(const General_polygon_with_holes_2<Polygon_>& pgn1,
const General_polygon_with_holes_2<Polygon_>& pgn2,
std::bool_constant<b>) {
return do_intersect(pgn1, pgn2);
}
#endif
//@}
/// \name Aggregated do_intersect() functions.
@ -235,26 +276,15 @@ inline bool do_intersect(const General_polygon_with_holes_2<Polygon_>& pgn1,
// With Traits
template <typename InputIterator, typename Traits>
inline bool do_intersect(InputIterator begin, InputIterator end, Traits& traits,
unsigned int k=5,
std::size_t k = 5,
std::enable_if_t<CGAL::is_iterator<InputIterator>::value>* = 0)
{ return r_do_intersect(begin, end, traits, k); }
// Without Traits
// Tag_true => convert to polylines
template <typename InputIterator>
inline bool do_intersect(InputIterator begin, InputIterator end,
Tag_true = Tag_true(), unsigned int k=5,
inline bool do_intersect(InputIterator begin, InputIterator end, std::size_t k = 5,
std::enable_if_t<CGAL::is_iterator<InputIterator>::value>* = 0,
Enable_if_Polygon_2_iterator<InputIterator>* = 0)
{ return r_do_intersect(begin, end, k); }
// Tag_false => do not convert to polylines
template <typename InputIterator>
inline bool do_intersect(InputIterator begin, InputIterator end,
Tag_false, unsigned int k=5,
std::enable_if_t<CGAL::is_iterator<InputIterator>::value>* = 0,
Enable_if_Polygon_2_iterator<InputIterator>* = 0)
{
Enable_if_Polygon_2_iterator<InputIterator>* = 0) {
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
return r_do_intersect(begin, end, traits, k);
}
@ -262,49 +292,57 @@ inline bool do_intersect(InputIterator begin, InputIterator end,
// General polygons or polygons with holes
template <typename InputIterator>
inline bool do_intersect(InputIterator begin, InputIterator end,
unsigned int k=5,
std::size_t k = 5,
std::enable_if_t<CGAL::is_iterator<InputIterator>::value>* = 0,
Disable_if_Polygon_2_iterator<InputIterator>* = 0)
{
Disable_if_Polygon_2_iterator<InputIterator>* = 0) {
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
return do_intersect(begin, end, traits, k);
}
#ifndef CGAL_NO_DEPRECATED_CODE
template <typename InputIterator, bool b>
inline bool do_intersect(InputIterator begin, InputIterator end, std::bool_constant<b>,
std::enable_if_t<CGAL::is_iterator<InputIterator>::value>* = 0) {
return do_intersect(begin, end);
}
#endif
// With Traits
template <typename InputIterator1, typename InputIterator2, typename Traits>
inline bool do_intersect(InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
Traits& traits, unsigned int k=5)
Traits& traits, std::size_t k = 5)
{ return r_do_intersect(begin1, end1, begin2, end2, traits, k); }
// Without Traits
// Tag_true => convert to polylines
template <typename InputIterator1, typename InputIterator2>
inline bool do_intersect (InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
Tag_true = Tag_true(), unsigned int k=5,
Enable_if_Polygon_2_iterator<InputIterator1>* = 0)
{ return r_do_intersect(begin1, end1, begin2, end2, k); }
// Tag_false => do not convert to polylines
template <typename InputIterator1, typename InputIterator2>
inline bool do_intersect (InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
Tag_false, unsigned int k=5,
Enable_if_Polygon_2_iterator<InputIterator1>* = 0)
inline bool do_intersect(InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
std::size_t k = 5,
Enable_if_Polygon_2_iterator<InputIterator1>* = 0)
{ return r_do_intersect(begin1, end1, begin2, end2, k); }
// General polygons or polygons with holes
template <typename InputIterator1, typename InputIterator2>
inline bool do_intersect (InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
unsigned int k=5,
Disable_if_Polygon_2_iterator<InputIterator1>* = 0)
{
inline bool do_intersect(InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
std::size_t k = 5,
Disable_if_Polygon_2_iterator<InputIterator1>* = 0) {
typename Iterator_to_gps_traits<InputIterator1>::Traits traits;
return r_do_intersect(begin1, end1, begin2, end2, traits, k);
}
#ifndef CGAL_NO_DEPRECATED_CODE
template <typename InputIterator1, typename InputIterator2, bool b>
inline bool do_intersect(InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
std::bool_constant<b>,
std::enable_if_t<CGAL::is_iterator<InputIterator1>::value &&
CGAL::is_iterator<InputIterator2>::value >* = 0) {
return do_intersect(begin1, end1, begin2, end2);
}
#endif
//@}
} //namespace CGAL

View File

@ -7,11 +7,10 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s): Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Simon Giraudot <simon.giraudot@geometryfactory.com>
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Simon Giraudot <simon.giraudot@geometryfactory.com>
#ifndef CGAL_BOOLEAN_SET_OPERATIONS_2_INTERSECTION_H
#define CGAL_BOOLEAN_SET_OPERATIONS_2_INTERSECTION_H
@ -33,8 +32,7 @@
#include <CGAL/Boolean_set_operations_2/Polygon_conversions.h>
#include <CGAL/type_traits/is_iterator.h>
namespace CGAL
{
namespace CGAL {
/// \name intersection() functions.
//@{
@ -59,10 +57,9 @@ inline OutputIterator intersection(const Polygon_2<Kernel, Container>& pgn1,
template <typename Kernel, typename Container, typename OutputIterator>
inline OutputIterator intersection(const Polygon_2<Kernel, Container>& pgn1,
const Polygon_2<Kernel, Container>& pgn2,
OutputIterator out, Tag_false)
{
OutputIterator out, Tag_false) {
// Use the first polygon to determine the (default) traits
typedef Polygon_2<Kernel, Container> Polygon;
using Polygon = Polygon_2<Kernel, Container>;
typename Gps_default_traits<Polygon>::Traits traits;
return s_intersection(pgn1, pgn2, out, traits);
}
@ -90,10 +87,9 @@ template <typename Kernel, typename Container, typename OutputIterator>
inline OutputIterator
intersection(const Polygon_2<Kernel, Container>& pgn1,
const Polygon_with_holes_2<Kernel, Container>& pgn2,
OutputIterator out, Tag_false)
{
OutputIterator out, Tag_false) {
// Use the first polygon to determine the (default) traits
typedef Polygon_2<Kernel, Container> Polygon;
using Polygon = Polygon_2<Kernel, Container>;
typename Gps_default_traits<Polygon>::Traits traits;
return s_intersection(pgn1, pgn2, out, traits);
}
@ -121,10 +117,9 @@ template <typename Kernel, typename Container, typename OutputIterator>
inline OutputIterator
intersection(const Polygon_with_holes_2<Kernel, Container>& pgn1,
const Polygon_2<Kernel, Container>& pgn2,
OutputIterator out, Tag_false)
{
OutputIterator out, Tag_false) {
// Use the first polygon to determine the (default) traits
typedef Polygon_with_holes_2<Kernel, Container> Polygon_with_holes;
using Polygon_with_holes = Polygon_with_holes_2<Kernel, Container>;
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
return s_intersection(pgn1, pgn2, out, traits);
}
@ -152,10 +147,9 @@ template <typename Kernel, typename Container, typename OutputIterator>
inline OutputIterator
intersection(const Polygon_with_holes_2<Kernel, Container>& pgn1,
const Polygon_with_holes_2<Kernel, Container>& pgn2,
OutputIterator out, Tag_false)
{
OutputIterator out, Tag_false) {
// Use the first polygon to determine the (default) traits
typedef Polygon_with_holes_2<Kernel, Container> Polygon_with_holes;
using Polygon_with_holes = Polygon_with_holes_2<Kernel, Container>;
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
return s_intersection(pgn1, pgn2, out, traits);
}
@ -172,10 +166,9 @@ inline OutputIterator intersection(const General_polygon_2<ArrTraits>& pgn1,
template <typename ArrTraits, typename OutputIterator>
inline OutputIterator intersection(const General_polygon_2<ArrTraits>& pgn1,
const General_polygon_2<ArrTraits>& pgn2,
OutputIterator out)
{
OutputIterator out) {
// Use the first polygon to determine the (default) traits
typedef General_polygon_2<ArrTraits> Polygon;
using Polygon = General_polygon_2<ArrTraits>;
typename Gps_default_traits<Polygon>::Traits traits;
return s_intersection(pgn1, pgn2, out, traits);
}
@ -194,10 +187,9 @@ template <typename ArrTraits, typename OutputIterator>
inline OutputIterator intersection(const General_polygon_2<ArrTraits>& pgn1,
const General_polygon_with_holes_2
<General_polygon_2<ArrTraits> >& pgn2,
OutputIterator out)
{
OutputIterator out) {
// Use the first polygon to determine the (default) traits
typedef General_polygon_2<ArrTraits> Polygon;
using Polygon = General_polygon_2<ArrTraits>;
typename Gps_default_traits<Polygon>::Traits traits;
return s_intersection(pgn1, pgn2, out, traits);
}
@ -216,11 +208,10 @@ template <typename ArrTraits, typename OutputIterator>
inline OutputIterator intersection(const General_polygon_with_holes_2
<General_polygon_2<ArrTraits> >& pgn1,
const General_polygon_2<ArrTraits>& pgn2,
OutputIterator out)
{
OutputIterator out) {
// Use the first polygon to determine the (default) traits
typedef General_polygon_2<ArrTraits> Polygon;
typedef General_polygon_with_holes_2<Polygon> Polygon_with_holes;
using Polygon = General_polygon_2<ArrTraits>;
using Polygon_with_holes = General_polygon_with_holes_2<Polygon>;
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
return s_intersection(pgn1, pgn2, out, traits);
}
@ -239,10 +230,9 @@ template <typename Polygon_, typename OutputIterator>
inline OutputIterator
intersection(const General_polygon_with_holes_2<Polygon_>& pgn1,
const General_polygon_with_holes_2<Polygon_>& pgn2,
OutputIterator out)
{
OutputIterator out) {
// Use the first polygon to determine the (default) traits
typedef General_polygon_with_holes_2<Polygon_> Polygon_with_holes;
using Polygon_with_holes = General_polygon_with_holes_2<Polygon_>;
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
return s_intersection(pgn1, pgn2, out, traits);
}
@ -256,7 +246,7 @@ intersection(const General_polygon_with_holes_2<Polygon_>& pgn1,
template <typename InputIterator, typename OutputIterator, typename Traits>
inline OutputIterator intersection(InputIterator begin, InputIterator end,
OutputIterator oi, Traits& traits,
unsigned int k=5)
std::size_t k = 5)
{ return r_intersection(begin, end, oi, traits, k); }
// Without Traits
@ -265,7 +255,7 @@ template <typename InputIterator, typename OutputIterator>
inline OutputIterator
intersection(InputIterator begin, InputIterator end,
OutputIterator oi, Tag_true = Tag_true(),
unsigned int k=5,
std::size_t k = 5,
Enable_if_Polygon_2_iterator<InputIterator>* = 0)
{ return r_intersection(begin, end, oi, k); }
@ -273,9 +263,8 @@ intersection(InputIterator begin, InputIterator end,
template <typename InputIterator, typename OutputIterator>
inline OutputIterator
intersection(InputIterator begin, InputIterator end,
OutputIterator oi, Tag_false, unsigned int k=5,
Enable_if_Polygon_2_iterator<InputIterator>* = 0)
{
OutputIterator oi, Tag_false, std::size_t k = 5,
Enable_if_Polygon_2_iterator<InputIterator>* = 0) {
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
return r_intersection(begin, end, oi, traits, k);
}
@ -284,11 +273,10 @@ intersection(InputIterator begin, InputIterator end,
template <typename InputIterator, typename OutputIterator>
inline OutputIterator
intersection(InputIterator begin, InputIterator end,
OutputIterator oi, unsigned int k=5,
OutputIterator oi, std::size_t k = 5,
// workaround to avoid ambiguous calls with kernel functions
std::enable_if_t<CGAL::is_iterator<InputIterator>::value>* = 0,
Disable_if_Polygon_2_iterator<InputIterator>* = 0)
{
Disable_if_Polygon_2_iterator<InputIterator>* = 0) {
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
return r_intersection(begin, end, oi, traits, k);
}
@ -300,7 +288,7 @@ template <typename InputIterator1, typename InputIterator2,
inline OutputIterator intersection(InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
OutputIterator oi, Traits& traits,
unsigned int k=5)
std::size_t k = 5)
{ return r_intersection(begin1, end1, begin2, end2, oi, traits, k); }
// Without Traits
@ -310,7 +298,7 @@ template <typename InputIterator1, typename InputIterator2,
inline OutputIterator
intersection(InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
OutputIterator oi, Tag_true = Tag_true(), unsigned int k=5,
OutputIterator oi, Tag_true = Tag_true(), std::size_t k = 5,
Enable_if_Polygon_2_iterator<InputIterator1>* = 0)
{ return r_intersection(begin1, end1, begin2, end2, oi, k); }
@ -320,9 +308,8 @@ template <typename InputIterator1, typename InputIterator2,
inline OutputIterator
intersection(InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
OutputIterator oi, Tag_false, unsigned int k=5,
Enable_if_Polygon_2_iterator<InputIterator1>* = 0)
{
OutputIterator oi, Tag_false, std::size_t k = 5,
Enable_if_Polygon_2_iterator<InputIterator1>* = 0) {
typename Iterator_to_gps_traits<InputIterator1>::Traits traits;
return r_intersection(begin1, end1, begin2, end2, oi, traits, k);
}
@ -333,9 +320,8 @@ template <typename InputIterator1, typename InputIterator2,
inline OutputIterator
intersection(InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
OutputIterator oi, unsigned int k=5,
Disable_if_Polygon_2_iterator<InputIterator1>* = 0)
{
OutputIterator oi, std::size_t k = 5,
Disable_if_Polygon_2_iterator<InputIterator1>* = 0) {
typename Iterator_to_gps_traits<InputIterator1>::Traits traits;
return r_intersection(begin1, end1, begin2, end2, oi, traits, k);
}

View File

@ -7,11 +7,10 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s): Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Simon Giraudot <simon.giraudot@geometryfactory.com>
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Simon Giraudot <simon.giraudot@geometryfactory.com>
#ifndef CGAL_BOOLEAN_SET_OPERATIONS_2_JOIN_H
#define CGAL_BOOLEAN_SET_OPERATIONS_2_JOIN_H
@ -33,8 +32,7 @@
#include <CGAL/Boolean_set_operations_2/Polygon_conversions.h>
#include <CGAL/type_traits/is_iterator.h>
namespace CGAL
{
namespace CGAL {
/// \name join() functions.
//@{
@ -60,10 +58,9 @@ template <typename Kernel, typename Container>
inline bool join(const Polygon_2<Kernel, Container>& pgn1,
const Polygon_2<Kernel, Container>& pgn2,
Polygon_with_holes_2<Kernel, Container>& res,
Tag_false)
{
Tag_false) {
// Use the first polygon to determine the (default) traits
typedef Polygon_2<Kernel, Container> Polygon;
using Polygon = Polygon_2<Kernel, Container>;
typename Gps_default_traits<Polygon>::Traits traits;
return s_join(pgn1, pgn2, res, traits);
}
@ -89,10 +86,9 @@ template <typename Kernel, typename Container>
inline bool join(const Polygon_2<Kernel, Container>& pgn1,
const Polygon_with_holes_2<Kernel, Container>& pgn2,
Polygon_with_holes_2<Kernel, Container>& res,
Tag_false)
{
Tag_false) {
// Use the first polygon to determine the (default) traits
typedef Polygon_2<Kernel, Container> Polygon;
using Polygon = Polygon_2<Kernel, Container>;
typename Gps_default_traits<Polygon>::Traits traits;
return s_join(pgn1, pgn2, res, traits);
}
@ -118,10 +114,9 @@ template <typename Kernel, typename Container>
inline bool join(const Polygon_with_holes_2<Kernel, Container>& pgn1,
const Polygon_2<Kernel, Container>& pgn2,
Polygon_with_holes_2<Kernel, Container>& res,
Tag_false)
{
Tag_false) {
// Use the first polygon to determine the (default) traits
typedef Polygon_with_holes_2<Kernel, Container> Polygon_with_holes;
using Polygon_with_holes = Polygon_with_holes_2<Kernel, Container>;
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
return s_join(pgn1, pgn2, res, traits);
}
@ -147,10 +142,9 @@ template <typename Kernel, typename Container>
inline bool join(const Polygon_with_holes_2<Kernel, Container>& pgn1,
const Polygon_with_holes_2<Kernel, Container>& pgn2,
Polygon_with_holes_2<Kernel, Container>& res,
Tag_false)
{
Tag_false) {
// Use the first polygon to determine the (default) traits
typedef Polygon_with_holes_2<Kernel, Container> Polygon_with_holes;
using Polygon_with_holes = Polygon_with_holes_2<Kernel, Container>;
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
return s_join(pgn1, pgn2, res, traits);
}
@ -170,10 +164,9 @@ template <typename ArrTraits>
inline bool
join(const General_polygon_2<ArrTraits>& pgn1,
const General_polygon_2<ArrTraits>& pgn2,
General_polygon_with_holes_2<General_polygon_2<ArrTraits> >& res)
{
General_polygon_with_holes_2<General_polygon_2<ArrTraits> >& res) {
// Use the first polygon to determine the (default) traits
typedef General_polygon_2<ArrTraits> Polygon;
using Polygon = General_polygon_2<ArrTraits>;
typename Gps_default_traits<Polygon>::Traits traits;
return s_join(pgn1, pgn2, res, traits);
}
@ -193,10 +186,9 @@ template <typename ArrTraits>
inline bool
join(const General_polygon_2<ArrTraits>& pgn1,
const General_polygon_with_holes_2<General_polygon_2<ArrTraits> >& pgn2,
General_polygon_with_holes_2<General_polygon_2<ArrTraits> >& res)
{
General_polygon_with_holes_2<General_polygon_2<ArrTraits> >& res) {
// Use the first polygon to determine the (default) traits
typedef General_polygon_2<ArrTraits> Polygon;
using Polygon = General_polygon_2<ArrTraits>;
typename Gps_default_traits<Polygon>::Traits traits;
return s_join(pgn1, pgn2, res, traits);
}
@ -216,11 +208,10 @@ template <typename ArrTraits>
inline bool
join(const General_polygon_with_holes_2<General_polygon_2<ArrTraits> >& pgn1,
const General_polygon_2<ArrTraits>& pgn2,
General_polygon_with_holes_2<General_polygon_2<ArrTraits> >& res)
{
General_polygon_with_holes_2<General_polygon_2<ArrTraits> >& res) {
// Use the first polygon to determine the (default) traits
typedef General_polygon_2<ArrTraits> Polygon;
typedef General_polygon_with_holes_2<Polygon> Polygon_with_holes;
using Polygon = General_polygon_2<ArrTraits>;
using Polygon_with_holes = General_polygon_with_holes_2<Polygon>;
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
return s_join(pgn1, pgn2, res, traits);
}
@ -237,10 +228,9 @@ inline bool join(const General_polygon_with_holes_2<Polygon_>& pgn1,
template <typename Polygon_>
inline bool join(const General_polygon_with_holes_2<Polygon_>& pgn1,
const General_polygon_with_holes_2<Polygon_>& pgn2,
General_polygon_with_holes_2<Polygon_>& res)
{
General_polygon_with_holes_2<Polygon_>& res) {
// Use the first polygon to determine the (default) traits
typedef General_polygon_with_holes_2<Polygon_> Polygon_with_holes;
using Polygon_with_holes = General_polygon_with_holes_2<Polygon_>;
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
return s_join(pgn1, pgn2, res, traits);
}
@ -253,7 +243,7 @@ inline bool join(const General_polygon_with_holes_2<Polygon_>& pgn1,
// With Traits
template <typename InputIterator, typename OutputIterator, typename Traits>
inline OutputIterator join(InputIterator begin, InputIterator end,
OutputIterator oi, Traits& traits, unsigned int k=5)
OutputIterator oi, Traits& traits, std::size_t k = 5)
{ return r_join(begin, end, oi, traits, k); }
// Without Traits
@ -261,16 +251,15 @@ inline OutputIterator join(InputIterator begin, InputIterator end,
template <typename InputIterator, typename OutputIterator>
inline OutputIterator join(InputIterator begin, InputIterator end,
OutputIterator oi, Tag_true = Tag_true(),
unsigned int k=5,
std::size_t k = 5,
Enable_if_Polygon_2_iterator<InputIterator>* = 0)
{ return r_join(begin, end, oi, k); }
// Tag_false => do not convert to polylines
template <typename InputIterator, typename OutputIterator>
inline OutputIterator join(InputIterator begin, InputIterator end,
OutputIterator oi, Tag_false, unsigned int k=5,
Enable_if_Polygon_2_iterator<InputIterator>* = 0)
{
OutputIterator oi, Tag_false, std::size_t k = 5,
Enable_if_Polygon_2_iterator<InputIterator>* = 0) {
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
return r_join(begin, end, oi, traits, k);
}
@ -278,9 +267,8 @@ inline OutputIterator join(InputIterator begin, InputIterator end,
// General polygons or polygons with holes
template <typename InputIterator, typename OutputIterator>
inline OutputIterator join(InputIterator begin, InputIterator end,
OutputIterator oi, unsigned int k=5,
Disable_if_Polygon_2_iterator<InputIterator>* = 0)
{
OutputIterator oi, std::size_t k = 5,
Disable_if_Polygon_2_iterator<InputIterator>* = 0) {
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
return r_join(begin, end, oi, traits, k);
}
@ -291,7 +279,7 @@ template <typename InputIterator1, typename InputIterator2,
typename OutputIterator, typename Traits>
inline OutputIterator join(InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
OutputIterator oi, Traits& traits, unsigned int k=5)
OutputIterator oi, Traits& traits, std::size_t k = 5)
{ return r_join(begin1, end1, begin2, end2, oi, traits, k); }
// Without Traits
@ -301,7 +289,7 @@ template <typename InputIterator1, typename InputIterator2,
inline OutputIterator join(InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
OutputIterator oi, Tag_true = Tag_true(),
unsigned int k=5,
std::size_t k = 5,
Enable_if_Polygon_2_iterator<InputIterator1>* = 0)
{ return r_join(begin1, end1, begin2, end2, oi, k); }
@ -310,9 +298,8 @@ template <typename InputIterator1, typename InputIterator2,
typename OutputIterator>
inline OutputIterator join(InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
OutputIterator oi, Tag_false, unsigned int k=5,
Enable_if_Polygon_2_iterator<InputIterator1>* = 0)
{
OutputIterator oi, Tag_false, std::size_t k = 5,
Enable_if_Polygon_2_iterator<InputIterator1>* = 0) {
typename Iterator_to_gps_traits<InputIterator1>::Traits traits;
return r_join(begin1, end1, begin2, end2, oi, traits, k);
}
@ -322,9 +309,8 @@ template <typename InputIterator1, typename InputIterator2,
typename OutputIterator>
inline OutputIterator join(InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
OutputIterator oi, unsigned int k=5,
Disable_if_Polygon_2_iterator<InputIterator1>* = 0)
{
OutputIterator oi, std::size_t k = 5,
Disable_if_Polygon_2_iterator<InputIterator1>* = 0) {
typename Iterator_to_gps_traits<InputIterator1>::Traits traits;
return r_join(begin1, end1, begin2, end2, oi, traits, k);
}

View File

@ -7,11 +7,10 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s): Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Simon Giraudot <simon.giraudot@geometryfactory.com>
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Simon Giraudot <simon.giraudot@geometryfactory.com>
#ifndef CGAL_BOOLEAN_SET_OPERATIONS_SYMMETRIC_DIFFERENCE_H
#define CGAL_BOOLEAN_SET_OPERATIONS_SYMMETRIC_DIFFERENCE_H
@ -33,8 +32,7 @@
#include <CGAL/Boolean_set_operations_2/Polygon_conversions.h>
#include <CGAL/type_traits/is_iterator.h>
namespace CGAL
{
namespace CGAL {
/// \name symmetric_difference() functions.
//@{
@ -62,10 +60,9 @@ template <typename Kernel, typename Container, typename OutputIterator>
inline OutputIterator
symmetric_difference(const Polygon_2<Kernel, Container>& pgn1,
const Polygon_2<Kernel, Container>& pgn2,
OutputIterator oi, Tag_false)
{
OutputIterator oi, Tag_false) {
// Use the first polygon to determine the (default) traits
typedef Polygon_2<Kernel, Container> Polygon;
using Polygon = Polygon_2<Kernel, Container>;
typename Gps_default_traits<Polygon>::Traits traits;
return s_symmetric_difference(pgn1, pgn2, oi, traits);
}
@ -93,10 +90,9 @@ template <typename Kernel, typename Container, typename OutputIterator>
inline OutputIterator
symmetric_difference(const Polygon_2<Kernel, Container>& pgn1,
const Polygon_with_holes_2<Kernel, Container>& pgn2,
OutputIterator oi, Tag_false)
{
OutputIterator oi, Tag_false) {
// Use the first polygon to determine the (default) traits
typedef Polygon_2<Kernel, Container> Polygon;
using Polygon = Polygon_2<Kernel, Container>;
typename Gps_default_traits<Polygon>::Traits traits;
return s_symmetric_difference(pgn1, pgn2, oi, traits);
}
@ -124,10 +120,9 @@ template <typename Kernel, typename Container, typename OutputIterator>
inline OutputIterator
symmetric_difference(const Polygon_with_holes_2<Kernel, Container>& pgn1,
const Polygon_2<Kernel, Container>& pgn2,
OutputIterator oi, Tag_false)
{
OutputIterator oi, Tag_false) {
// Use the first polygon to determine the (default) traits
typedef Polygon_with_holes_2<Kernel, Container> Polygon_with_holes;
using Polygon_with_holes = Polygon_with_holes_2<Kernel, Container>;
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
return s_symmetric_difference(pgn1, pgn2, oi, traits);
}
@ -155,10 +150,9 @@ template <typename Kernel, typename Container, typename OutputIterator>
inline OutputIterator
symmetric_difference(const Polygon_with_holes_2<Kernel, Container>& pgn1,
const Polygon_with_holes_2<Kernel, Container>& pgn2,
OutputIterator oi, Tag_false)
{
OutputIterator oi, Tag_false) {
// Use the first polygon to determine the (default) traits
typedef Polygon_with_holes_2<Kernel, Container> Polygon_with_holes;
using Polygon_with_holes = Polygon_with_holes_2<Kernel, Container>;
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
return s_symmetric_difference(pgn1, pgn2, oi, traits);
}
@ -176,10 +170,9 @@ template <typename ArrTraits, typename OutputIterator>
inline OutputIterator
symmetric_difference(const General_polygon_2<ArrTraits>& pgn1,
const General_polygon_2<ArrTraits>& pgn2,
OutputIterator oi)
{
OutputIterator oi) {
// Use the first polygon to determine the (default) traits
typedef General_polygon_2<ArrTraits> Polygon;
using Polygon = General_polygon_2<ArrTraits>;
typename Gps_default_traits<Polygon>::Traits traits;
return s_symmetric_difference(pgn1, pgn2, oi, traits);
}
@ -200,10 +193,9 @@ inline OutputIterator
symmetric_difference(const General_polygon_2<ArrTraits>& pgn1,
const General_polygon_with_holes_2
<General_polygon_2<ArrTraits> >& pgn2,
OutputIterator oi)
{
OutputIterator oi) {
// Use the first polygon to determine the (default) traits
typedef General_polygon_2<ArrTraits> Polygon;
using Polygon = General_polygon_2<ArrTraits>;
typename Gps_default_traits<Polygon>::Traits traits;
return s_symmetric_difference(pgn1, pgn2, oi, traits);
}
@ -224,11 +216,10 @@ inline OutputIterator
symmetric_difference(const General_polygon_with_holes_2
<General_polygon_2<ArrTraits> >& pgn1,
const General_polygon_2<ArrTraits>& pgn2,
OutputIterator oi)
{
OutputIterator oi) {
// Use the first polygon to determine the (default) traits
typedef General_polygon_2<ArrTraits> Polygon;
typedef General_polygon_with_holes_2<Polygon> Polygon_with_holes;
using Polygon = General_polygon_2<ArrTraits>;
using Polygon_with_holes = General_polygon_with_holes_2<Polygon>;
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
return s_symmetric_difference(pgn1, pgn2, oi, traits);
}
@ -247,9 +238,8 @@ template <typename Polygon_, typename OutputIterator>
inline OutputIterator
symmetric_difference(const General_polygon_with_holes_2<Polygon_>& pgn1,
const General_polygon_with_holes_2<Polygon_>& pgn2,
OutputIterator oi)
{
typedef General_polygon_with_holes_2<Polygon_> Polygon_with_holes;
OutputIterator oi) {
using Polygon_with_holes = General_polygon_with_holes_2<Polygon_>;
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
return s_symmetric_difference(pgn1, pgn2, oi, traits);
}
@ -264,7 +254,7 @@ template <typename InputIterator, typename OutputIterator, typename Traits>
inline
OutputIterator symmetric_difference(InputIterator begin, InputIterator end,
OutputIterator oi, Traits& traits,
unsigned int k=5)
std::size_t k = 5)
{ return r_symmetric_difference(begin, end, oi, traits, k); }
// Without Traits
@ -272,7 +262,7 @@ OutputIterator symmetric_difference(InputIterator begin, InputIterator end,
template <typename InputIterator, typename OutputIterator>
inline OutputIterator
symmetric_difference(InputIterator begin, InputIterator end,
OutputIterator oi, Tag_true = Tag_true(), unsigned int k=5,
OutputIterator oi, Tag_true = Tag_true(), std::size_t k = 5,
Enable_if_Polygon_2_iterator<InputIterator>* = 0)
{ return r_symmetric_difference(begin, end, oi, k); }
@ -280,9 +270,8 @@ symmetric_difference(InputIterator begin, InputIterator end,
template <typename InputIterator, typename OutputIterator>
inline OutputIterator
symmetric_difference(InputIterator begin, InputIterator end,
OutputIterator oi, Tag_false, unsigned int k=5,
Enable_if_Polygon_2_iterator<InputIterator>* = 0)
{
OutputIterator oi, Tag_false, std::size_t k = 5,
Enable_if_Polygon_2_iterator<InputIterator>* = 0) {
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
return r_symmetric_difference(begin, end, oi, traits, k);
}
@ -291,9 +280,8 @@ symmetric_difference(InputIterator begin, InputIterator end,
template <typename InputIterator, typename OutputIterator>
inline OutputIterator
symmetric_difference(InputIterator begin, InputIterator end,
OutputIterator oi, unsigned int k=5,
Disable_if_Polygon_2_iterator<InputIterator>* = 0)
{
OutputIterator oi, std::size_t k = 5,
Disable_if_Polygon_2_iterator<InputIterator>* = 0) {
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
return r_symmetric_difference(begin, end, oi, traits, k);
}
@ -306,7 +294,7 @@ inline
OutputIterator symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
OutputIterator oi, Traits& traits,
unsigned int k=5)
std::size_t k = 5)
{ return r_symmetric_difference(begin1, end1, begin2, end2, oi, traits, k); }
// Without Traits
@ -316,7 +304,7 @@ template <typename InputIterator1, typename InputIterator2,
inline OutputIterator
symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
OutputIterator oi, Tag_true = Tag_true(), unsigned int k=5,
OutputIterator oi, Tag_true = Tag_true(), std::size_t k = 5,
Enable_if_Polygon_2_iterator<InputIterator1>* = 0)
{ return r_symmetric_difference(begin1, end1, begin2, end2, oi, k); }
@ -326,9 +314,8 @@ template <typename InputIterator1, typename InputIterator2,
inline OutputIterator
symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
OutputIterator oi, Tag_false, unsigned int k=5,
Enable_if_Polygon_2_iterator<InputIterator1>* = 0)
{
OutputIterator oi, Tag_false, std::size_t k = 5,
Enable_if_Polygon_2_iterator<InputIterator1>* = 0) {
typename Iterator_to_gps_traits<InputIterator1>::Traits traits;
return r_symmetric_difference(begin1, end1, begin2, end2, oi, traits, k);
}
@ -339,9 +326,8 @@ template <typename InputIterator1, typename InputIterator2,
inline OutputIterator
symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
OutputIterator oi, unsigned int k=5,
Disable_if_Polygon_2_iterator<InputIterator1>* = 0)
{
OutputIterator oi, std::size_t k = 5,
Disable_if_Polygon_2_iterator<InputIterator1>* = 0) {
typename Iterator_to_gps_traits<InputIterator1>::Traits traits;
return r_symmetric_difference(begin1, end1, begin2, end2, oi, traits, k);
}

View File

@ -7,8 +7,8 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
#ifndef CGAL_GENERAL_POLYGON_SET_2_H
#define CGAL_GENERAL_POLYGON_SET_2_H
@ -27,25 +27,20 @@
namespace CGAL {
// General_polygon_set_2
template <class Traits_, class Dcel_ = Gps_default_dcel<Traits_> >
class General_polygon_set_2 : public General_polygon_set_on_surface_2
<Traits_, typename Default_planar_topology<Traits_, Dcel_>::Traits>
{
protected:
typedef General_polygon_set_2<Traits_, Dcel_> Self;
template <typename Traits_, typename Dcel_ = Gps_default_dcel<Traits_>>
class General_polygon_set_2 :
public General_polygon_set_on_surface_2<
Traits_, typename Default_planar_topology<Traits_, Dcel_>::Traits> {
public:
typedef Traits_ Traits_2;
typedef Dcel_ Dcel;
typedef General_polygon_set_on_surface_2 <Traits_2,
typename Default_planar_topology<Traits_2, Dcel >::Traits>
Base;
typedef CGAL::Arrangement_2<Traits_2, Dcel> Arrangement_2;
typedef typename Base::Polygon_2 Polygon_2;
typedef typename Base::Polygon_with_holes_2 Polygon_with_holes_2;
using Traits_2 = Traits_;
using Dcel = Dcel_;
using Self = General_polygon_set_2<Traits_2, Dcel>;
using Topology_traits = typename Default_planar_topology<Traits_2, Dcel>::Traits;
using Base = General_polygon_set_on_surface_2<Traits_2, Topology_traits>;
using Arrangement_2 = CGAL::Arrangement_2<Traits_2, Dcel>;
using Polygon_2 = typename Base::Polygon_2;
using Polygon_with_holes_2 = typename Base::Polygon_with_holes_2;
// default constructor
General_polygon_set_2() : Base() {}
@ -80,19 +75,16 @@ public:
using Base::join;
using Base::symmetric_difference;
inline void intersection(const Self& ps1, const Self& ps2)
{
inline void intersection(const Self& ps1, const Self& ps2) {
Base::intersection(static_cast<const Base&>(ps1),
static_cast<const Base&>(ps2));
}
inline void join(const Self& ps1, const Self& ps2)
{
inline void join(const Self& ps1, const Self& ps2) {
Base::join(static_cast<const Base&>(ps1), static_cast<const Base&>(ps2));
}
inline void symmetric_difference(const Self& ps1, const Self& ps2)
{
inline void symmetric_difference(const Self& ps1, const Self& ps2) {
Base::symmetric_difference(static_cast<const Base&>(ps1),
static_cast<const Base&>(ps2));
}

View File

@ -7,8 +7,8 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Author(s): Baruch Zukerman <baruchzu@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Ophir Setter <ophir.setter@cs.tau.ac.il>
#ifndef CGAL_GENERAL_POLYGON_SET_ON_SURFACE_2_H
@ -23,54 +23,48 @@
namespace CGAL {
namespace Boolean_set_operation_2_internal
{
struct PreconditionValidationPolicy
{
/*! is_valid - Checks if a Traits::Polygon_2 OR
Traits::Polygon_with_holes_2 are valid.
This validation policy checks that polygons are valid in a
CGAL_precondition macro. We inherit from Gps_on_surface_base_2
and use preconditions to validate the input polygons.
namespace Boolean_set_operation_2_internal {
struct PreconditionValidationPolicy {
/*! Checks if a Traits::Polygon_2 or Traits::Polygon_with_holes_2 are valid.
* This validation policy checks that polygons are valid in a
* CGAL_precondition macro. We inherit from Gps_on_surface_base_2 and use
* preconditions to validate the input polygons.
*/
template <class Polygon, class Traits>
inline static void is_valid(const Polygon& p, const Traits& t)
{
CGAL_precondition(is_valid_unknown_polygon(p, t));
CGAL_USE(p); CGAL_USE(t);
}
};
template <typename Polygon, typename Traits>
inline static void is_valid(const Polygon& p, const Traits& t) {
CGAL_precondition(is_valid_unknown_polygon(p, t));
CGAL_USE(p); CGAL_USE(t);
}
};
}
// General_polygon_set_on_surface_2
/*
This class is derived from Gps_on_surface_base_2.
It enforces the validation conditions for general polygons, and is therefore
the basic implementation that should be used by the user
*/
template <class Traits_, class TopTraits_>
class General_polygon_set_on_surface_2 :
public Gps_on_surface_base_2<Traits_, TopTraits_,
Boolean_set_operation_2_internal::PreconditionValidationPolicy>
{
/* `General_polygon_set_on_surface_2` class is derived from
* `Gps_on_surface_base_2`. It enforces the validation conditions for general
* polygons, and is therefore the basic implementation that should be used by
* the user
*/
template <typename Traits_, typename TopTraits_>
class General_polygon_set_on_surface_2 :
public Gps_on_surface_base_2<
Traits_, TopTraits_,
Boolean_set_operation_2_internal::PreconditionValidationPolicy> {
protected:
typedef Traits_ Traits_2;
typedef General_polygon_set_on_surface_2<Traits_2, TopTraits_> Self;
typedef Gps_on_surface_base_2<Traits_2, TopTraits_,
Boolean_set_operation_2_internal::PreconditionValidationPolicy> Base;
using Traits_2 = Traits_;
using Self = General_polygon_set_on_surface_2<Traits_2, TopTraits_>;
using Base = Gps_on_surface_base_2<Traits_2, TopTraits_,
Boolean_set_operation_2_internal::PreconditionValidationPolicy>;
public:
typedef typename Base::Polygon_2 Polygon_2;
typedef typename Base::Polygon_with_holes_2
Polygon_with_holes_2;
typedef typename Base::Arrangement_on_surface_2
Arrangement_on_surface_2;
using Polygon_2 = typename Base::Polygon_2;
using Polygon_with_holes_2 = typename Base::Polygon_with_holes_2;
using Arrangement_on_surface_2 = typename Base::Arrangement_on_surface_2;
public:
// default constructor
General_polygon_set_on_surface_2() : Base()
{}
General_polygon_set_on_surface_2() : Base() {}
// constructor from a traits object
General_polygon_set_on_surface_2(const Traits_2& traits) : Base(traits) {}
@ -79,8 +73,7 @@ public:
General_polygon_set_on_surface_2(const Self& ps) : Base(ps) {}
// assignment operator
General_polygon_set_on_surface_2& operator=(const Self& ps)
{
General_polygon_set_on_surface_2& operator=(const Self& ps) {
Base::operator=(ps);
return (*this);
}
@ -90,19 +83,15 @@ public:
// constructor from a polygon with holes
explicit
General_polygon_set_on_surface_2(const Polygon_with_holes_2& pwh) :
Base(pwh)
{}
General_polygon_set_on_surface_2(const Polygon_with_holes_2& pwh) : Base(pwh) {}
// constructor from a polygon and a traits object
explicit General_polygon_set_on_surface_2(const Polygon_2& pgn,
const Traits_2& traits) :
explicit General_polygon_set_on_surface_2(const Polygon_2& pgn, const Traits_2& traits) :
Base(pgn, traits) {}
// constructor from a polygon with holes and a traits object
explicit
General_polygon_set_on_surface_2(const Polygon_with_holes_2& pwh,
const Traits_2& traits) :
General_polygon_set_on_surface_2(const Polygon_with_holes_2& pwh, const Traits_2& traits) :
Base(pwh, traits)
{}
@ -142,4 +131,4 @@ private:
#include <CGAL/enable_warnings.h>
#endif // CGAL_GENERAL_POLYGON_SET_ON_SURFACE_2_H
#endif

View File

@ -1,48 +0,0 @@
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Boolean_set_operations_2.h>
#include <CGAL/Polygon_set_2.h>
#include <list>
typedef CGAL::Exact_predicates_exact_constructions_kernel K;
int main()
{
CGAL::Polygon_2<K> ob;
ob.push_back(CGAL::Point_2<K>(1, 1));
ob.push_back(CGAL::Point_2<K>(1, 0));
ob.push_back(CGAL::Point_2<K>(6, 0));
ob.push_back(CGAL::Point_2<K>(6, 7));
ob.push_back(CGAL::Point_2<K>(0, 7));
ob.push_back(CGAL::Point_2<K>(0, 1));
CGAL::Polygon_2<K> h;
h.push_back(CGAL::Point_2<K>(2, 1));
h.push_back(CGAL::Point_2<K>(2, 2));
h.push_back(CGAL::Point_2<K>(3, 2));
h.push_back(CGAL::Point_2<K>(3, 3));
h.push_back(CGAL::Point_2<K>(2, 3));
h.push_back(CGAL::Point_2<K>(2, 4));
h.push_back(CGAL::Point_2<K>(3, 4));
h.push_back(CGAL::Point_2<K>(3, 5));
h.push_back(CGAL::Point_2<K>(4, 5));
h.push_back(CGAL::Point_2<K>(4, 1));
CGAL::Polygon_with_holes_2<K> ob_with_holes(ob);
ob_with_holes.add_hole(h);
CGAL::Polygon_set_2<K> inter(ob_with_holes);
CGAL::Polygon_2<K> new_poly;
new_poly.push_back(CGAL::Point_2<K>(1, 1));
new_poly.push_back(CGAL::Point_2<K>(2, 1));
new_poly.push_back(CGAL::Point_2<K>(2, 2));
new_poly.push_back(CGAL::Point_2<K>(2, 3));
new_poly.push_back(CGAL::Point_2<K>(2, 4));
new_poly.push_back(CGAL::Point_2<K>(2, 5));
new_poly.push_back(CGAL::Point_2<K>(3, 5));
new_poly.push_back(CGAL::Point_2<K>(4, 5));
new_poly.push_back(CGAL::Point_2<K>(4, 6));
new_poly.push_back(CGAL::Point_2<K>(1, 6));
inter.difference(new_poly);
}

View File

@ -1,4 +1,3 @@
#include <vector>
#include <CGAL/Simple_cartesian.h>
@ -13,35 +12,32 @@
#include <CGAL/Polygon_set_2.h>
//typedef CGAL::Quotient<CGAL::MP_Float> Number_type;
typedef int Number_type;
using Number_type = int;
typedef CGAL::Simple_cartesian<Number_type> Kernel;
using Kernel = CGAL::Simple_cartesian<Number_type>;
typedef CGAL::Gps_segment_traits_2<Kernel> Traits;
typedef CGAL::Polygon_set_2<Kernel> Ps;
using Traits = CGAL::Gps_segment_traits_2<Kernel>;
using Ps = CGAL::Polygon_set_2<Kernel>;
typedef CGAL::Arr_segment_traits_2<Kernel> Arr_traits;
typedef CGAL::Gps_traits_2<Arr_traits> General_traits;
typedef CGAL::General_polygon_set_2<General_traits> Gps;
using Arr_traits = CGAL::Arr_segment_traits_2<Kernel>;
using General_traits = CGAL::Gps_traits_2<Arr_traits>;
using Gps = CGAL::General_polygon_set_2<General_traits>;
typedef CGAL::Arr_non_caching_segment_traits_2<Kernel> Nc_traits;
typedef CGAL::Gps_segment_traits_2<Kernel,
std::vector<Kernel::Point_2>,
Nc_traits> Traits_non_caching;
typedef CGAL::General_polygon_set_2<Traits_non_caching> Gps_non_caching;
using Nc_traits = CGAL::Arr_non_caching_segment_traits_2<Kernel>;
using Traits_non_caching = CGAL::Gps_segment_traits_2<Kernel, std::vector<Kernel::Point_2>, Nc_traits>;
using Gps_non_caching = CGAL::General_polygon_set_2<Traits_non_caching>;
template <class GPS>
void test()
{
typedef typename GPS::Traits_2 Traits;
typedef typename Traits::Point_2 Point_2;
typedef typename Traits::Polygon_2 Polygon_2;
typedef typename Traits::Polygon_with_holes_2 Polygon_with_holes_2;
template <typename GPS>
void test() {
using Traits = typename GPS::Traits_2;
using Point_2 = typename Traits::Point_2;
using Polygon_2 = typename Traits::Polygon_2;
using Polygon_with_holes_2 = typename Traits::Polygon_with_holes_2;
Polygon_2 pgn1, pgn2;
Polygon_with_holes_2 pgn_with_holes1, pgn_with_holes2;
std::vector<Polygon_2> polygons;
std::vector<Polygon_with_holes_2> polygons_with_holes;
Polygon_with_holes_2 pgn_with_holes1, pgn_with_holes2;
std::vector<Polygon_2> polygons;
std::vector<Polygon_with_holes_2> polygons_with_holes;
GPS gps;
GPS other;
@ -242,8 +238,7 @@ void test()
GPS new_gps2 = gps;
}
void test_CGAL_Polygon_variants()
{
void test_CGAL_Polygon_variants() {
typedef CGAL::Polygon_2<Kernel> Polygon_2;
typedef CGAL::Polygon_with_holes_2<Kernel> Polygon_with_holes_2;
typedef CGAL::Gps_default_traits<Polygon_2>::Traits Traits;
@ -257,45 +252,25 @@ void test_CGAL_Polygon_variants()
Traits tr;
CGAL::do_intersect(pgn1, pgn2);
CGAL::do_intersect(pgn1, pgn2, CGAL::Tag_true());
CGAL::do_intersect(pgn1, pgn2, CGAL::Tag_false());
CGAL::do_intersect(pgn1, pgn2, tr);
CGAL::do_intersect(pgn1, pgn_with_holes2);
CGAL::do_intersect(pgn1, pgn_with_holes2, CGAL::Tag_true());
CGAL::do_intersect(pgn1, pgn_with_holes2, CGAL::Tag_false());
CGAL::do_intersect(pgn1, pgn_with_holes2, tr);
CGAL::do_intersect(pgn_with_holes1, pgn2);
CGAL::do_intersect(pgn_with_holes1, pgn2, CGAL::Tag_true());
CGAL::do_intersect(pgn_with_holes1, pgn2, CGAL::Tag_false());
CGAL::do_intersect(pgn_with_holes1, pgn2, tr);
CGAL::do_intersect(pgn_with_holes1, pgn_with_holes2);
CGAL::do_intersect(pgn_with_holes1, pgn_with_holes2, CGAL::Tag_true());
CGAL::do_intersect(pgn_with_holes1, pgn_with_holes2, CGAL::Tag_false());
CGAL::do_intersect(pgn_with_holes1, pgn_with_holes2, tr);
CGAL::do_intersect(polygons.begin(), polygons.end());
CGAL::do_intersect(polygons.begin(), polygons.end(), CGAL::Tag_true());
CGAL::do_intersect(polygons.begin(), polygons.end(), CGAL::Tag_false());
CGAL::do_intersect(polygons.begin(), polygons.end(), tr);
CGAL::do_intersect(polygons_with_holes.begin(), polygons_with_holes.end());
CGAL::do_intersect(polygons_with_holes.begin(), polygons_with_holes.end(),
CGAL::Tag_true());
CGAL::do_intersect(polygons_with_holes.begin(), polygons_with_holes.end(),
CGAL::Tag_false());
CGAL::do_intersect(polygons_with_holes.begin(), polygons_with_holes.end(), tr);
CGAL::do_intersect(polygons.begin(), polygons.end(),
polygons_with_holes.begin(), polygons_with_holes.end());
CGAL::do_intersect(polygons.begin(), polygons.end(),
polygons_with_holes.begin(), polygons_with_holes.end(),
CGAL::Tag_true());
CGAL::do_intersect(polygons.begin(), polygons.end(),
polygons_with_holes.begin(), polygons_with_holes.end(),
CGAL::Tag_false());
CGAL::do_intersect(polygons.begin(), polygons.end(),
polygons_with_holes.begin(), polygons_with_holes.end(), tr);
@ -519,8 +494,7 @@ void test_CGAL_Polygon_variants()
CGAL::complement(pgn_with_holes1, std::back_inserter(result), tr);
}
int main()
{
int main() {
test<Gps>();
test<Ps>();
test<Gps_non_caching>();

View File

@ -0,0 +1,94 @@
#include <iostream>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Boolean_set_operations_2.h>
#include <CGAL/Arr_circle_segment_traits_2.h>
#include <CGAL/General_polygon_2.h>
#include <CGAL/Boolean_set_operations_2.h>
// #include <CGAL/draw_arrangement_2.h>
using Kernel = CGAL::Exact_predicates_exact_constructions_kernel;
using Point_2 = Kernel::Point_2;
using Polygon_2 = CGAL::Polygon_2<Kernel>;
using Circle_2 = Kernel::Circle_2;
int main() {
Kernel kernel;
auto ctr_circle = kernel.construct_circle_2_object();
auto circle1 = ctr_circle(Point_2(0, 1), 1);
auto circle2 = ctr_circle(Point_2(0, -1), 1);
auto circle3 = ctr_circle(Point_2(0, 2), 4);
// 1. Circular arcs and linear segments
using Circle_segment_arr_traits_2 = CGAL::Arr_circle_segment_traits_2<Kernel>;
using Circle_segment_xcv_2 = Circle_segment_arr_traits_2::X_monotone_curve_2;
using Circle_segment_pnt_2 = Circle_segment_arr_traits_2::Point_2;
using Circle_segment_gps_traits_2 = CGAL::Gps_traits_2<Circle_segment_arr_traits_2>;
using Circle_segment_polygon = Circle_segment_gps_traits_2::General_polygon_2;
Circle_segment_arr_traits_2 circle_segment_traits;
Circle_segment_pnt_2 cs_pnt11(1, 1);
Circle_segment_pnt_2 cs_pnt12(-1, 1);
Circle_segment_xcv_2 xcv11(circle1, cs_pnt11, cs_pnt12, CGAL::COUNTERCLOCKWISE);
Circle_segment_xcv_2 xcv12(circle1, cs_pnt12, cs_pnt11, CGAL::COUNTERCLOCKWISE);
Circle_segment_polygon pgn1;
pgn1.push_back(xcv11);
pgn1.push_back(xcv12);
Circle_segment_pnt_2 cs_pnt21(1, -1);
Circle_segment_pnt_2 cs_pnt22(-1, -1);
Circle_segment_xcv_2 xcv21(circle2, cs_pnt21, cs_pnt22, CGAL::COUNTERCLOCKWISE);
Circle_segment_xcv_2 xcv22(circle2, cs_pnt22, cs_pnt21, CGAL::COUNTERCLOCKWISE);
Circle_segment_polygon pgn2;
pgn2.push_back(xcv21);
pgn2.push_back(xcv22);
Circle_segment_pnt_2 cs_pnt31(2, 2);
Circle_segment_pnt_2 cs_pnt32(-2, 2);
Circle_segment_xcv_2 xcv31(circle3, cs_pnt31, cs_pnt32, CGAL::COUNTERCLOCKWISE);
Circle_segment_xcv_2 xcv32(circle3, cs_pnt32, cs_pnt31, CGAL::COUNTERCLOCKWISE);
Circle_segment_polygon pgn3;
pgn3.push_back(xcv31);
pgn3.push_back(xcv32);
// 1.1.
auto do_intersect = CGAL::do_intersect(pgn1, pgn2);
if (do_intersect) {
std::cerr << "The circles intersect (case 1)\n" << std::endl;
return 1;
}
// 1.2.
std::vector<Circle_segment_polygon> pgns1 = { pgn1, pgn2 };
do_intersect = CGAL::do_intersect(pgns1.begin(), pgns1.end());
if (do_intersect) {
std::cerr << "The circles intersect (case 2)\n" << std::endl;
return 1;
}
// 2.1.
do_intersect = CGAL::do_intersect(pgn1, pgn3);
if (! do_intersect) {
std::cerr << "The circles do not intersect (case 1)\n" << std::endl;
return 1;
}
// 2.2.
std::vector<Circle_segment_polygon> pgns2 = { pgn1, pgn3 };
do_intersect = CGAL::do_intersect(pgns2.begin(), pgns2.end());
if (! do_intersect) {
std::cerr << "The circles do not intersect (case 2)\n" << std::endl;
return 1;
}
// using Circle_segment_arr = CGAL::Arrangement_2<Circle_segment_arr_traits_2>;
// Circle_segment_arr arr;
// CGAL::insert_non_intersecting_curve(arr, xcv11);
// CGAL::insert_non_intersecting_curve(arr, xcv12);
// CGAL::insert_non_intersecting_curve(arr, xcv21);
// CGAL::insert_non_intersecting_curve(arr, xcv22);
// CGAL::draw(arr);
return 0;
}

View File

@ -4,7 +4,7 @@ project(Approximate_min_ellipsoid_d_Examples)
find_package(CGAL REQUIRED)
# Use Eigen
find_package(Eigen3 3.1.0 QUIET) #(3.1.0 or greater)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
# create a target per cppfile

View File

@ -7,7 +7,7 @@ project(Bounding_volumes_Tests)
find_package(CGAL REQUIRED COMPONENTS Core)
# Use Eigen
find_package(Eigen3 3.1.0 QUIET) #(3.1.0 or greater)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
# create a target per cppfile

View File

@ -20,8 +20,9 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
find_package(CGAL REQUIRED COMPONENTS Core)
find_package(Eigen3 3.1.0 QUIET) #(requires 3.1.0 or greater)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
if(NOT TARGET CGAL::Eigen3_support)
message("NOTICE: This project requires the Eigen library, and will not be compiled.")
return()

View File

@ -23,8 +23,9 @@ if(NOT TARGET CGAL::Boost_iostreams_support)
set(Classification_dependencies_met FALSE)
endif()
find_package(Eigen3 3.1.0 QUIET) #(3.1.0 or greater)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
if(NOT TARGET CGAL::Eigen3_support)
message("NOTICE: This project requires the Eigen library, and will not be compiled.")
set(Classification_dependencies_met FALSE)

View File

@ -23,8 +23,9 @@ if(NOT TARGET CGAL::Boost_iostreams_support)
set(Classification_dependencies_met FALSE)
endif()
find_package(Eigen3 3.1.0 QUIET) #(3.1.0 or greater)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
if(NOT TARGET CGAL::Eigen3_support)
message("NOTICE: This project requires the Eigen library, and will not be compiled.")
set(Classification_dependencies_met FALSE)

View File

@ -12,6 +12,7 @@
#ifndef CGAL_CONFORMING_CONSTRAINED_DELAUNAY_TRIANGULATION_3_H
#define CGAL_CONFORMING_CONSTRAINED_DELAUNAY_TRIANGULATION_3_H
#include <CGAL/IO/Color_ostream.h>
#include <CGAL/license/Constrained_triangulation_3.h>
#include <CGAL/Conforming_constrained_Delaunay_triangulation_3_fwd.h>
@ -42,7 +43,9 @@
#include <CGAL/Exception_ostream.h>
#include <CGAL/exceptions.h>
#include <CGAL/intersection_3.h>
#include <CGAL/IO/Color_ostream.h>
#include <CGAL/IO/Color.h>
#include <CGAL/IO/Indenting_ostream.h>
#include <CGAL/IO/io.h>
#include <CGAL/Iterator_range.h>
#include <CGAL/iterator.h>
@ -196,6 +199,26 @@ does_first_triangle_intersect_second_triangle_interior(const typename K::Triangl
const typename K::Triangle_3& t2,
const K& k)
{
// if(do_intersect(t1, t2) == false)
// return false;
// using Point_3 = typename K::Point_3;
// std::array<Point_3,3> tr1_points{ t1.vertex(0), t1.vertex(1), t1.vertex(2) };
// std::array<Point_3,3> tr2_points{ t2.vertex(0), t2.vertex(1), t2.vertex(2) };
// std::sort(tr1_points.begin(), tr1_points.end());
// std::sort(tr2_points.begin(), tr2_points.end());
// std::size_t nb_of_common_vertices = 0;
// std::set_intersection(
// tr1_points.begin(), tr1_points.end(),
// tr2_points.begin(), tr2_points.end(),
// CGAL::Counting_output_iterator(&nb_of_common_vertices));
// if(nb_of_common_vertices >= 2)
// return false;
// return true;
typedef typename K::Point_3 Point_3;
CGAL_kernel_precondition(!k.is_degenerate_3_object() (t1) );
@ -240,11 +263,13 @@ does_first_triangle_intersect_second_triangle_interior(const typename K::Triangl
auto comp = k.compare_xyz_3_object();
auto sort_ptrs = [&comp](const Point_3* p1, const Point_3* p2) { return comp(*p1, *p2) == SMALLER; };
auto intersection_is_a_vertex_or_a_common_edge = [&]() {
CGAL_assume(nb_of_t1_vertices_in_the_line >= 0 && nb_of_t1_vertices_in_the_line <= 3);
auto intersection_is_a_common_edge = [&]() {
if(nb_of_t1_vertices_in_the_line < 2) return false;
CGAL_assume(nb_of_t1_vertices_in_the_line <= 3);
if(nb_of_t2_vertices_in_the_line < 2) return false;
CGAL_assume(nb_of_t2_vertices_in_the_line <= 3);
std::sort(t1_vertices_in_the_line.data(), t1_vertices_in_the_line.data() + nb_of_t1_vertices_in_the_line,
sort_ptrs);
CGAL_assume(nb_of_t2_vertices_in_the_line >= 0 && nb_of_t2_vertices_in_the_line <= 3);
std::sort(t2_vertices_in_the_line.data(), t2_vertices_in_the_line.data() + nb_of_t2_vertices_in_the_line,
sort_ptrs);
std::size_t nb_of_common_vertices = 0;
@ -252,7 +277,7 @@ does_first_triangle_intersect_second_triangle_interior(const typename K::Triangl
t1_vertices_in_the_line.data(), t1_vertices_in_the_line.data() + nb_of_t1_vertices_in_the_line,
t2_vertices_in_the_line.data(), t2_vertices_in_the_line.data() + nb_of_t2_vertices_in_the_line,
CGAL::Counting_output_iterator(&nb_of_common_vertices), sort_ptrs);
return nb_of_common_vertices == 1 || nb_of_common_vertices == 2;
return nb_of_common_vertices == 2;
};
switch(dp)
@ -352,7 +377,7 @@ does_first_triangle_intersect_second_triangle_interior(const typename K::Triangl
push_to_t2_vertices_in_the_line(&a);
push_to_t2_vertices_in_the_line(&b);
push_to_t2_vertices_in_the_line(&c);
if(intersection_is_a_vertex_or_a_common_edge()) return false;
if(intersection_is_a_common_edge()) return false;
return CGAL::Intersections::internal::do_intersect_coplanar(t1,t2,k);
}
default: // should not happen.
@ -386,7 +411,7 @@ does_first_triangle_intersect_second_triangle_interior(const typename K::Triangl
if(db == COPLANAR) push_to_t2_vertices_in_the_line(&b);
if(dc == COPLANAR) push_to_t2_vertices_in_the_line(&c);
if(intersection_is_a_vertex_or_a_common_edge()) return false;
if(intersection_is_a_common_edge()) return false;
switch(da)
{
@ -2413,8 +2438,9 @@ private:
};
template <typename Fh_region>
int does_edge_interior_intersect_region(Cell_handle cell, int index_vc, int index_vd,
const CDT_2& cdt_2, const Fh_region& fh_region)
std::pair<int, std::array<Vertex_handle, 3>>
does_edge_interior_intersect_region(Cell_handle cell, int index_vc, int index_vd,
const CDT_2& cdt_2, const Fh_region& fh_region)
{
auto orientation = tr().geom_traits().orientation_3_object();
const auto vc = cell->vertex(index_vd);
@ -2442,16 +2468,17 @@ private:
orientation(pc, pd, t1, t2) != opc &&
orientation(pc, pd, t2, t0) != opc)
{
return static_cast<int>(opc);
return {static_cast<int>(opc), {v0, v1, v2}};
}
}
}
return 0;
return {0, {}};
}
struct Search_first_intersection_result_type {
Edge intersecting_edge;
Edge border_edge;
std::array<Vertex_handle, 3> triangle_vertices;
};
// Given a region and a border edge of it, returns an edge in the link of the
@ -2482,12 +2509,13 @@ private:
if(is_marked(cell_circ->vertex(index_vc), Vertex_marker::REGION_BORDER)) continue;
if(is_marked(cell_circ->vertex(index_vd), Vertex_marker::REGION_BORDER)) continue;
int cd_intersects_region = does_edge_interior_intersect_region(cell_circ, index_vc, index_vd, cdt_2, fh_region);
auto [cd_intersects_region, triangle_vertices] =
does_edge_interior_intersect_region(cell_circ, index_vc, index_vd, cdt_2, fh_region);
if(cd_intersects_region == 1) {
return Search_first_intersection_result_type{ Edge{cell_circ, index_vc, index_vd}, border_edge };
return Search_first_intersection_result_type{ Edge{cell_circ, index_vc, index_vd}, border_edge, triangle_vertices };
}
if(cd_intersects_region == -1) {
return Search_first_intersection_result_type{ Edge{cell_circ, index_vd, index_vc}, border_edge };
return Search_first_intersection_result_type{ Edge{cell_circ, index_vd, index_vc}, border_edge, triangle_vertices };
}
} while(++cell_circ != end);
}
@ -2601,26 +2629,27 @@ private:
int region_index,
const CDT_2& cdt_2,
const Fh_region& fh_region,
const Vertices_container& region_border_vertices,
const Vertices_container& region_vertices,
Edge first_intersecting_edge,
const std::array<Vertex_handle, 3>& first_intersected_triangle_vertices,
Edges_container border_edges)
{
// outputs
struct Outputs
{
std::vector<Edge> intersecting_edges;
std::set<Cell_handle> intersecting_cells;
std::vector<std::array<Vertex_handle, 3>> intersected_triangles;
std::vector<Cell_handle> intersecting_cells;
std::vector<Vertex_handle> vertices_of_upper_cavity;
std::vector<Vertex_handle> vertices_of_lower_cavity;
std::vector<Facet> facets_of_upper_cavity;
std::vector<Facet> facets_of_lower_cavity;
} outputs{
{}, {}, {region_vertices.begin(), region_vertices.end()}, {region_vertices.begin(), region_vertices.end()},
{}, {}, {}, {region_vertices.begin(), region_vertices.end()}, {region_vertices.begin(), region_vertices.end()},
{}, {}};
auto& [intersecting_edges, intersecting_cells, vertices_of_upper_cavity, vertices_of_lower_cavity,
facets_of_upper_cavity, facets_of_lower_cavity] = outputs;
auto& [intersecting_edges, intersected_triangles, intersecting_cells, vertices_of_upper_cavity,
vertices_of_lower_cavity, facets_of_upper_cavity, facets_of_lower_cavity] = outputs;
// to avoid "warning: captured structured bindings are a C++20 extension [-Wc++20-extensions]""
auto& vertices_of_upper_cavity_ = vertices_of_upper_cavity;
@ -2629,16 +2658,18 @@ private:
std::set<std::pair<Vertex_handle, Vertex_handle>> non_intersecting_edges_set;
detect_edges_and_cells_intersecting_region(face_index, region_index, cdt_2, fh_region, region_border_vertices,
first_intersecting_edge, intersecting_edges, intersecting_cells,
non_intersecting_edges_set);
if constexpr (cdt_3_can_use_cxx20_format()) if(this->debug().regions()) {
expensive_debug_dump_tetrahedra_intersect_region(face_index, region_index, cdt_2, fh_region,
std::as_const(intersecting_cells));
}
detect_edges_and_cells_intersecting_region(face_index, region_index, cdt_2, fh_region, first_intersecting_edge,
first_intersected_triangle_vertices, intersecting_edges,
intersected_triangles, intersecting_cells, non_intersecting_edges_set);
const std::set<Cell_handle> cr_intersecting_cells_set{cr_intersecting_cells.begin(), cr_intersecting_cells.end()};
// if constexpr(cdt_3_can_use_cxx20_format())
// if(this->debug().regions()) {
// expensive_debug_dump_tetrahedra_intersect_region(face_index, region_index, cdt_2, fh_region,
// cr_intersecting_cells_set);
// }
if(this->use_older_cavity_algorithm()) {
process_older_cavity_algorithm(intersecting_edges, cr_intersecting_cells, vertices_of_upper_cavity,
process_older_cavity_algorithm(intersecting_edges, cr_intersecting_cells_set, vertices_of_upper_cavity,
vertices_of_lower_cavity, facets_of_upper_cavity, facets_of_lower_cavity);
} // older algorithm
@ -2649,7 +2680,7 @@ private:
for(auto c : cr_intersecting_cells) {
for(int i = 0; i < 4; ++i) {
auto n = c->neighbor(i);
if(cr_intersecting_cells.count(n) == 0) {
if(cr_intersecting_cells_set.count(n) == 0) {
facets_of_border.emplace(n, n->index(c));
}
}
@ -2768,8 +2799,8 @@ private:
const auto facet = stack.top();
stack.pop();
const auto [cell, facet_index] = facet; // border facet seen from the outside of the cavity
CGAL_assertion(cr_intersecting_cells.count(cell) == 0); //REMOVE
CGAL_assertion(cr_intersecting_cells.count(cell->neighbor(facet_index)) > 0); //REMOVE
CGAL_assertion(cr_intersecting_cells_set.count(cell) == 0); //REMOVE
CGAL_assertion(cr_intersecting_cells_set.count(cell->neighbor(facet_index)) > 0); //REMOVE
const auto vertices = tr().vertices(facet);
for(auto v : vertices) {
if(is_marked(v, Vertex_marker::CAVITY)) {
@ -2792,14 +2823,14 @@ private:
auto previous_cell = cell;
auto other_cell = cell->neighbor(facet_index);
do {
CGAL_assertion(cr_intersecting_cells.count(other_cell) >= 0); // REMOVE
CGAL_assertion(cr_intersecting_cells_set.count(other_cell) >= 0); // REMOVE
auto index_va = other_cell->index(va);
auto index_vb = other_cell->index(vb);
auto other_facet_index = tr().next_around_edge(index_vb, index_va);
previous_cell = other_cell;
other_cell = previous_cell->neighbor(other_facet_index);
} while(cr_intersecting_cells.count(other_cell) > 0);
} while(cr_intersecting_cells_set.count(other_cell) > 0);
const Facet neighbor_facet{other_cell, other_cell->index(previous_cell)};
CGAL_assertion(facets_of_border.count(neighbor_facet) > 0);
if(remaining_facets_of_border.erase(neighbor_facet) > 0) {
@ -2956,8 +2987,11 @@ private:
CDT_2& non_const_cdt_2, Fh_region& non_const_fh_region)
{
if(this->debug().regions()) {
auto guard_color = CGAL::IO::make_color_guards(CGAL::IO::Ansi_color::Yellow, std::cerr);
std::cerr << "restore_subface_region face index: " << face_index << ", region #" << region_index << "\n";
}
auto guard_indenting = CGAL::IO::make_indenting_guards(2, std::cerr, std::cout);
const auto& cdt_2 = non_const_cdt_2;
const auto& fh_region = non_const_fh_region;
const auto border_edges = brute_force_border_3_of_region(face_index, region_index, cdt_2, fh_region);
@ -3145,11 +3179,12 @@ private:
clear_marks(region_vertices, Vertex_marker::REGION_INSIDE);
}};
const auto [first_intersecting_edge, _] = *found_edge_opt;
const auto [intersecting_edges, original_intersecting_cells, original_vertices_of_upper_cavity,
original_vertices_of_lower_cavity, original_facets_of_upper_cavity, original_facets_of_lower_cavity] =
construct_cavities(face_index, region_index, cdt_2, fh_region, region_border_vertices, region_vertices,
first_intersecting_edge, border_edges);
const auto [first_intersecting_edge, _, triangle_vertices] = *found_edge_opt;
const auto [intersecting_edges, intersected_triangles, original_intersecting_cells,
original_vertices_of_upper_cavity, original_vertices_of_lower_cavity, original_facets_of_upper_cavity,
original_facets_of_lower_cavity] =
construct_cavities(face_index, region_index, cdt_2, fh_region, region_vertices,
first_intersecting_edge, triangle_vertices, border_edges);
const std::set<Point_3> polygon_points = std::invoke([&](){
std::set<Point_3> polygon_points;
@ -3969,7 +4004,7 @@ public:
std::cerr << "ratio (non-squared): "
<< CGAL::sqrt(CGAL::to_double(from_exact(exact_sq_distance / exact_sq_circumradius))) << '\n';
}
result = false;
result = true;
}
}
}
@ -3988,7 +4023,7 @@ public:
if(verbose)
std::cerr << "non-empty circle " << std::endl;
result = false;
result = true;
}
}
}
@ -4232,16 +4267,17 @@ public:
};
};
template <typename Fh_region, typename Vertices_container>
template <typename Fh_region>
void detect_edges_and_cells_intersecting_region(
CDT_3_signed_index face_index,
int region_index,
[[maybe_unused]] CDT_3_signed_index face_index,
[[maybe_unused]] int region_index,
const CDT_2& cdt_2,
const Fh_region& fh_region,
const Vertices_container& region_border_vertices,
Edge first_intersecting_edge,
const std::array<Vertex_handle, 3>& first_intersected_triangle_vertices,
std::vector<Edge>& intersecting_edges,
std::set<Cell_handle>& intersecting_cells,
std::vector<std::array<Vertex_handle, 3>>& intersected_triangles,
std::vector<Cell_handle>& intersecting_cells,
std::set<std::pair<Vertex_handle, Vertex_handle>>& non_intersecting_edges_set)
{
// Create visitor functors
@ -4253,135 +4289,85 @@ public:
};
intersecting_edges.push_back(first_intersecting_edge);
const auto [v0, v1] = tr().vertices(first_intersecting_edge);
(void)new_edge(v0, v1, true);
intersecting_cells.push_back(first_intersecting_edge.first);
intersected_triangles.push_back(first_intersected_triangle_vertices);
(void)new_cell(first_intersecting_edge.first);
for(std::size_t i = 0; i < intersecting_edges.size(); ++i) {
const auto intersecting_edge = intersecting_edges[i];
const auto [v_above, v_below] = tr().vertices(intersecting_edge);
if constexpr (cdt_3_can_use_cxx20_format()) if(this->debug().regions()) {
debug_dump_edge_region_intersection(face_index, region_index, fh_region, i, v_above, v_below, intersecting_edge);
}
auto test_edge = [&](Cell_handle cell, Vertex_handle v0, int index_v0, Vertex_handle v1, int index_v1,
int expected)
{
auto value_returned = [this, v0, v1](bool b, bool not_visited) {
if constexpr (cdt_3_can_use_cxx20_format()) if(this->debug().regions()) {
std::cerr << cdt_3_format(" test_edge {} {} return {} {}\n",
IO::oformat(v0, with_point_and_info),
IO::oformat(v1, with_point_and_info),
b,
not_visited ? "(new)" : "(cached)");
auto test_edge = [&](Cell_handle cell, Vertex_handle v0, int index_v0, Vertex_handle v1, int index_v1)
{
auto value_returned = [this, v0, v1](bool b, bool not_visited, std::array<Vertex_handle, 3> triangle_vertices = {}) {
if constexpr (cdt_3_can_use_cxx20_format()) if(this->debug().regions()) {
std::cerr << cdt_3_format("test_edge {} {} return {} {}\n",
IO::oformat(v0, with_point_and_info),
IO::oformat(v1, with_point_and_info),
b,
not_visited ? "(new)" : "(cached)");
if(not_visited && b) {
std::cerr << " triangle " << IO::oformat(triangle_vertices[0], with_point_and_info) << "\n"
<< " " << IO::oformat(triangle_vertices[1], with_point_and_info) << "\n"
<< " " << IO::oformat(triangle_vertices[2], with_point_and_info) << "\n";
}
CGAL_USE(this, v0, v1, b, not_visited);
return b;
};
auto [cached_value_it, not_visited] = new_edge(v0, v1, false);
if(!not_visited) return value_returned(cached_value_it->second, not_visited);
int v0v1_intersects_region =
(is_marked(v0, Vertex_marker::REGION_INSIDE) || is_marked(v1, Vertex_marker::REGION_INSIDE))
? expected
: does_edge_interior_intersect_region(cell, index_v0, index_v1, cdt_2, fh_region);
}
CGAL_USE(this, v0, v1, b, not_visited);
return b;
};
auto [cached_value_it, not_visited] = new_edge(v0, v1, false);
if(!not_visited) return value_returned(cached_value_it->second, not_visited);
if(!is_marked(v0, Vertex_marker::REGION_INSIDE) && !is_marked(v1, Vertex_marker::REGION_INSIDE)) {
auto [v0v1_intersects_region, triangle_vertices] =
does_edge_interior_intersect_region(cell, index_v0, index_v1, cdt_2, fh_region);
if(v0v1_intersects_region != 0) {
if(this->use_older_cavity_algorithm()) {
if(v0v1_intersects_region != expected) {
throw PLC_error{"PLC error: v0v1_intersects_region != expected" ,
__FILE__, __LINE__, face_index, region_index};
}
}
// report the edge with first vertex above the region
if(v0v1_intersects_region < 0) {
std::swap(index_v0, index_v1);
}
intersecting_edges.emplace_back(cell, index_v0, index_v1);
intersected_triangles.push_back(triangle_vertices);
cached_value_it->second = true;
return value_returned(true, not_visited);
} else {
non_intersecting_edges_set.insert(make_sorted_pair(v0, v1));
cached_value_it->second = false;
return value_returned(false, not_visited);
return value_returned(true, not_visited, triangle_vertices);
}
};
}
non_intersecting_edges_set.insert(make_sorted_pair(v0, v1));
cached_value_it->second = false;
return value_returned(false, not_visited);
};
auto facet_circ = this->incident_facets(intersecting_edge);
const auto facet_circ_end = facet_circ;
do { // loop facets around [v_above, v_below]
CGAL_assertion(false == this->is_infinite(*facet_circ));
const auto cell = facet_circ->first;
const auto facet_index = facet_circ->second;
if(cell->ccdt_3_data().is_facet_constrained(facet_index)) {
CGAL_error_msg(std::invoke([&]() {
if(this->debug().regions()) this->dump_triangulation_to_off();
return std::string("intersecting polygons!");
}).c_str());
auto test_cell = [&](Cell_handle cell) {
if constexpr(cdt_3_can_use_cxx20_format()) if(this->debug().regions()) {
std::cerr << cdt_3_format("test_cell #{}\n {}\n {}\n {}\n {}\n",
IO::oformat(cell, with_offset),
IO::oformat(cell->vertex(0), with_point_and_info),
IO::oformat(cell->vertex(1), with_point_and_info),
IO::oformat(cell->vertex(2), with_point_and_info),
IO::oformat(cell->vertex(3), with_point_and_info));
}
auto indent_guard = CGAL::IO::make_indenting_guards("| ", std::cerr, std::cout, std::clog);
bool does_intersect = false;
for(int i = 0; i < 4; ++i) {
const auto v0 = cell->vertex(i);
for(int j = i + 1; j < 4; ++j) {
const auto v1 = cell->vertex(j);
if(test_edge(cell, v0, i, v1, j) != 0) {
does_intersect = true;
}
}
if(new_cell(cell)) {
intersecting_cells.insert(cell);
}
const auto index_v_above = cell->index(v_above);
const auto index_v_below = cell->index(v_below);
const auto index_vc = 6 - index_v_above - index_v_below - facet_index;
const auto vc = cell->vertex(index_vc);
if(region_border_vertices.count(vc) > 0) continue; // intersecting edges cannot touch the border
}
if constexpr(cdt_3_can_use_cxx20_format()) if(this->debug().regions()) {
std::cerr << cdt_3_format(" -> test_cell return {}\n", does_intersect);
}
return does_intersect;
};
if(!test_edge(cell, v_above, index_v_above, vc, index_vc, 1) &&
!test_edge(cell, v_below, index_v_below, vc, index_vc, -1) &&
this->use_older_cavity_algorithm())
{
if(this->debug().regions()) {
dump_triangulation();
dump_region(face_index, region_index, cdt_2);
std::ofstream out(std::string("dump_two_edges_") + std::to_string(face_index) + ".polylines.txt");
out.precision(17);
write_segment(out, Edge{cell, index_v_above, index_vc});
write_segment(out, Edge{cell, index_v_below, index_vc});
}
throw PLC_error{"PLC error: !test_edge(v_above..) && !test_edge(v_below..)" ,
__FILE__, __LINE__, face_index, region_index};
for(std::size_t i = 0; i < intersecting_cells.size(); ++i) {
const auto cell = intersecting_cells[i];
test_cell(cell);
for(int other_i = 0; other_i < 4; ++other_i) {
auto neighbor = cell->neighbor(other_i);
if(new_cell(neighbor) && !tr().is_infinite(neighbor) && test_cell(neighbor)) {
intersecting_cells.push_back(neighbor);
}
} while(++facet_circ != facet_circ_end);
if(this->use_newer_cavity_algorithm() && i + 1 == intersecting_edges.size()) {
for(auto ch: intersecting_cells) {
if(this->debug().regions()) {
std::cerr << "tetrahedron #" << ch->time_stamp() << " intersects the region\n";
}
for(int i = 0; i < 4; ++i) {
for(int j = i + 1; j < 4; ++j) {
test_edge(ch, ch->vertex(i), i, ch->vertex(j), j, 1);
}
}
for(int i = 0; i < 4; ++i) {
auto n_ch = ch->neighbor(i);
if(tr().is_infinite(n_ch))
continue;
if(new_cell(n_ch)) {
const auto tetrahedron = tr().tetrahedron(n_ch);
const auto tet_bbox = tetrahedron.bbox();
if(std::any_of(fh_region.begin(), fh_region.end(), [&](auto fh) {
const auto triangle = cdt_2.triangle(fh);
const auto tri_bbox = triangle.bbox();
return CGAL::do_overlap(tet_bbox, tri_bbox) &&
does_tetrahedron_intersect_triangle_interior(tetrahedron, triangle, tr().geom_traits());
}))
{
intersecting_cells.insert(n_ch);
if(this->debug().regions()) {
std::cerr << "new tetrahedron #" << n_ch->time_stamp() << " intersects the region\n";
}
} else if(this->debug().regions()) {
std::cerr << "NO, new tetrahedron #" << n_ch->time_stamp() << " does not intersect the region\n";
}
for(int i = 0; i < 4; ++i) {
for(int j = i + 1; j < 4; ++j) {
test_edge(n_ch, n_ch->vertex(i), i, n_ch->vertex(j), j, 1);
}
}
}
}
}
} // last intersecting edge, and new algorithm
} // end loop on intersecting_edges
}
}
}
void debug_dump_cavity_outputs(CDT_3_signed_index face_index,
@ -4442,16 +4428,28 @@ public:
std::size_t edge_index,
Vertex_handle v_above,
Vertex_handle v_below,
Edge intersecting_edge)
Edge intersecting_edge,
const std::array<Vertex_handle, 3>& first_intersected_triangle_vertices)
{
using EK = CGAL::Exact_predicates_exact_constructions_kernel;
const auto to_exact = CGAL::Cartesian_converter<Geom_traits, EK>();
const auto& cdt_2 = this->face_cdt_2(face_index);
std::cerr << cdt_3_format("restore_subface_region face index: {}, region #{}, intersecting edge #{}: ({} {})\n",
face_index, region_index, edge_index,
IO::oformat(v_above, with_point_and_info),
IO::oformat(v_below, with_point_and_info));
auto of = [](auto&&... args) {
return IO::oformat(std::forward<decltype(args)>(args)..., with_point_and_info);
};
std::cerr << cdt_3_format("restore_subface_region face index: {}, region #{}\n",
face_index, region_index);
auto indent_guard = CGAL::IO::make_indenting_guards("| ", std::cerr, std::cout, std::clog);
std::cerr << cdt_3_format("intersecting edge #{}: ( {} {} )\n"
"intersected triangle vertices: {}\n"
" {}\n"
" {}\n",
edge_index, of(v_above), of(v_below),
of(first_intersected_triangle_vertices[0]),
of(first_intersected_triangle_vertices[1]),
of(first_intersected_triangle_vertices[2]));
dump_region(face_index, region_index, cdt_2);
const auto p_above = this->point(v_above);
@ -4481,12 +4479,8 @@ public:
for(const auto& ch: make_prevent_deref_range(cells_around_intersecting_edge)) {
CGAL_assertion(!ch->has_vertex(tr().infinite_vertex()));
auto tetrahedron = tr().tetrahedron(ch.current_circulator());
std::cerr << cdt_3_format("Test tetrahedron (#{}):\n {}\n {}\n {}\n {}\n",
ch->time_stamp(),
IO::oformat(ch->vertex(0), with_point_and_info),
IO::oformat(ch->vertex(1), with_point_and_info),
IO::oformat(ch->vertex(2), with_point_and_info),
IO::oformat(ch->vertex(3), with_point_and_info));
std::cerr << cdt_3_format("Test tetrahedron (#{}):\n {}\n {}\n {}\n {}\n", ch->time_stamp(),
of(ch->vertex(0)), of(ch->vertex(1)), of(ch->vertex(2)), of(ch->vertex(3)));
if(!std::any_of(fh_region.begin(), fh_region.end(), [&](const auto fh) {
auto triangle = cdt_2.triangle(fh);
bool b = does_tetrahedron_intersect_triangle_interior(tetrahedron, triangle, tr().geom_traits());
@ -4496,12 +4490,13 @@ public:
return b;
}))
{
auto triangle = typename Geom_traits::Triangle_3{tr().point(first_intersected_triangle_vertices[0]),
tr().point(first_intersected_triangle_vertices[1]),
tr().point(first_intersected_triangle_vertices[2])};
exception_ostream()
<< cdt_3_format(
"ERROR: The following tetrahedron (#{}) does not intersect the region:\n {}\n {}\n {}\n {}",
ch->time_stamp(), IO::oformat(ch->vertex(0), with_point_and_info),
IO::oformat(ch->vertex(1), with_point_and_info), IO::oformat(ch->vertex(2), with_point_and_info),
IO::oformat(ch->vertex(3), with_point_and_info))
ch->time_stamp(), of(ch->vertex(0)), of(ch->vertex(1)), of(ch->vertex(2)), of(ch->vertex(3)))
<< std::endl;
}
}
@ -4541,7 +4536,7 @@ public:
bool intersects = false;
for(int i = 0; i < 4; ++i) {
for(int j = i + 1; j < 4; ++j) {
int intersects_region = does_edge_interior_intersect_region(ch, i, j, cdt_2, fh_region);
int intersects_region = does_edge_interior_intersect_region(ch, i, j, cdt_2, fh_region).first;
if(intersects_region != 0) {
intersects = true;
}

View File

@ -14,10 +14,17 @@
#include <CGAL/license/Constrained_triangulation_3.h>
#include <CGAL/Triangulation_simplex_base_with_time_stamp.h>
#include <CGAL/Conforming_constrained_Delaunay_triangulation_cell_data_3.h>
#include <CGAL/Triangulation_cell_base_3.h>
#include <CGAL/IO/io.h>
#include <CGAL/SMDS_3/io_signature.h>
#include <CGAL/Triangulation_cell_base_3.h>
#include <CGAL/Triangulation_simplex_base_with_time_stamp.h>
#include <istream>
#include <ostream>
#include <string>
#include <type_traits>
#include <utility>
namespace CGAL {

View File

@ -39,7 +39,7 @@ cgal_add_test(test_CDT_3_insert_constrained_edge_from_OFF_file)
function(CGAL_add_cdt3_from_off_test_aux data_name data_dir)
set(options ONLY_MERGE_FACETS)
set(oneValueArgs DATA_FILENAME TIMEOUT)
set(multiValueArgs LABELS)
set(multiValueArgs LABELS OPTIONS)
cmake_parse_arguments(PARSE_ARGV 2 "MY" "${options}" "${oneValueArgs}"
"${multiValueArgs}")
if(NOT MY_DATA_FILENAME)
@ -58,7 +58,7 @@ function(CGAL_add_cdt3_from_off_test_aux data_name data_dir)
cgal_setup_test_properties("execution of cdt_3_from_off ${data_name}" cdt_3_from_off)
add_test(NAME "execution of cdt_3_from_off --merge-facets ${data_name}"
COMMAND cdt_3_from_off
--merge-facets --segment-vertex-epsilon 0 --vertex-vertex-epsilon 0
--merge-facets --segment-vertex-epsilon 0 --vertex-vertex-epsilon 0 ${MY_OPTIONS}
${data_dir}/${data_filename}
${CMAKE_CURRENT_BINARY_DIR}/dump_output_${data_name}--merge-facets.off)
cgal_setup_test_properties("execution of cdt_3_from_off --merge-facets ${data_name}" cdt_3_from_off)
@ -100,6 +100,8 @@ CGAL_add_cdt3_from_local_off_test(cheese28)
CGAL_add_cdt3_from_local_off_test(cheese31)
CGAL_add_cdt3_from_local_off_test(cheese36-bis)
CGAL_add_cdt3_from_local_off_test(cheese36)
CGAL_add_cdt3_from_local_off_test(cheese-min1-no-merge-facets-read-mesh-with-operator OPTIONS --read-mesh-with-operator --debug-regions)
CGAL_add_cdt3_from_local_off_test(cheese-min2)
CGAL_add_cdt3_from_local_off_test(cheese6-PLCerrorWithFace0)
CGAL_add_cdt3_from_local_off_test(HexiCosPot-11)
CGAL_add_cdt3_from_local_off_test(HexiCosPot-1)
@ -130,7 +132,7 @@ if (CGAL_CDT_TEST_USE_THINGI)
CGAL_add_cdt3_from_local_off_test(40985-min3)
CGAL_add_cdt3_from_local_off_test(505036-min1)
CGAL_add_cdt3_from_local_off_test(57811-min)
CGAL_add_cdt3_from_local_off_test(734961-min1)
CGAL_add_cdt3_from_local_off_test(734961-min3)
CGAL_add_cdt3_from_local_off_test(error_mesh-p_not_equal_0-min2)
CGAL_add_cdt3_from_local_off_test(thingi-1036467-selection3)

View File

@ -748,6 +748,14 @@ int bisect_errors(Mesh mesh, CDT_options options) {
CGAL::Euler::remove_face(halfedge(*it, m), m);
}
std::stringstream ss;
ss.precision(17);
ss << m;
ss.seekg(0);
Mesh simplified_mesh;
ss >> simplified_mesh;
m = std::move(simplified_mesh);
return m.is_valid(true);
return true;
};

View File

@ -1,592 +0,0 @@
OFF
284 304 0
-36.779350280761719 -23.099626541137695 18.701873779296875
-42.555007934570312 -19.583858489990234 23.548229217529297
-42.555007934570312 19.583858489990234 23.548229217529297
-42.931419372558594 -19.638389587402344 23.76545524597168
-42.931419372558594 19.638389587402344 23.76545524597168
-43.321365356445312 -19.682565689086914 23.840118408203125
-43.321365356445312 19.682565689086914 23.840118408203125
-43.58544921875 -19.706684112548828 23.819894790649414
-43.58544921875 19.706684112548828 23.819894790649414
-43.839744567871094 -19.725315093994141 23.744318008422852
-43.839744567871094 19.725315093994141 23.744318008422852
-44.072181701660156 -19.737567901611328 23.616901397705078
-44.072181701660156 19.737567901611328 23.616901397705078
-44.272682189941406 -19.742908477783203 23.443172454833984
-44.272682189941406 19.742908477783203 23.443172454833984
-37.944908142089844 24.230958938598633 18.133537292480469
-43.83099365234375 20.647974014282227 23.072547912597656
-37.682060241699219 24.161458969116211 18.396366119384766
-43.64532470703125 20.612237930297852 23.258724212646484
-43.446907043457031 20.530267715454102 23.414690017700195
-37.410129547119141 23.994781494140625 18.599523544311523
-43.244354248046875 20.405618667602539 23.533679962158203
-37.154006958007812 23.746179580688477 18.724409103393555
-43.047248840332031 20.244251251220703 23.610109329223633
-42.779983520507812 19.948694229125977 23.638385772705078
-36.779350280761719 23.099626541137695 18.701873779296875
-36.937129974365234 23.438405990600586 18.759601593017578
-36.297103881835938 23.479263305664062 18.371559143066406
-36.620006561279297 23.682655334472656 18.507028579711914
-34.850986480712891 24.316011428833008 18.000007629394531
-35.311180114746094 24.090059280395508 18.035511016845703
-35.752426147460938 23.839736938476562 18.138641357421875
-34.850986480712891 14.027206420898438 18.000007629394531
-34.850986480712891 -24.316011428833008 18.000007629394531
-34.850986480712891 -14.027389526367188 18.000007629394531
-36.507049560546875 -23.322196960449219 18.498517990112305
-35.142234802246094 -24.177053451538086 18.014181137084961
-35.62921142578125 -23.913114547729492 18.102706909179688
-36.087120056152344 -23.625667572021484 18.266511917114258
-37.018566131591797 31.353113174438477 0.57017076015472412
-31.488866806030273 33.198989868164062 0.79087954759597778
-32.837959289550781 32.925224304199219 0.73261791467666626
-34.1419677734375 32.558513641357422 0.67864316701889038
-36.223121643066406 31.745574951171875 0.59852051734924316
-35.401527404785156 32.101917266845703 0.62917023897171021
-45.971839904785156 21.947345733642578 0.36052587628364563
-46.772842407226562 20.331201553344727 0.35106539726257324
-47.610565185546875 18.363397598266602 0.34236899018287659
-48.338508605957031 16.342769622802734 0.33569896221160889
-48.963981628417969 14.277647018432617 0.33057129383087158
-49.492584228515625 12.175520896911621 0.32660263776779175
-50.32745361328125 7.5033769607543945 0.32097962498664856
-50.589942932128906 5.1325240135192871 0.31935694813728333
-50.752395629882812 2.7478582859039307 0.31838774681091309
-50.816146850585938 0.35597807168960571 0.31801745295524597
-35.191650390625 8.0233678817749023 16.466701507568359
-34.508567810058594 12.283490180969238 16.345012664794922
-34.134033203125 13.834349632263184 16.330089569091797
-33.933021545410156 14.552207946777344 16.331699371337891
-33.168899536132812 16.9285888671875 16.338346481323242
-32.733959197998047 18.091268539428711 16.342527389526367
-31.360790252685547 21.144365310668945 16.357900619506836
-30.864288330078125 22.072181701660156 16.364362716674805
-22.254966735839844 30.377103805541992 17.169248580932617
-21.388984680175781 30.713247299194336 17.389657974243164
-20.500434875488281 31.004573822021484 17.645532608032227
-19.419178009033203 31.294624328613281 17.998111724853516
-18.323799133300781 31.525302886962891 18.402353286743164
-17.169727325439453 31.708671569824219 18.880874633789062
-16.018253326416016 31.838802337646484 19.413871765136719
-14.776437759399414 31.928308486938477 20.053590774536133
-35.607261657714844 1.5982358455657959 16.604997634887695
-35.535102844238281 3.7208642959594727 16.577224731445312
-35.398593902587891 5.877772331237793 16.529092788696289
47.098747253417969 33.880203247070312 74.279922485351562
46.244697570800781 33.886741638183594 74.747245788574219
47.17083740234375 34 74.316596984863281
46.16943359375 34 74.865982055664062
47.305160522460938 34.414215087890625 74.604652404785156
46.3402099609375 34.414215087890625 75.134048461914062
47.480216979980469 34.732051849365234 74.980056762695312
46.562767028808594 34.732051849365234 75.483390808105469
47.684074401855469 34.931850433349609 75.417228698730469
46.821937561035156 34.931850433349609 75.890205383300781
47.667686462402344 35 76.001419067382812
45.102317810058594 34.931850433349609 87.062767028808594
44.520851135253906 34.931850433349609 86.269744873046875
44.732803344726562 34.732051849365234 87.372817993164062
44.114028930664062 34.732051849365234 86.528915405273438
44.415496826171875 34.414215087890625 87.639068603515625
43.764686584472656 34.414215087890625 86.751472473144531
44.172019958496094 34 87.843376159667969
43.496627807617188 34 86.922248840332031
44.018966674804688 33.51763916015625 87.9718017578125
43.328117370605469 33.51763916015625 87.02960205078125
43.306808471679688 33 87.122528076171875
57.755561828613281 33 76.4454345703125
57.061042785644531 33 75.70660400390625
57.703361511230469 33.51763916015625 76.489234924316406
56.895431518554688 33.51763916015625 75.645271301269531
57.550300598144531 34 76.617668151855469
56.760452270507812 34 75.792579650878906
57.30682373046875 34.414215087890625 76.821968078613281
54.393745422363281 32 84.106910705566406
54.393745422363281 27.329744338989258 84.106910705566406
57.507408142089844 27.819313049316406 76.6053466796875
57.684379577636719 28.143291473388672 76.479019165039062
57.755561828613281 28.525449752807617 76.4454345703125
-34.9549560546875 13.490707397460938 18.001808166503906
-35.116249084472656 -12.564321517944336 18.011754989624023
-35.405059814453125 -10.521085739135742 18.051620483398438
-35.622817993164062 -8.4573488235473633 18.100996017456055
-35.938854217529297 -2.9209175109863281 18.204202651977539
-35.844734191894531 -5.3018879890441895 18.169376373291016
-35.977474212646484 -0.53356623649597168 18.219537734985352
-35.966587066650391 1.618476390838623 18.215152740478516
-35.911941528320312 3.7682209014892578 18.193878173828125
-35.808559417724609 5.9533171653747559 18.156938552856445
-35.491828918457031 9.7716169357299805 18.069252014160156
-35.651840209960938 8.1280059814453125 18.108875274658203
-35.290451049804688 11.403753280639648 18.032369613647461
-55.864982604980469 -14.244834899902344 4.3644118309020996
-54.462471008300781 -17.755165100097656 3.0565366744995117
-54.818603515625 -17.94352912902832 3.3886284828186035
-56.626029968261719 -15.95280647277832 5.0740923881530762
-56.585136413574219 -16.471908569335938 5.0359563827514648
-56.173324584960938 -14.552809715270996 4.6519408226013184
-55.1982421875 -17.999443054199219 3.7426614761352539
-55.575538635253906 -17.919099807739258 4.094489574432373
-55.924766540527344 -17.707971572875977 4.4201545715332031
-56.222137451171875 -17.380449295043945 4.6974596977233887
-56.447372436523438 -16.958850860595703 4.907494068145752
-56.567268371582031 -15.436921119689941 5.0192937850952148
-56.412864685058594 -14.959407806396484 4.8753066062927246
-54.409530639648438 16.04719352722168 7.4509906768798828
-54.350776672363281 16.563079833984375 7.3961920738220215
-54.196365356445312 17.040592193603516 7.2522048950195312
-53.956832885742188 17.44719123840332 7.028839111328125
-53.648490905761719 17.755165100097656 6.7413101196289062
-53.292366027832031 17.94352912902832 6.4092183113098145
-55.324134826660156 12.75 8.3038663864135742
-50.570335388183594 12.75 3.8708794116973877
-55.324134826660156 19.25 8.3038663864135742
-50.570335388183594 19.25 3.8708794116973877
-41.743515014648438 12.75 22.867301940917969
-36.779350280761719 12.75 18.701873779296875
-36.757293701171875 12.75 18.683547973632812
-36.757293701171875 19.25 18.683547973632812
-36.779350280761719 19.25 18.701873779296875
-41.743515014648438 19.25 22.867301940917969
-36.757297515869141 11.250000953674316 18.683549880981445
-36.779350280761719 11.25 18.701873779296875
-36.757297515869141 4.7500004768371582 18.683549880981445
-36.779350280761719 4.7500004768371582 18.701873779296875
-36.757297515869141 3.2500004768371582 18.683549880981445
-36.779350280761719 3.2500004768371582 18.701873779296875
-36.757297515869141 -3.2499995231628418 18.683549880981445
-36.779350280761719 -3.2499995231628418 18.701873779296875
-36.757297515869141 -4.7499995231628418 18.683549880981445
-36.779350280761719 -4.7499995231628418 18.701873779296875
-36.757297515869141 -11.249999046325684 18.683549880981445
-36.779350280761719 -11.249999046325684 18.701873779296875
-36.757297515869141 -12.749999046325684 18.683549880981445
-36.779350280761719 -12.75 18.701873779296875
-36.779350280761719 -19.25 18.701873779296875
-36.757297515869141 -19.25 18.683549880981445
-41.743515014648438 -19.25 22.867301940917969
-41.743515014648438 11.250000953674316 22.867301940917969
-41.743515014648438 -12.749999046325684 22.867301940917969
-41.743515014648438 -11.249999046325684 22.867301940917969
-41.743515014648438 -4.7499995231628418 22.867301940917969
-41.743515014648438 -3.2499995231628418 22.867301940917969
-41.743515014648438 3.2500004768371582 22.867301940917969
-41.743515014648438 4.7500004768371582 22.867301940917969
-52.245979309082031 -17.755165100097656 5.4334349632263184
-52.602104187011719 -17.94352912902832 5.7655272483825684
-52.98175048828125 -17.999443054199219 6.1195602416992188
-53.359046936035156 -17.919099807739258 6.4713883399963379
-53.708274841308594 -17.707971572875977 6.797053337097168
-54.005638122558594 -17.380449295043945 7.0743570327758789
-54.230880737304688 -16.958850860595703 7.2843923568725586
-54.368644714355469 -16.471908569335938 7.4128546714782715
-54.409530639648438 -15.95280647277832 7.4509906768798828
-54.350776672363281 -15.436921119689941 7.3961920738220215
-54.196365356445312 -14.959407806396484 7.2522048950195312
-53.956832885742188 -14.552809715270996 7.028839111328125
-52.245979309082031 6.2448348999023438 5.4334349632263184
-52.602104187011719 6.0564718246459961 5.7655272483825684
-52.98175048828125 6.0005569458007812 6.1195602416992188
-53.359046936035156 6.0809006690979004 6.4713883399963379
-53.708274841308594 6.2920279502868652 6.797053337097168
-54.005638122558594 6.6195507049560547 7.0743570327758789
-54.230880737304688 7.0411491394042969 7.2843923568725586
-54.368644714355469 7.5280909538269043 7.4128546714782715
-54.409530639648438 8.0471935272216797 7.4509906768798828
-54.350776672363281 8.5630788803100586 7.3961920738220215
-54.196365356445312 9.0405921936035156 7.2522048950195312
-53.956832885742188 9.4471902847290039 7.028839111328125
-53.648490905761719 9.7551651000976562 6.7413101196289062
-53.292366027832031 9.9435281753540039 6.4092183113098145
-52.9127197265625 9.9994430541992188 6.0551853179931641
-52.535423278808594 9.9190988540649414 5.7033572196960449
-52.186195373535156 9.7079715728759766 5.3776912689208984
-51.888832092285156 9.3804492950439453 5.1003875732421875
-51.663589477539062 8.9588508605957031 4.8903532028198242
-51.525825500488281 8.4719085693359375 4.7618908882141113
-51.484931945800781 7.9528069496154785 4.7237534523010254
-51.543693542480469 7.4369211196899414 4.7785534858703613
-51.698104858398438 6.9594078063964844 4.9225406646728516
-51.937637329101562 6.5528097152709961 5.1459064483642578
-52.245979309082031 -9.7551651000976562 5.4334349632263184
-52.602104187011719 -9.9435281753540039 5.7655272483825684
-52.98175048828125 -9.9994430541992188 6.1195602416992188
-53.359046936035156 -9.9190988540649414 6.4713883399963379
-53.708274841308594 -9.7079715728759766 6.797053337097168
-54.005638122558594 -9.3804492950439453 7.0743570327758789
-54.230880737304688 -8.9588508605957031 7.2843923568725586
-54.368644714355469 -8.4719085693359375 7.4128546714782715
-54.409530639648438 -7.9528069496154785 7.4509906768798828
-54.350776672363281 -7.4369211196899414 7.3961920738220215
-54.196365356445312 -6.9594078063964844 7.2522048950195312
-53.956832885742188 -6.5528097152709961 7.028839111328125
-53.648490905761719 -6.2448348999023438 6.7413101196289062
-53.292366027832031 -6.0564718246459961 6.4092183113098145
-52.9127197265625 -6.0005569458007812 6.0551853179931641
-52.535423278808594 -6.0809006690979004 5.7033572196960449
-52.186195373535156 -6.2920279502868652 5.3776912689208984
-51.888832092285156 -6.6195507049560547 5.1003875732421875
-51.663589477539062 -7.0411491394042969 4.8903532028198242
-51.525825500488281 -7.5280909538269043 4.7618908882141113
-51.484931945800781 -8.0471935272216797 4.7237534523010254
-51.543693542480469 -8.5630788803100586 4.7785534858703613
-51.698104858398438 -9.0405921936035156 4.9225406646728516
-51.937637329101562 -9.4471902847290039 5.1459064483642578
-52.245979309082031 -1.7551651000976562 5.4334349632263184
-52.602104187011719 -1.9435282945632935 5.7655272483825684
-52.98175048828125 -1.9994431734085083 6.1195602416992188
-53.359046936035156 -1.9190992116928101 6.4713883399963379
-53.708274841308594 -1.7079719305038452 6.797053337097168
-54.005638122558594 -1.3804491758346558 7.0743570327758789
-54.230880737304688 -0.95885109901428223 7.2843923568725586
-54.368644714355469 -0.47190886735916138 7.4128546714782715
-54.409530639648438 0.047193169593811035 7.4509906768798828
-54.350776672363281 0.56307905912399292 7.3961920738220215
-54.196365356445312 1.0405920743942261 7.2522048950195312
-53.956832885742188 1.4471904039382935 7.028839111328125
-53.648490905761719 1.7551651000976562 6.7413101196289062
-53.292366027832031 1.9435282945632935 6.4092183113098145
-52.9127197265625 1.9994431734085083 6.0551853179931641
-52.535423278808594 1.9190992116928101 5.7033572196960449
-52.186195373535156 1.7079719305038452 5.3776912689208984
-51.888832092285156 1.3804491758346558 5.1003875732421875
-51.663589477539062 0.95885109901428223 4.8903532028198242
-51.525825500488281 0.47190886735916138 4.7618908882141113
-51.484931945800781 -0.047193169593811035 4.7237534523010254
-51.543693542480469 -0.56307905912399292 4.7785534858703613
-51.698104858398438 -1.0405920743942261 4.9225406646728516
-51.937637329101562 -1.4471904039382935 5.1459064483642578
-55.324134826660156 -19.25 8.3038663864135742
-55.324134826660156 -12.749999046325684 8.3038663864135742
-55.324134826660156 -11.249999046325684 8.3038663864135742
-50.570335388183594 -11.249999046325684 3.8708794116973877
-55.324134826660156 -4.7499995231628418 8.3038663864135742
-50.570335388183594 -4.7499995231628418 3.8708794116973877
-55.324134826660156 4.7500004768371582 8.3038663864135742
-50.570335388183594 4.7500004768371582 3.8708794116973877
-55.324134826660156 11.250000953674316 8.3038663864135742
-50.570335388183594 11.250000953674316 3.8708794116973877
-55.324134826660156 -3.2499995231628418 8.3038663864135742
-50.570335388183594 -3.2499995231628418 3.8708794116973877
-55.324134826660156 3.2500004768371582 8.3038663864135742
-50.570335388183594 3.2500004768371582 3.8708794116973877
54.561210632324219 32 84.306480407714844
54.561210632324219 27.316091537475586 84.306480407714844
59.023063659667969 27.245063781738281 83.614967346191406
58.855140686035156 27.220464706420898 84.373291015625
58.709556579589844 27.20634651184082 83.559196472167969
58.547500610351562 27.182525634765625 84.288505554199219
58.705459594726562 27.198905944824219 84.742828369140625
58.318092346191406 27.161706924438477 84.999580383300781
58.428375244140625 28.472723007202148 77.358428955078125
58.353050231933594 28.08903694152832 77.383209228515625
58.16021728515625 27.764249801635742 77.487274169921875
57.879478454589844 27.548213958740234 77.654670715332031
3 3 4 5
3 5 4 6
3 5 6 7
3 7 6 8
3 7 8 9
3 9 8 10
3 9 10 11
3 11 10 12
3 11 12 13
3 13 12 14
3 15 16 17
3 17 16 18
3 17 18 19
3 17 19 20
3 20 19 21
3 20 21 22
3 22 21 23
3 22 23 24
3 2 25 24
3 24 25 26
3 24 26 22
3 27 28 25
3 50 49 56
3 49 57 56
3 49 48 57
3 48 58 57
3 48 59 58
3 48 47 59
3 47 60 59
3 47 46 60
3 39 43 63
3 43 64 63
3 43 44 64
3 44 65 64
3 44 66 65
3 42 41 67
3 41 68 67
3 41 69 68
3 41 40 69
3 40 70 69
3 54 53 71
3 71 53 72
3 52 72 53
3 72 52 73
3 51 73 52
3 73 51 55
3 46 45 61
3 45 62 61
3 44 42 66
3 66 42 67
3 74 75 76
3 76 75 77
3 76 77 78
3 78 77 79
3 78 79 80
3 80 79 81
3 80 81 82
3 82 81 83
3 82 83 84
3 85 86 87
3 87 86 88
3 87 88 89
3 89 88 90
3 89 90 91
3 91 90 92
3 91 92 93
3 93 92 94
3 93 94 95
3 96 97 98
3 98 97 99
3 98 99 100
3 100 99 101
3 100 101 102
3 142 134 135
3 142 135 136
3 142 136 137
3 142 137 138
3 142 138 139
3 142 139 143
3 140 144 141
3 141 144 145
3 141 145 146
3 147 143 146
3 143 141 146
3 143 147 142
3 142 147 148
3 142 148 149
3 144 140 149
3 140 142 149
3 30 31 119
3 31 117 119
3 31 116 117
3 29 30 108
3 30 120 108
3 30 118 120
3 25 148 27
3 148 147 27
3 146 145 150
3 145 151 150
3 152 153 154
3 153 155 154
3 156 157 158
3 157 159 158
3 160 161 162
3 161 163 162
3 113 112 37
3 112 38 37
3 112 114 38
3 110 111 36
3 111 37 36
3 111 113 37
3 34 109 33
3 109 36 33
3 109 110 36
3 35 164 0
3 35 165 164
3 35 162 165
3 35 160 162
3 35 158 160
3 35 156 158
3 35 154 156
3 35 152 154
3 35 150 152
3 35 146 150
3 35 147 146
3 35 27 147
3 35 38 27
3 27 115 31
3 27 114 115
3 27 38 114
3 116 31 115
3 119 118 30
3 32 29 108
3 166 1 164
3 1 0 164
3 145 144 151
3 144 167 151
3 144 1 167
3 2 148 25
3 2 149 148
3 2 144 149
3 2 1 144
3 168 1 166
3 168 169 1
3 168 161 169
3 168 163 161
3 170 1 169
3 170 171 1
3 170 157 171
3 170 159 157
3 172 1 171
3 172 173 1
3 172 153 173
3 172 155 153
3 1 173 167
3 122 123 174
3 123 175 174
3 123 127 175
3 127 176 175
3 127 128 176
3 128 177 176
3 128 129 177
3 129 178 177
3 129 130 178
3 130 179 178
3 130 131 179
3 131 180 179
3 131 125 180
3 125 181 180
3 125 124 181
3 124 182 181
3 124 132 182
3 132 183 182
3 132 133 183
3 133 184 183
3 133 126 184
3 126 185 184
3 126 121 185
3 258 259 168
3 260 261 213
3 260 213 214
3 260 214 215
3 260 215 216
3 260 216 217
3 260 217 218
3 260 218 262
3 261 263 229
3 261 229 230
3 261 230 231
3 261 231 232
3 261 232 233
3 261 233 210
3 261 210 211
3 261 211 212
3 261 212 213
3 263 223 224
3 263 224 225
3 263 225 226
3 263 226 227
3 263 227 228
3 263 228 229
3 262 218 219
3 262 219 220
3 262 220 221
3 262 221 222
3 262 222 223
3 262 223 263
3 260 169 261
3 261 169 161
3 261 161 160
3 158 263 160
3 263 261 160
3 263 158 262
3 262 158 159
3 262 159 170
3 169 260 170
3 260 262 170
3 264 265 189
3 264 189 190
3 264 190 191
3 264 191 192
3 264 192 193
3 264 193 194
3 264 194 266
3 265 267 205
3 265 205 206
3 265 206 207
3 265 207 208
3 265 208 209
3 265 209 186
3 265 186 187
3 265 187 188
3 265 188 189
3 267 199 200
3 267 200 201
3 267 201 202
3 267 202 203
3 267 203 204
3 267 204 205
3 266 194 195
3 266 195 196
3 266 196 197
3 266 197 198
3 266 198 199
3 266 199 267
3 264 173 265
3 265 173 153
3 265 153 152
3 150 267 152
3 267 265 152
3 267 150 266
3 266 150 151
3 266 151 167
3 173 264 167
3 264 266 167
3 268 269 237
3 268 237 238
3 268 238 239
3 268 239 240
3 268 240 241
3 268 241 242
3 268 242 270
3 269 271 253
3 269 253 254
3 269 254 255
3 269 255 256
3 269 256 257
3 269 257 234
3 269 234 235
3 269 235 236
3 269 236 237
3 271 247 248
3 271 248 249
3 271 249 250
3 271 250 251
3 271 251 252
3 271 252 253
3 270 242 243
3 270 243 244
3 270 244 245
3 270 245 246
3 270 246 247
3 270 247 271
3 268 171 269
3 269 171 157
3 269 157 156
3 154 271 156
3 271 269 156
3 271 154 270
3 270 154 155
3 270 155 172
3 171 268 172
3 268 270 172
3 272 103 273
3 273 103 104
3 274 275 276
3 275 277 276
3 275 278 277
3 278 279 277
3 280 281 107
3 281 106 107
3 281 282 106
3 282 105 106
3 282 283 105

View File

@ -0,0 +1,93 @@
OFF
54 35 0
-42.555007934570312 -19.583858489990234 23.548229217529297
-42.555007934570312 19.583858489990234 23.548229217529297
-42.931419372558594 -19.638389587402344 23.76545524597168
-42.931419372558594 19.638389587402344 23.76545524597168
-43.321365356445312 -19.682565689086914 23.840118408203125
-43.58544921875 19.706684112548828 23.819894790649414
-43.839744567871094 -19.725315093994141 23.744318008422852
-43.839744567871094 19.725315093994141 23.744318008422852
-44.072181701660156 19.737567901611328 23.616901397705078
-44.272682189941406 -19.742908477783203 23.443172454833984
-44.272682189941406 19.742908477783203 23.443172454833984
-35.752426147460938 23.839736938476562 18.138641357421875
-36.507049560546875 -23.322196960449219 18.498517990112305
-31.488866806030273 33.198989868164062 0.79087954759597778
-45.971839904785156 21.947345733642578 0.36052587628364563
-46.772842407226562 20.331201553344727 0.35106539726257324
-48.338508605957031 16.342769622802734 0.33569896221160889
-48.963981628417969 14.277647018432617 0.33057129383087158
-50.32745361328125 7.5033769607543945 0.32097962498664856
-50.589942932128906 5.1325240135192871 0.31935694813728333
-35.191650390625 8.0233678817749023 16.466701507568359
-34.508567810058594 12.283490180969238 16.345012664794922
-34.134033203125 13.834349632263184 16.330089569091797
-33.933021545410156 14.552207946777344 16.331699371337891
-31.360790252685547 21.144365310668945 16.357900619506836
-16.018253326416016 31.838802337646484 19.413871765136719
-14.776437759399414 31.928308486938477 20.053590774536133
-35.535102844238281 3.7208642959594727 16.577224731445312
-35.398593902587891 5.877772331237793 16.529092788696289
43.764686584472656 34.414215087890625 86.751472473144531
44.172019958496094 34 87.843376159667969
43.496627807617188 34 86.922248840332031
-35.911941528320312 3.7682209014892578 18.193878173828125
-35.808559417724609 5.9533171653747559 18.156938552856445
-55.324134826660156 12.75 8.3038663864135742
-50.570335388183594 12.75 3.8708794116973877
-55.324134826660156 19.25 8.3038663864135742
-50.570335388183594 19.25 3.8708794116973877
-41.743515014648438 12.75 22.867301940917969
-36.779350280761719 12.75 18.701873779296875
-36.757293701171875 12.75 18.683547973632812
-36.757293701171875 19.25 18.683547973632812
-36.779350280761719 19.25 18.701873779296875
-41.743515014648438 19.25 22.867301940917969
-36.757297515869141 11.250000953674316 18.683549880981445
-36.779350280761719 11.25 18.701873779296875
-36.757297515869141 4.7500004768371582 18.683549880981445
-36.779350280761719 4.7500004768371582 18.701873779296875
-41.743515014648438 11.250000953674316 22.867301940917969
-41.743515014648438 4.7500004768371582 22.867301940917969
-55.324134826660156 4.7500004768371582 8.3038663864135742
-50.570335388183594 4.7500004768371582 3.8708794116973877
-55.324134826660156 11.250000953674316 8.3038663864135742
-50.570335388183594 11.250000953674316 3.8708794116973877
3 2 3 4
3 6 5 7
3 9 8 10
3 17 22 21
3 17 16 22
3 16 23 22
3 13 26 25
3 27 19 28
3 28 18 20
3 15 14 24
3 30 29 31
3 34 38 35
3 35 38 39
3 41 37 40
3 37 35 40
3 36 42 43
3 38 34 43
3 34 36 43
3 11 32 33
3 39 45 44
3 12 44 46
3 39 38 45
3 38 48 45
3 38 0 48
3 1 38 43
3 1 0 38
3 0 49 48
3 51 49 47
3 51 47 46
3 44 53 46
3 53 51 46
3 52 44 45
3 52 45 48
3 49 50 48
3 50 52 48

View File

@ -0,0 +1,527 @@
OFF
360 163 0
-0.050000000699999998 -0.017913000700000001 -0.015625
-0.043749999300000002 -0.0125000002 -0.018750000700000002
-0.041919000400000003 0.033080998799999997 -0.041919000400000003
-0.043719999500000002 -0.018719999099999999 -0.0131130004
-0.050000000699999998 -0.0062500000999999999 -0.0125000002
-0.041919000400000003 -0.0080810003000000002 -0.016919000100000001
0.050000000699999998 0.043620001499999998 0.036230001599999999
0.050000000699999998 0.043561998800000001 0.014023000399999999
-0.050000000699999998 -0.018536999799999999 -0.014117999900000001
-0.043274000299999997 0.031725998999999998 -0.0398919992
-0.041919000400000003 -0.016919000100000001 -0.016919000100000001
-0.050000000699999998 -0.018750000700000002 -0.0125000002
-0.043719999500000002 -0.0131130004 -0.018719999099999999
-0.050000000699999998 -0.014117999900000001 -0.018536999799999999
0.050000000699999998 0.043102998300000001 0.034729998599999999
0.050000000699999998 0.043007999700000001 0.015453999899999999
-0.050000000699999998 0.043749999300000002 -0.037500001499999998
-0.043719999500000002 -0.0118869999 -0.018719999099999999
-0.043719999500000002 -0.0062799999000000004 -0.0131130004
-0.042697001200000001 0.040972001899999999 -0.042697001200000001
-0.042697001200000001 0.034028001099999997 -0.042697001200000001
-0.042697001200000001 0.0323030017 -0.040972001899999999
0.050000000699999998 0.042224999499999999 0.0334089994
-0.050000000699999998 0.043536998299999997 -0.035881999900000003
-0.050000000699999998 0.041919000400000003 -0.041919000400000003
-0.038113001700000003 0.0312799998 -0.018719999099999999
-0.038113001700000003 0.0312799998 -0.0312799998
-0.043274000299999997 -0.0148919998 -0.018273999900000001
-0.042697001200000001 -0.0073029999999999996 -0.015971999600000002
-0.042697001200000001 -0.0090279998000000004 -0.017697000899999999
-0.042697001200000001 -0.015971999600000002 -0.017697000899999999
-0.050000000699999998 0.040624998500000002 -0.042913000999999999
-0.050000000699999998 0.039117999399999999 -0.043536998299999997
-0.050000000699999998 -0.015625 -0.017913000700000001
-0.050000000699999998 0.037500001499999998 -0.03125
0.050000000699999998 0.040624998500000002 -0.032086998200000001
-0.050000000699999998 0.037500001499999998 -0.043749999300000002
-0.042697001200000001 -0.017697000899999999 -0.015971999600000002
-0.050000000699999998 0.035881999900000003 -0.031463000900000003
-0.050000000699999998 0.035881999900000003 -0.043536998299999997
-0.038718998400000003 0.031369999099999997 -0.018629999800000002
-0.038718998400000003 0.031369999099999997 -0.031369999099999997
-0.050000000699999998 0.034375000699999998 -0.042913000999999999
0.050000000699999998 0.039117999399999999 -0.031463000900000003
-0.050000000699999998 0.033080998799999997 -0.041919000400000003
-0.050000000699999998 0.032086998200000001 -0.040624998500000002
-0.043719999500000002 0.0118869999 -0.018719999099999999
-0.050000000699999998 -0.0125000002 -0.018750000700000002
-0.050000000699999998 0.031463000900000003 -0.039117999399999999
-0.043719999500000002 0.036887001199999998 -0.043719999500000002
0.050000000699999998 0.037833999799999997 -0.027458000900000001
0.050000000699999998 0.037500001499999998 -0.03125
-0.043719999500000002 0.036887001199999998 -0.0312799998
-0.043719999500000002 0.038113001700000003 -0.043719999500000002
0.050000000699999998 0.0370969996 -0.0292380005
-0.050000000699999998 0.0125000002 -0.018750000700000002
-0.050000000699999998 -0.016919000100000001 -0.016919000100000001
-0.050000000699999998 0.010882000399999999 -0.018536999799999999
-0.043274000299999997 -0.018273999900000001 -0.0148919998
-0.043274000299999997 -0.0101079997 -0.018273999900000001
-0.043274000299999997 0.0398919992 -0.043274000299999997
-0.050000000699999998 -0.010882000399999999 -0.018536999799999999
-0.043719999500000002 0.043719999500000002 -0.036887001199999998
0.015971999600000002 0.017697000899999999 -0.0323030017
0.015971999600000002 0.0323030017 -0.0323030017
0.016797000499999999 -0.025195000700000001 -0.025546999599999998
0.016797000499999999 -0.025195000700000001 -0.019218999899999999
0.016797000499999999 -0.025112999600000002 -0.0181159992
0.016797000499999999 -0.0249439999 -0.027458000900000001
0.016797000499999999 -0.0248659998 -0.0170389991
0.016797000499999999 -0.024205999400000001 -0.0292380005
0.016797000499999999 -0.023033000500000001 -0.0307669993
0.016797000499999999 -0.0215039998 -0.031941000400000003
0.016797000499999999 -0.019723000000000001 -0.0326780006
0.050000000699999998 0.0307030007 -0.032930001600000001
0.016797000499999999 -0.017812000599999999 -0.032930001600000001
0.016797000499999999 -0.0170389991 -0.032930001600000001
0.016797000499999999 -0.0170389991 -0.0170389991
0.016797000499999999 -0.0079610002999999999 -0.032930001600000001
0.016797000499999999 -0.0079610002999999999 -0.0170389991
0.016797000499999999 0.0079610002999999999 -0.032930001600000001
0.016797000499999999 0.0079610002999999999 -0.0170389991
0.016797000499999999 0.0170389991 -0.032930001600000001
0.016797000499999999 0.0170389991 -0.0170389991
0.016797000499999999 0.0307030007 -0.032930001600000001
0.016797000499999999 0.031846001700000001 -0.032841000699999998
0.016797000499999999 0.032960999800000002 -0.032575998500000002
0.016797000499999999 0.032960999800000002 -0.0170389991
0.016919000100000001 0.016919000100000001 -0.050000000699999998
0.016919000100000001 0.016919000100000001 -0.033080998799999997
0.016919000100000001 0.033080998799999997 -0.033080998799999997
0.016919000100000001 0.041919000400000003 -0.033080998799999997
0.016919000100000001 0.041919000400000003 -0.016919000100000001
0.0170699991 -0.0082369995999999994 -0.032930001600000001
0.0170699991 0.0082369995999999994 -0.032930001600000001
0.0170699991 0.016762999800000001 -0.032930001600000001
0.017508000100000001 -0.0245670006 -0.0162390005
0.017550000900000001 0.041182000199999999 0.0074499999000000004
0.017563000299999999 0.033835999700000001 -0.032232001400000002
0.017613999500000001 0.041092999300000002 -0.017613999500000001
0.017697000899999999 0.0323030017 -0.034028001099999997
0.050000000699999998 0.014401000000000001 0.0184540004
0.017697000899999999 0.034028001099999997 -0.0323030017
0.017697000899999999 0.040972001899999999 -0.0323030017
0.050000000699999998 0.0137449997 0.0313749984
0.017913000700000001 0.015625 -0.050000000699999998
0.018043000300000001 -0.024124000199999999 -0.0153879998
0.050000000699999998 0.012891000099999999 0.018737999700000001
0.018060000600000001 0.040355000600000003 0.0069400002000000001
0.018123999200000001 0.034775000100000002 -0.031706001599999999
-0.0398919992 0.031725998999999998 -0.018273999900000001
0.018155999499999999 0.040160000299999998 -0.018155999499999999
0.018273999900000001 0.035108 -0.031725998999999998
0.018273999900000001 0.0398919992 -0.031725998999999998
0.018420999899999999 -0.023491000799999998 -0.014500999800000001
0.0184349995 0.039459999699999998 0.0065649999000000001
0.018492000200000001 0.0357219987 -0.030960999400000001
0.018528999800000001 0.039147999099999997 -0.018528999800000001
0.018536999799999999 0.014117999900000001 -0.050000000699999998
0.018629999800000002 -0.022735999900000001 -0.0137179997
-0.043749999300000002 0.037500001499999998 -0.043749999300000002
0.018629999800000002 0.036281000799999998 -0.031369999099999997
0.018629999800000002 0.038718998400000003 -0.031369999099999997
0.018666999399999998 0.038516998300000001 0.0063330000000000001
0.0186730009 0.036520998899999997 -0.030092999299999999
0.018719999099999999 -0.018719999099999999 -0.011892000200000001
0.018719999099999999 0.036887001199999998 -0.0312799998
0.018719999099999999 0.038113001700000003 -0.0312799998
0.018721999600000001 0.038086000799999999 -0.025546999599999998
0.050000000699999998 0.0082369995999999994 -0.032930001600000001
0.018721999600000001 0.038086000799999999 -0.018721999600000001
0.018726000600000001 -0.021869 -0.0130500002
0.0187309999 0.037987999600000003 -0.026743000400000001
0.018737999700000001 -0.019819999099999999 -0.0121139996
-0.037500001499999998 0.03125 -0.018750000700000002
0.018742000700000001 0.037188000999999998 -0.029075000399999999
0.018747 0.037686999899999997 -0.0279399995
0.018750000700000002 -0.020883999800000001 -0.0125050005
0.018750000700000002 0.037500001499999998 -0.03125
0.022630000500000001 0.040805000799999998 0.0071959998000000001
0.023674000099999998 0.0412780009 0.0075210002
-0.050000000699999998 -0.0093750003999999998 -0.017913000700000001
0.03125 0.043749999300000002 0.0125000002
-0.050000000699999998 -0.0064630000999999996 -0.014117999900000001
0.03125 0.050000000699999998 0.0125000002
0.031252000500000002 0.037645999300000003 -0.028056999700000002
0.031252998900000002 -0.020402999599999999 -0.012306000100000001
0.031263001300000003 0.037099000100000001 -0.029234999800000001
0.031268000599999998 0.037978000900000003 -0.026802999899999999
0.031277999299999998 0.038086000799999999 -0.025546999599999998
0.031277999299999998 0.038086000799999999 -0.0062779997999999997
0.031277999299999998 0.038086000799999999 0.0062779997999999997
0.031279001399999999 -0.0219470002 -0.013101999600000001
0.0312799998 -0.018719999099999999 -0.011892000200000001
0.0312799998 0.043719999500000002 0.0118869999
0.0312799998 0.043719999500000002 0.0131130004
0.031351000099999998 -0.022621000200000001 -0.0136160003
0.0313530006 0.036370001700000001 -0.030277999100000001
-0.050000000699999998 -0.0080810003000000002 -0.016919000100000001
0.031369999099999997 0.043630000199999998 0.011281000500000001
0.031463000900000003 0.014117999900000001 -0.050000000699999998
0.031463000900000003 0.050000000699999998 0.010882000399999999
0.031463000900000003 0.050000000699999998 0.014117999900000001
0.031470999100000001 0.039147999099999997 -0.0064710000999999998
0.031470999100000001 0.039147999099999997 0.0064710000999999998
0.031482998300000002 -0.023217000099999999 -0.014189000199999999
0.031578999000000003 0.035498999099999998 -0.031160000699999999
0.031706001599999999 -0.023758999999999999 -0.0148440003
0.050000000699999998 -0.0082369995999999994 -0.032930001600000001
0.031844001300000001 0.040160000299999998 -0.0068440000000000003
0.031844001300000001 0.040160000299999998 0.0068440000000000003
0.032024998200000002 0.034485999500000003 -0.031886998600000001
0.032037001099999997 -0.024211000699999999 -0.015535999999999999
0.032086998200000001 0.015625 -0.050000000699999998
0.0323030017 -0.015971999600000002 -0.0073029999999999996
0.0323030017 -0.015971999600000002 0.0073029999999999996
0.0323860012 0.041092999300000002 -0.0073859998999999997
0.0323860012 0.041092999300000002 0.0073859998999999997
0.032460000400000001 -0.0245479997 -0.016196999699999999
0.032680001100000002 0.0335219987 -0.032370001099999997
0.032930001600000001 -0.016762999800000001 -0.032930001600000001
0.032930001600000001 -0.0082369995999999994 -0.032930001600000001
0.032930001600000001 0.0082369995999999994 -0.032930001600000001
0.032930001600000001 0.016762999800000001 -0.032930001600000001
0.032972000500000001 -0.024791000399999999 -0.0168079995
0.033080998799999997 -0.016919000100000001 -0.0080810003000000002
0.033080998799999997 -0.016919000100000001 0.0080810003000000002
-0.043630000199999998 -0.018629999800000002 -0.013718999900000001
0.033080998799999997 0.016919000100000001 -0.050000000699999998
0.033080998799999997 0.041919000400000003 -0.0080810003000000002
0.033080998799999997 0.041919000400000003 0.0080810003000000002
0.033080998799999997 0.050000000699999998 0.0080810003000000002
0.033236999099999998 -0.017812000599999999 -0.032930001600000001
0.033236999099999998 -0.0170699991 -0.032930001600000001
0.033236999099999998 -0.0079300003000000001 -0.032930001600000001
0.033236999099999998 0.0079300003000000001 -0.032930001600000001
0.050000000699999998 -0.016762999800000001 -0.032930001600000001
0.033236999099999998 0.0307030007 -0.032930001600000001
0.033578999300000002 -0.024958999799999999 -0.017366999800000001
0.050000000699999998 -0.0177040007 -0.0090380003999999993
0.034028001099999997 -0.017697000899999999 -0.0073029999999999996
0.050000000699999998 -0.017812000599999999 -0.032930001600000001
0.034028001099999997 -0.017697000899999999 0.0073029999999999996
0.034028001099999997 0.042697001200000001 -0.0073029999999999996
0.034028001099999997 0.042697001200000001 0.0073029999999999996
0.034269999699999998 -0.025066999699999998 -0.017851000700000001
0.034375000699999998 0.050000000699999998 0.0070870001999999996
0.050000000699999998 -0.0183879994 -0.0104019996
0.035027999400000003 -0.02513 -0.018239999199999999
0.035108 -0.018273999900000001 -0.0067260000000000002
0.035108 -0.018273999900000001 0.0067260000000000002
-0.043630000199999998 -0.013718999900000001 -0.018629999800000002
0.035108 0.043274000299999997 -0.0067260000000000002
0.035108 0.043274000299999997 0.0067260000000000002
0.035108 0.043274000299999997 0.018273999900000001
0.050000000699999998 -0.018719999099999999 -0.011892000200000001
0.035833999499999998 -0.0251630004 -0.018524000400000001
0.035881999900000003 0.050000000699999998 0.0064630000999999996
0.035881999900000003 0.050000000699999998 0.018536999799999999
0.050000000699999998 -0.0204450004 -0.012321
0.036281000799999998 -0.018629999800000002 -0.0063700001000000003
0.050000000699999998 -0.022016000000000001 -0.01315
0.036281000799999998 -0.018629999800000002 0.0063700001000000003
0.050000000699999998 -0.023344999200000001 -0.0143299997
0.036281000799999998 0.043630000199999998 -0.0063700001000000003
0.050000000699999998 -0.024351999199999998 -0.0157929994
0.036281000799999998 0.043630000199999998 0.0063700001000000003
0.050000000699999998 -0.024981999800000002 -0.0174550004
0.050000000699999998 -0.025195000700000001 -0.019218999899999999
0.050000000699999998 -0.025195000700000001 -0.025546999599999998
0.036281000799999998 0.043630000199999998 0.018629999800000002
0.036665998399999997 -0.025177000099999999 -0.018694000299999999
0.050000000699999998 -0.03125 -0.0125000002
0.036887001199999998 -0.018719999099999999 -0.0062799999000000004
0.036887001199999998 -0.018719999099999999 0.0062799999000000004
0.050000000699999998 -0.031463000900000003 0.035881999900000003
0.036887001199999998 0.043719999500000002 -0.0062799999000000004
0.036887001199999998 0.043719999500000002 0.0062799999000000004
0.050000000699999998 -0.031463000900000003 -0.010882000399999999
0.050000000699999998 -0.031463000900000003 -0.014117999900000001
0.036887001199999998 0.043719999500000002 0.018719999099999999
0.037500001499999998 -0.025180000800000001 -0.018750000700000002
0.037500001499999998 -0.018750000700000002 -0.0062500000999999999
0.050000000699999998 -0.032086998200000001 0.034375000699999998
0.037500001499999998 -0.018750000700000002 0.0062500000999999999
0.037500001499999998 0.043749999300000002 -0.0062500000999999999
0.050000000699999998 -0.032086998200000001 -0.015625
0.038113001700000003 -0.018719999099999999 0.0062799999000000004
0.050000000699999998 -0.033080998799999997 0.033080998799999997
0.038113001700000003 0.043719999500000002 -0.0062799999000000004
0.038334000899999998 -0.025177000099999999 -0.018694000299999999
0.050000000699999998 -0.033080998799999997 -0.016919000100000001
0.050000000699999998 -0.034375000699999998 0.032086998200000001
0.039165999700000002 -0.0251630004 -0.018524000400000001
0.0398919992 -0.018273999900000001 -0.0067260000000000002
0.050000000699999998 -0.034375000699999998 -0.017913000700000001
0.0398919992 -0.018273999900000001 0.0067260000000000002
0.039971999799999998 -0.02513 -0.018239999199999999
0.050000000699999998 -0.035881999900000003 0.031463000900000003
-0.050000000699999998 -0.0070870001999999996 -0.015625
0.040729999500000003 -0.025066999699999998 -0.017851000700000001
0.050000000699999998 -0.035881999900000003 -0.018536999799999999
0.050000000699999998 -0.035881999900000003 -0.031463000900000003
0.040972001899999999 -0.017697000899999999 -0.0073029999999999996
0.040972001899999999 -0.017697000899999999 0.0073029999999999996
0.050000000699999998 -0.037500001499999998 0.03125
0.041420999899999998 -0.024958999799999999 -0.017366999800000001
0.041763000199999997 -0.017812000599999999 -0.032930001600000001
0.050000000699999998 -0.037500001499999998 -0.018750000700000002
0.050000000699999998 -0.037500001499999998 -0.03125
0.041763000199999997 -0.0079300003000000001 -0.032930001600000001
0.050000000699999998 -0.039103001399999997 -0.018541000799999999
0.041763000199999997 0.0079300003000000001 -0.032930001600000001
0.050000000699999998 -0.039117999399999999 0.031463000900000003
0.041763000199999997 0.0170699991 -0.032930001600000001
0.041763000199999997 0.0307030007 -0.032930001600000001
0.050000000699999998 -0.039117999399999999 -0.031463000900000003
0.041919000400000003 -0.041919000400000003 0.033080998799999997
0.041919000400000003 -0.033080998799999997 0.033080998799999997
0.041919000400000003 -0.016919000100000001 -0.0080810003000000002
0.050000000699999998 -0.040624998500000002 0.032086998200000001
0.041919000400000003 -0.016919000100000001 0.0080810003000000002
0.042027998699999999 -0.024791000399999999 -0.0168079995
0.042070001400000001 -0.016762999800000001 -0.032930001600000001
0.042070001400000001 -0.0082369995999999994 -0.032930001600000001
0.042070001400000001 0.0082369995999999994 -0.032930001600000001
0.050000000699999998 -0.041919000400000003 0.033080998799999997
0.042070001400000001 0.016762999800000001 -0.032930001600000001
0.042539998900000001 -0.0245479997 -0.016196999699999999
0.042697001200000001 -0.042697001200000001 0.034028001099999997
0.042697001200000001 -0.040972001899999999 0.0323030017
0.042697001200000001 -0.034028001099999997 0.0323030017
0.042697001200000001 -0.0323030017 0.034028001099999997
0.050000000699999998 -0.042913000999999999 0.034375000699999998
0.042697001200000001 -0.015971999600000002 -0.0073029999999999996
0.042697001200000001 -0.015971999600000002 0.0073029999999999996
0.042697001200000001 -0.0073029999999999996 -0.034028001099999997
0.042697001200000001 0.0073029999999999996 -0.034028001099999997
-0.043274000299999997 0.035108 -0.043274000299999997
0.042962998199999998 -0.024211000699999999 -0.015535999999999999
0.050000000699999998 -0.043536998299999997 0.035881999900000003
0.043274000299999997 -0.043274000299999997 0.035108
0.043274000299999997 -0.0398919992 0.031725998999999998
0.043274000299999997 -0.035108 0.031725998999999998
0.043274000299999997 -0.031725998999999998 0.035108
0.043274000299999997 -0.0067260000000000002 -0.035108
0.043274000299999997 0.0067260000000000002 -0.035108
-0.043630000199999998 0.036281000799999998 -0.043630000199999998
0.043294001399999997 -0.023758999999999999 -0.0148440003
0.043517001 -0.023217000099999999 -0.014189000199999999
0.0435290001 0.039147999099999997 -0.018528999800000001
0.043630000199999998 -0.038718998400000003 0.031369999099999997
0.043630000199999998 -0.036281000799999998 0.031369999099999997
0.043630000199999998 -0.0063700001000000003 -0.036281000799999998
0.043630000199999998 0.0063700001000000003 -0.036281000799999998
0.043630000199999998 0.038718998400000003 -0.031369999099999997
0.043648999199999997 -0.022621000200000001 -0.0136160003
0.043719999500000002 -0.038113001700000003 0.0312799998
0.043719999500000002 -0.036887001199999998 0.0312799998
-0.043630000199999998 0.038718998400000003 -0.043630000199999998
0.043719999500000002 0.038113001700000003 -0.0312799998
0.043721999999999997 0.038086000799999999 -0.025546999599999998
0.043721999999999997 0.038086000799999999 -0.018721999600000001
0.043749999300000002 -0.037500001499999998 0.03125
-0.037500001499999998 0.03125 -0.03125
-0.038113001700000003 0.0312799998 -0.018719999099999999
-0.042697001200000001 -0.0090279998000000004 -0.017697000899999999
-0.038718998400000003 0.031369999099999997 -0.018629999800000002
0.050000000699999998 0.039117999399999999 -0.031463000900000003
0.016919000100000001 0.033080998799999997 -0.033080998799999997
0.016919000100000001 0.033080998799999997 -0.033080998799999997
0.017563000299999999 0.033835999700000001 -0.032232001400000002
0.017613999500000001 0.041092999300000002 -0.017613999500000001
0.017697000899999999 0.034028001099999997 -0.0323030017
0.018123999200000001 0.034775000100000002 -0.031706001599999999
0.018155999499999999 0.040160000299999998 -0.018155999499999999
0.018273999900000001 0.035108 -0.031725998999999998
0.018492000200000001 0.0357219987 -0.030960999400000001
0.018528999800000001 0.039147999099999997 -0.018528999800000001
0.018629999800000002 0.036281000799999998 -0.031369999099999997
0.0186730009 0.036520998899999997 -0.030092999299999999
0.018719999099999999 0.036887001199999998 -0.0312799998
-0.050000000699999998 -0.0080810003000000002 -0.016919000100000001
0.031725998999999998 0.043274000299999997 0.0101079997
0.031844001300000001 0.040160000299999998 -0.0068440000000000003
0.032086998200000001 0.015625 -0.050000000699999998
0.0323860012 0.041092999300000002 -0.0073859998999999997
0.033080998799999997 -0.016919000100000001 0.0080810003000000002
0.033080998799999997 0.041919000400000003 -0.0080810003000000002
0.033080998799999997 0.041919000400000003 0.0080810003000000002
0.034028001099999997 0.042697001200000001 -0.0073029999999999996
0.034028001099999997 0.042697001200000001 0.0073029999999999996
0.035108 0.043274000299999997 -0.0067260000000000002
0.036887001199999998 0.043719999500000002 -0.0062799999000000004
0.037500001499999998 0.043749999300000002 0.0062500000999999999
0.050000000699999998 -0.035881999900000003 -0.018536999799999999
0.050000000699999998 -0.037500001499999998 -0.018750000700000002
0.043274000299999997 -0.0067260000000000002 -0.035108
0.043630000199999998 -0.0063700001000000003 -0.036281000799999998
0.043719999500000002 -0.0062799999000000004 -0.036887001199999998
3 217 226 237
3 213 226 217
3 206 191 204
3 191 190 204
3 159 343 161
3 159 161 154
3 155 142 144
3 155 144 162
3 214 218 230
3 218 240 230
3 55 57 46
3 22 15 14
3 76 65 68
3 70 76 68
3 75 72 73
3 67 77 69
3 76 71 75
3 81 79 78
3 43 35 50
3 51 328 54
3 182 94 80
3 194 195 80
3 78 93 181
3 180 192 193
3 283 267 201
3 196 283 201
3 275 274 287
3 74 275 287
3 197 84 183
3 84 82 95
3 359 313 314
3 7 6 14
3 321 315 320
3 310 315 322
3 87 84 85
3 84 83 82
3 132 149 128
3 132 136 148
3 136 135 145
3 135 124 147
3 124 116 157
3 116 109 166
3 109 98 171
3 98 86 179
3 168 270 284
3 272 129 285
3 67 69 198
3 205 208 67
3 67 208 216
3 231 241 66
3 241 250 228
3 228 250 253
3 257 228 253
3 227 260 266
3 282 225 227
3 225 288 299
3 308 223 225
3 308 309 223
3 303 312 258
3 303 252 291
3 248 278 291
3 292 278 248
3 243 235 304
3 221 223 316
3 114 119 165
3 119 131 156
3 131 137 152
3 137 133 146
3 133 125 153
3 172 106 167
3 178 96 172
3 178 184 96
3 66 241 228
3 358 305 306
3 357 296 297
3 164 151 150
3 163 169 164
3 344 176 170
3 346 189 177
3 348 203 349
3 350 212 351
3 352 224 213
3 213 224 226
3 224 236 237
3 353 245 354
3 354 245 249
3 301 300 293
3 286 277 289
3 290 280 302
3 317 311 273
3 317 265 323
3 258 318 265
3 45 48 9
3 21 2 44
3 44 2 20
3 298 39 42
3 298 307 39
3 120 36 49
3 281 263 264
3 264 254 256
3 247 242 244
3 234 244 233
3 234 220 222
3 186 202 200
3 175 347 185
3 175 185 174
3 53 319 32
3 19 31 60
3 19 24 31
3 34 52 38
3 16 62 23
3 130 122 128
3 132 128 127
3 138 136 127
3 209 202 210
3 220 209 222
3 279 295 294
3 138 126 135
3 341 121 340
3 339 112 337
3 336 102 334
3 333 90 331
3 271 276 268
3 86 64 87
3 130 117 122
3 338 111 113
3 335 99 103
3 332 92 91
3 356 269 261
3 229 355 262
3 255 229 228
3 251 228 246
3 239 227 225
3 246 227 239
3 238 223 221
3 158 28 259
3 143 18 4
3 232 223 238
3 215 207 219
3 207 199 219
3 11 3 8
3 5 342 29
3 326 141 59
3 47 17 61
3 1 47 12
3 27 211 13
3 27 13 33
3 56 10 30
3 37 10 56
3 0 8 58
3 3 187 8
3 140 97 139
3 118 173 160
3 108 115 139
3 115 123 139
3 107 101 104
3 88 345 105
3 88 188 345
3 25 134 324
3 40 325 26
3 110 327 41
3 64 329 63
3 330 100 89

View File

@ -0,0 +1,36 @@
OFF
24 8 0
-0.038718998400000003 0.031369999099999997 -0.018629999800000002
-0.038718998400000003 0.031369999099999997 -0.031369999099999997
0.015971999600000002 0.017697000899999999 -0.0323030017
0.015971999600000002 0.0323030017 -0.0323030017
0.016797000499999999 0.0170389991 -0.032930001600000001
0.016797000499999999 0.0170389991 -0.0170389991
0.016797000499999999 0.0307030007 -0.032930001600000001
0.016797000499999999 0.031846001700000001 -0.032841000699999998
0.016797000499999999 0.032960999800000002 -0.032575998500000002
0.016919000100000001 0.016919000100000001 -0.033080998799999997
0.016919000100000001 0.033080998799999997 -0.033080998799999997
0.0170699991 0.016762999800000001 -0.032930001600000001
0.017697000899999999 0.017697000899999999 -0.034028001099999997
0.017697000899999999 0.0323030017 -0.034028001099999997
-0.0398919992 0.031725998999999998 -0.018273999900000001
0.0323030017 0.017697000899999999 -0.034028001099999997
0.032680001100000002 0.0335219987 -0.032370001099999997
0.032930001600000001 0.016762999800000001 -0.032930001600000001
0.033309001499999998 0.031690999900000003 -0.032862998499999997
0.016797000499999999 0.0307030007 -0.032930001600000001
0.016797000499999999 0.0307030007 -0.032930001600000001
0.016919000100000001 0.016919000100000001 -0.033080998799999997
0.016919000100000001 0.033080998799999997 -0.033080998799999997
0.017563000299999999 0.033835999700000001 -0.032232001400000002
3 17 6 11
3 20 5 4
3 23 8 16
3 7 19 18
3 12 15 9
3 14 0 1
3 3 10 2
3 22 13 21

View File

@ -117,14 +117,14 @@ Qt is a cross-platform application and UI framework.
The component `CGAL_Qt6` is essential to run the \cgal demos and basic viewers.
It requires \qt6 installed on your system.
In case \qt is not yet installed on your system, you can download
it from <A HREF="https://www.qt-project.org/">`https://www.qt-project.org/`</A>.
it from <A HREF="https://contribute.qt-project.org/">`https://contribute.qt-project.org/`</A>.
The exhaustive list of \qt6 components used in demos is:
`Core`, `Gui`, `Help`, `OpenGL`, `OpenGLWidgets`, `Qml`, `Svg`, `Widgets`,
`WebSockets`, `Network`, and `qcollectiongenerator` (with `sqlite` driver plugin).
\subsection thirdpartyEigen Eigen
<b>Version 3.3.7 or later</b>
<b>Version 3.3.7 or later (including Eigen3 5.0.0)</b>
\eigen is a `C++` template library for linear algebra. \eigen supports all
matrix sizes, various matrix decomposition methods and sparse linear solvers.
@ -138,7 +138,7 @@ Overview</a> page. In order to use Eigen in \cgal programs, the
executables should be linked with the CMake imported target
`CGAL::Eigen3_support` provided in `CGAL_Eigen3_support.cmake`.
The \eigen web site is <A HREF="https://eigen.tuxfamily.org/index.php?title=Main_Page">`https://eigen.tuxfamily.org`</A>.
The \eigen web site is <A HREF="https://libeigen.gitlab.io/">`https://libeigen.gitlab.io/`</A>.
\subsection thirdpartyOpenGR OpenGR
@ -167,17 +167,6 @@ Alternatively, version 1.3.1 of \libpointmatcher is supported with version 3.3.7
`https://github.com/ethz-asl/libpointmatcher/blob/master/doc/Compilation.md`:`NABO_INCLUDE_DIR` becomes `libnabo_INCLUDE_DIRS`
and `NABO_LIBRARY` becomes `libnabo_LIBRARIES` in the "Build libpointmatcher" section.
\subsection thirdpartyLeda LEDA
<b>Version 6.2 or later</b>
\leda is a library of efficient data structures and
algorithms. Like \core, \leda offers a real number data type.
In \cgal this library is optional, and its number types can
be used as an alternative to \gmp, \mpfr, and \core.
Free and commercial editions of \leda are available from <A HREF="https://www.algorithmic-solutions.com">`https://www.algorithmic-solutions.com`</A>.
\subsection thirdpartyMPFI Multiple Precision Floating-point Interval (MPFI)
<b>Version 1.4 or later</b>
@ -265,7 +254,7 @@ vcpkg install suitesparse
\subsection thirdpartyMETIS METIS
<b>Version 5.1 or later</b>
\metis is a library developed by the <A HREF="http://glaros.dtc.umn.edu/gkhome/">Karypis Lab</A>
\metis is a library developed by the <A HREF="https://github.com/KarypisLab/">Karypis Lab</A>
and designed to partition graphs and produce fill-reducing matrix orderings.
\cgal offers wrappers around some of the methods of the \metis library
@ -274,7 +263,7 @@ to allow the partitioning of graphs that are models of the concepts of the
and, by extension, of surface meshes (see Section \ref BGLPartitioning of the package \ref PkgBGL).
More information is available on the METIS library
at <A HREF="http://glaros.dtc.umn.edu/gkhome/metis/metis/overview">`http://glaros.dtc.umn.edu/gkhome/metis/metis/overview`</A>.
at <A HREF="https://github.com/KarypisLab/METIS">`https://github.com/KarypisLab/METIS`</A>.
\subsection thirdpartyzlib zlib

View File

@ -83,12 +83,12 @@ a newline character and each coordinate separated by a white
space. Other formats available are 'OFF', 'PLY' and 'LAS'. \cgal
provides functions to read such formats:
- `read_XYZ()`
- `read_OFF()`
- `read_PLY()`
- `read_PLY_with_properties()` to read additional PLY properties
- `read_LAS()`
- `read_LAS_with_properties()` to read additional LAS properties
- `CGAL::IO::read_XYZ()`
- `CGAL::IO::read_OFF()`
- `CGAL::IO::read_PLY()`
- `CGAL::IO::read_PLY_with_properties()` to read additional PLY properties
- `CGAL::IO::read_LAS()`
- `CGAL::IO::read_LAS_with_properties()` to read additional LAS properties
\cgal also provides a dedicated container `CGAL::Point_set_3` to
handle point sets with additional properties such as normal

View File

@ -7,7 +7,7 @@ project( Frechet_distance_Examples )
find_package(CGAL REQUIRED QUIET OPTIONAL_COMPONENTS Core )
find_package(Eigen3 3.1.0 QUIET) #(requires 3.1.0 or greater)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
create_single_source_cgal_program( "Frechet_distance_2.cpp" )

View File

@ -6,11 +6,12 @@ project( Frechet_distance_Tests )
find_package(CGAL REQUIRED)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
create_single_source_cgal_program( "Frechet-IssueOct25.cpp" )
find_package(Eigen3 3.1.0 QUIET) #(3.1.0 or greater)
include(CGAL_Eigen3_support)
if(TARGET CGAL::Eigen3_support)
create_single_source_cgal_program( "Frechet_distance_test.cpp" )
target_link_libraries(Frechet_distance_test PRIVATE CGAL::Eigen3_support)

View File

@ -6,8 +6,7 @@ project( classical_Frechet_distance )
find_package(CGAL REQUIRED)
find_package(Eigen3 3.1.0 QUIET) #(requires 3.1.0 or greater)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
create_single_source_cgal_program("Compute_classical_Frechet_distance_3.cpp")

View File

@ -28,8 +28,9 @@ create_single_source_cgal_program("random_segments1.cpp")
create_single_source_cgal_program("random_segments2.cpp")
create_single_source_cgal_program("sphere_d.cpp")
find_package(Eigen3 3.1.0 QUIET) #(3.1.0 or greater)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
if(TARGET CGAL::Eigen3_support)
create_single_source_cgal_program("random_points_in_tetrahedral_mesh_3.cpp")
target_link_libraries(random_points_in_tetrahedral_mesh_3 PRIVATE CGAL::Eigen3_support)

View File

@ -15,8 +15,9 @@ create_single_source_cgal_program("test_tetrahedron_3.cpp")
create_single_source_cgal_program("test_triangle_2.cpp")
create_single_source_cgal_program("test_triangle_3.cpp")
find_package(Eigen3 3.1.0 QUIET) #(3.1.0 or greater)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
if(TARGET CGAL::Eigen3_support)
create_single_source_cgal_program("generic_random_test.cpp")
target_link_libraries(generic_random_test PRIVATE CGAL::Eigen3_support)

View File

@ -8,7 +8,7 @@ find_package(CGAL REQUIRED OPTIONAL_COMPONENTS Qt6)
find_package(Qt6 QUIET COMPONENTS Widgets)
find_package(Eigen3 3.1.91 QUIET) #(requires 3.1.91 or greater)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
if(NOT TARGET CGAL::Eigen3_support)

View File

@ -6,8 +6,9 @@ project(Polygon_Demo)
find_package(CGAL REQUIRED OPTIONAL_COMPONENTS Qt6 Core)
find_package(Eigen3 3.1.0 QUIET) #(requires 3.1.0 or greater)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
if(NOT TARGET CGAL::Eigen3_support)
message("NOTICE: This demo requires the Eigen library, and will not be compiled.")
return()

View File

@ -13,12 +13,12 @@
\cgalPkgPicture{detail.png}
\cgalPkgSummaryBegin
\cgalPkgAuthors{Andreas Fabri and Laurent Rineau}
\cgalPkgDesc{This package provides classes for displaying \cgal objects and data structures in the <A HREF="https://doc.qt.io/qt-6/graphicsview.html">Qt 5 Graphics View Framework</A>.}
\cgalPkgDesc{This package provides classes for displaying \cgal objects and data structures in the <A HREF="https://doc.qt.io/qt-6/graphicsview.html">Qt 6 Graphics View Framework</A>.}
\cgalPkgManuals{Chapter_CGAL_and_the_Qt_Graphics_View_Framework,PkgGraphicsViewRef}
\cgalPkgSummaryEnd
\cgalPkgShortInfoBegin
\cgalPkgSince{3.4}
\cgalPkgDependsOn{\qt 5}
\cgalPkgDependsOn{\qt 6}
\cgalPkgBib{cgal:fr-cqgvf}
\cgalPkgLicense{\ref licensesGPL "GPL"}
\cgalPkgShortInfoEnd

View File

@ -221,7 +221,10 @@ void
DemosMainWindow::popupAboutBox(QString title, QString html_resource_name)
{
QFile about_CGAL(html_resource_name);
about_CGAL.open(QIODevice::ReadOnly);
if (!about_CGAL.open(QIODevice::ReadOnly)) {
QMessageBox::warning(this, tr("Error"), tr("Could not open resource file: %1").arg(html_resource_name));
return;
}
QString about_CGAL_txt = QTextStream(&about_CGAL).readAll();
#ifdef CGAL_VERSION_STR
QString cgal_version(CGAL_VERSION_STR);

View File

@ -7,8 +7,9 @@ project(Heat_method_3_Examples)
# CGAL and its components
find_package(CGAL REQUIRED)
find_package(Eigen3 3.3.0 QUIET)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
if(NOT TARGET CGAL::Eigen3_support)
message("NOTICE: These examples require the Eigen library (3.3 or greater), and will not be compiled.")
return()

View File

@ -7,8 +7,9 @@ project(Heat_method_3_Tests)
# CGAL and its components
find_package(CGAL REQUIRED)
find_package(Eigen3 3.3.0 QUIET)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
if(NOT TARGET CGAL::Eigen3_support)
message("NOTICE: These tests require the Eigen library (3.3 or greater), and will not be compiled.")
return()

File diff suppressed because it is too large Load Diff

View File

@ -3,5 +3,5 @@ if(CERES_FOUND AND NOT TARGET CGAL::Ceres_support)
set_target_properties(CGAL::Ceres_support PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "CGAL_PMP_USE_CERES_SOLVER"
INTERFACE_INCLUDE_DIRECTORIES "${CERES_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "ceres")
INTERFACE_LINK_LIBRARIES "Ceres::ceres")
endif()

View File

@ -1,3 +1,10 @@
if((EIGEN3_FOUND OR Eigen3_FOUND) AND NOT TARGET CGAL::Eigen3_support)
if ("${Eigen3_VERSION}" VERSION_LESS "3.3.7")
set (EIGEN3_FOUND 0)
find_package(Eigen3 3.3.7 QUIET) # (3.3.7 or greater)
endif()
endif()
if((EIGEN3_FOUND OR Eigen3_FOUND) AND NOT TARGET CGAL::Eigen3_support)
if(NOT TARGET Threads::Threads)
find_package(Threads REQUIRED)

View File

@ -554,6 +554,11 @@ namespace cpp11{
/// @}
#include <CGAL/license/lgpl.h>
#ifdef __STDC_LIB_EXT1__
# define __STDC_WANT_LIB_EXT1__ 1
# include <stdlib.h> // for getenv_s
#endif
//----------------------------------------------------------------------//
// Function to define data directory
//----------------------------------------------------------------------//

View File

@ -6,7 +6,7 @@ project( Isosurfacing_3_benchmark )
find_package(CGAL REQUIRED)
find_package(Eigen3 3.1.0 QUIET) #(3.1.0 or greater)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
find_package(TBB)

View File

@ -6,7 +6,7 @@ project( Isosurfacing_3_Examples )
find_package(CGAL REQUIRED COMPONENTS ImageIO)
find_package(Eigen3 3.1.0 QUIET) #(3.1.0 or greater)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
find_package(TBB QUIET)

View File

@ -4,7 +4,7 @@ project(Isosurfacing_3_Tests)
find_package(CGAL REQUIRED)
find_package(Eigen3 3.1.0 QUIET) #(3.1.0 or greater)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
find_package(TBB QUIET)

View File

@ -7,8 +7,9 @@ project(Jet_fitting_3_Examples)
find_package(CGAL REQUIRED)
# use Eigen
find_package(Eigen3 3.1.0 QUIET) #(requires 3.1.0 or greater)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
if(TARGET CGAL::Eigen3_support)
# Link with Boost.ProgramOptions (optional)

View File

@ -7,8 +7,9 @@ project(Jet_fitting_3_Tests)
find_package(CGAL REQUIRED)
# use Eigen
find_package(Eigen3 3.1.0 QUIET) #(requires 3.1.0 or greater)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
if(TARGET CGAL::Eigen3_support)
create_single_source_cgal_program("blind_1pt.cpp")
target_link_libraries(blind_1pt PRIVATE CGAL::Eigen3_support)

View File

@ -48,7 +48,7 @@ Cartesian_converter<>();
/// @{
/*!
returns a `K2::Point_2` which coordinates are those of `p`,
returns a `K2::Point_2` whose coordinates are those of `p`,
converted by `NTConverter`.
*/
K2::Point_2 operator()(const K1::Point_2&p);

View File

@ -8,7 +8,7 @@ project(Kinetic_space_partition_Examples)
find_package(CGAL REQUIRED)
include(CGAL_CreateSingleSourceCGALProgram)
find_package(Eigen3 3.1.0 REQUIRED)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
if(TARGET CGAL::Eigen3_support)

View File

@ -8,7 +8,7 @@ project(Kinetic_space_partition_Tests)
find_package(CGAL REQUIRED)
include(CGAL_CreateSingleSourceCGALProgram)
find_package(Eigen3 3.1.0 REQUIRED)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
set(targets kinetic_3d_test_all issue_8624)

View File

@ -8,7 +8,7 @@ project(Kinetic_surface_reconstruction_Examples)
find_package(CGAL REQUIRED)
include(CGAL_CreateSingleSourceCGALProgram)
find_package(Eigen3 3.1.0 REQUIRED)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
if(TARGET CGAL::Eigen3_support)

View File

@ -8,7 +8,7 @@ project(Kinetic_surface_reconstruction_Tests)
find_package(CGAL REQUIRED)
include(CGAL_CreateSingleSourceCGALProgram)
find_package(Eigen3 3.1.0 REQUIRED)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
if(TARGET CGAL::Eigen3_support)

View File

@ -51,12 +51,14 @@ if(Qt6_FOUND)
add_compile_definitions(QT_NO_KEYWORDS)
endif(Qt6_FOUND)
find_package(Eigen3 3.2.0 QUIET) #(requires 3.2.0 or greater)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
set_package_properties(
Eigen3 PROPERTIES
DESCRIPTION "A library for linear algebra."
PURPOSE "Required for most plugins (Meshing, Mesh and Point Set Processing, etc.).")
include(CGAL_Eigen3_support)
if(NOT TARGET CGAL::Eigen3_support)
message(STATUS "NOTICE: Eigen was not found.")
endif()

View File

@ -96,7 +96,7 @@ load(QFileInfo fileinfo, bool& ok, bool add_to_scene) {
}
else
{
ok = true;
ok = false;
return QList<Scene_item*>();
}
}

View File

@ -7,6 +7,7 @@
#include <CGAL/Three/CGAL_Lab_io_plugin_interface.h>
#include <CGAL/Surface_mesh/IO/PLY.h>
#include <CGAL/Three/Three.h>
#include <CGAL/use.h>
#include <QInputDialog>
#include <QApplication>
@ -132,8 +133,9 @@ load(QFileInfo fileinfo, bool& ok, bool add_to_scene) {
std::vector<CGAL::IO::Color> fcolors;
std::vector<CGAL::IO::Color> vcolors;
if (!(CGAL::IO::read_PLY (in, points, polygons, fcolors, vcolors)))
if (!(CGAL::IO::read_PLY (in, points, polygons, comments, fcolors, vcolors)))
{
CGAL_USE(comments);
QApplication::restoreOverrideCursor();
ok = false;
return QList<Scene_item*>();

View File

@ -78,8 +78,9 @@ target_link_libraries(
CGAL_Lab_target_use_c3t3_type(mesh_3_optimization_plugin)
# Use Eigen
find_package(Eigen3 3.1.0 QUIET) #(3.1.0 or greater)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
if(TARGET CGAL::Eigen3_support)
target_link_libraries(mesh_3_optimization_plugin PRIVATE CGAL::Eigen3_support)
else()

View File

@ -28,61 +28,57 @@ target_link_libraries(extrude_plugin PRIVATE scene_surface_mesh_item
scene_selection_item)
if(TARGET CGAL::Eigen3_support)
if("${Eigen3_VERSION}" VERSION_GREATER "3.1.90")
qt6_wrap_ui( acvd_remeshingUI_FILES ACVD_remeshing_dialog.ui)
cgal_lab_plugin(acvd_remeshing_plugin ACVD_remeshing_plugin ${acvd_remeshingUI_FILES} KEYWORDS PMP)
target_link_libraries(acvd_remeshing_plugin PUBLIC scene_surface_mesh_item scene_points_with_normal_item scene_polygon_soup_item CGAL::Eigen3_support)
qt6_wrap_ui( acvd_remeshingUI_FILES ACVD_remeshing_dialog.ui)
cgal_lab_plugin(acvd_remeshing_plugin ACVD_remeshing_plugin ${acvd_remeshingUI_FILES} KEYWORDS PMP)
target_link_libraries(acvd_remeshing_plugin PUBLIC scene_surface_mesh_item scene_points_with_normal_item scene_polygon_soup_item CGAL::Eigen3_support)
qt6_wrap_ui( hole_fillingUI_FILES Hole_filling_widget.ui)
cgal_lab_plugin(hole_filling_plugin Hole_filling_plugin ${hole_fillingUI_FILES} KEYWORDS PMP)
target_link_libraries(hole_filling_plugin PRIVATE scene_surface_mesh_item scene_polylines_item scene_selection_item CGAL::Eigen3_support)
qt6_wrap_ui( hole_fillingUI_FILES Hole_filling_widget.ui)
cgal_lab_plugin(hole_filling_plugin Hole_filling_plugin ${hole_fillingUI_FILES} KEYWORDS PMP)
target_link_libraries(hole_filling_plugin PRIVATE scene_surface_mesh_item scene_polylines_item scene_selection_item CGAL::Eigen3_support)
qt6_wrap_ui( fairingUI_FILES Fairing_widget.ui)
cgal_lab_plugin(fairing_plugin Fairing_plugin ${fairingUI_FILES} KEYWORDS PMP)
target_link_libraries(fairing_plugin PRIVATE scene_selection_item CGAL::Eigen3_support)
qt6_wrap_ui( fairingUI_FILES Fairing_widget.ui)
cgal_lab_plugin(fairing_plugin Fairing_plugin ${fairingUI_FILES} KEYWORDS PMP)
target_link_libraries(fairing_plugin PRIVATE scene_selection_item CGAL::Eigen3_support)
qt6_wrap_ui( Mean_curvature_flow_skeleton_pluginUI_FILES Mean_curvature_flow_skeleton_plugin.ui)
cgal_lab_plugin(mean_curvature_flow_skeleton_plugin Mean_curvature_flow_skeleton_plugin ${Mean_curvature_flow_skeleton_pluginUI_FILES})
target_link_libraries(mean_curvature_flow_skeleton_plugin
PRIVATE
scene_surface_mesh_item
scene_points_with_normal_item
scene_polylines_item
scene_mcf_item
demo_framework
CGAL::Eigen3_support)
# The smoothing plugin can still do some things, even if Ceres is not found
qt6_wrap_ui( smoothingUI_FILES Smoothing_plugin.ui Smoothing_tangential_relaxation.ui)
cgal_lab_plugin(smoothing_plugin Smoothing_plugin ${smoothingUI_FILES})
target_link_libraries(smoothing_plugin PRIVATE scene_surface_mesh_item scene_selection_item CGAL::Eigen3_support)
find_package(Ceres QUIET)
include(CGAL_Ceres_support)
if(TARGET CGAL::Ceres_support)
target_link_libraries(smoothing_plugin PRIVATE CGAL::Ceres_support)
endif()
qt6_wrap_ui( Mean_curvature_flow_skeleton_pluginUI_FILES Mean_curvature_flow_skeleton_plugin.ui)
cgal_lab_plugin(mean_curvature_flow_skeleton_plugin Mean_curvature_flow_skeleton_plugin ${Mean_curvature_flow_skeleton_pluginUI_FILES})
target_link_libraries(mean_curvature_flow_skeleton_plugin
PRIVATE
scene_surface_mesh_item
scene_points_with_normal_item
scene_polylines_item
scene_mcf_item
demo_framework
CGAL::Eigen3_support)
# The smoothing plugin can still do some things, even if Ceres is not found
qt6_wrap_ui( smoothingUI_FILES Smoothing_plugin.ui Smoothing_tangential_relaxation.ui)
cgal_lab_plugin(smoothing_plugin Smoothing_plugin ${smoothingUI_FILES})
target_link_libraries(smoothing_plugin PRIVATE scene_surface_mesh_item scene_selection_item CGAL::Eigen3_support)
find_package(Ceres QUIET)
include(CGAL_Ceres_support)
if(TARGET CGAL::Ceres_support)
target_link_libraries(smoothing_plugin PRIVATE CGAL::Ceres_support)
endif()
set_package_properties(
Ceres PROPERTIES
DESCRIPTION "A large scale non-linear optimization library."
PURPOSE "Can be used as a solver in the smoothing plugin.")
target_link_libraries(extrude_plugin PRIVATE CGAL::Eigen3_support)
set_package_properties(
Ceres PROPERTIES
DESCRIPTION "A large scale non-linear optimization library."
PURPOSE "Can be used as a solver in the smoothing plugin.")
target_link_libraries(extrude_plugin PRIVATE CGAL::Eigen3_support)
qt6_wrap_ui(remeshPlanarPatchesUI_FILES Remesh_planar_patches_dialog.ui)
cgal_lab_plugin(remesh_planar_patches_plugin Remesh_planar_patches_plugin
${remeshPlanarPatchesUI_FILES} KEYWORDS PMP CDT_3)
target_link_libraries(remesh_planar_patches_plugin PRIVATE scene_surface_mesh_item CGAL::Eigen3_support)
qt6_wrap_ui(remeshPlanarPatchesUI_FILES Remesh_planar_patches_dialog.ui)
cgal_lab_plugin(remesh_planar_patches_plugin Remesh_planar_patches_plugin
${remeshPlanarPatchesUI_FILES} KEYWORDS PMP CDT_3)
target_link_libraries(remesh_planar_patches_plugin PRIVATE scene_surface_mesh_item CGAL::Eigen3_support)
if(CGAL_ENABLE_TESTING AND NOT CMAKE_VS_MSBUILD_COMMAND)
set_tests_properties(
"compilation of extrude_plugin"
"compilation of fairing_plugin"
"compilation of hole_filling_plugin"
"compilation of remesh_planar_patches_plugin"
"compilation of smoothing_plugin"
PROPERTIES RESOURCE_LOCK Selection_test_resources)
endif()
else()
message(STATUS "NOTICE: The hole filling and fairing plugins require Eigen 3.2 (or higher) and will not be available.")
if(CGAL_ENABLE_TESTING AND NOT CMAKE_VS_MSBUILD_COMMAND)
set_tests_properties(
"compilation of extrude_plugin"
"compilation of fairing_plugin"
"compilation of hole_filling_plugin"
"compilation of remesh_planar_patches_plugin"
"compilation of smoothing_plugin"
PROPERTIES RESOURCE_LOCK Selection_test_resources)
endif()
else()
message(STATUS "NOTICE: The hole filling and fairing plugins require Eigen 3.2 (or higher) and will not be available.")

View File

@ -1,6 +1,6 @@
include(CGALlab_macros)
if(TARGET CGAL::Eigen3_support AND "${Eigen3_VERSION}" VERSION_GREATER "3.1.90")
if(TARGET CGAL::Eigen3_support)
qt6_wrap_ui(editionUI_FILES Deform_mesh.ui)
add_item(scene_edit_item

View File

@ -14,7 +14,7 @@ cgal_lab_plugin(
target_link_libraries(tetrahedral_remeshing_plugin PRIVATE scene_c3t3_item
${OPENGL_gl_LIBRARY})
CGAL_Lab_target_use_c3t3_type(tetrahedral_remeshing_plugin)
find_package(Eigen3 3.1.0 REQUIRED) #(3.1.0 or greater)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
if(TARGET CGAL::Eigen3_support)
target_link_libraries(tetrahedral_remeshing_plugin PRIVATE CGAL::Eigen3_support)

View File

@ -1563,7 +1563,7 @@ bool
Scene_surface_mesh_item::load_obj(std::istream& in)
{
typedef SMesh::Point Point;
bool failed = !CGAL::IO::read_OBJ(in, *(d->smesh_));
bool failed = !CGAL::IO::read_OBJ(in, *(d->smesh_), CGAL::parameters::verbose(true));
if(failed)
{
in.clear();

View File

@ -78,6 +78,9 @@ pushd Triangulation_on_sphere_2_Demo_with_dlls; zip -r ../triangulation_on_spher
pushd Lab_Demo_with_dlls; zip -r ../CGALlab.zip *; popd
pushd Arrangement_on_surface_2_earth_Demo_with_dlls; zip -r ../arrangements_2_earth.zip *; popd
# CGAL-6.1
pushd Triangulation_on_hyperbolic_surface_2_Demo_with_dlls; zip -r ../triangulation_on_hyperbolic_surface_2.zip *; popd
# check
echo CHECK now. The following lines should be empty.
for f in *zip; do unzip -qql $f; done | awk '{print $4}' >| done

View File

@ -19,8 +19,9 @@ if(CGAL_ACTIVATE_CONCURRENT_MESH_3 OR "$ENV{CGAL_ACTIVATE_CONCURRENT_MESH_3}")
endif()
# Use Eigen
find_package(Eigen3 3.1.0 QUIET) #(3.1.0 or greater)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
if(NOT TARGET CGAL::Eigen3_support)
message("NOTICE: All examples require the Eigen3 library, and will not be compiled.")
return()

View File

@ -7,8 +7,9 @@ project( Mesh_3_Tests )
find_package(CGAL REQUIRED COMPONENTS ImageIO)
# Use Eigen
find_package(Eigen3 3.1.0 QUIET) #(3.1.0 or greater)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
if (NOT TARGET CGAL::Eigen3_support)
message("NOTICE: This project requires the Eigen library, and will not be compiled.")
return()

View File

@ -14,6 +14,7 @@ find_package(CGAL REQUIRED)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
if(TARGET CGAL::Eigen3_support)
file(
GLOB cppfiles

View File

@ -476,6 +476,9 @@ typedef int FPU_CW_t;
#define CGAL_FE_DOWNWARD FE_DOWNWARD
#endif
#define CGAL_FE_ROUNDING_MASK ((CGAL_FE_TONEAREST | CGAL_FE_TOWARDZERO | CGAL_FE_UPWARD | CGAL_FE_DOWNWARD) \
& ~(CGAL_FE_TONEAREST & CGAL_FE_TOWARDZERO & CGAL_FE_UPWARD & CGAL_FE_DOWNWARD)) // mask for rounding bits
// User interface:
inline
@ -484,7 +487,8 @@ FPU_get_cw (void)
{
#ifdef CGAL_ALWAYS_ROUND_TO_NEAREST
CGAL_assertion_code(FPU_CW_t cw; CGAL_IA_GETFPCW(cw);)
CGAL_assertion(cw == CGAL_FE_TONEAREST);
CGAL_assertion_code(FPU_CW_t mask = CGAL_FE_ROUNDING_MASK;)
CGAL_assertion((cw & mask) == (CGAL_FE_TONEAREST & mask));
return CGAL_FE_TONEAREST;
#else
FPU_CW_t cw;

View File

@ -80,8 +80,10 @@ if(NOT CGAL_DISABLE_GMP)
create_single_source_cgal_program( "Gmpfi.cpp" )
create_single_source_cgal_program( "Gmpfr_bug.cpp" )
create_single_source_cgal_program( "test_eigen.cpp" )
find_package(Eigen3 3.2.0 QUIET) #(requires 3.2.0 or greater)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
if (TARGET CGAL::Eigen3_support)
target_link_libraries(test_eigen PRIVATE CGAL::Eigen3_support)
endif()

View File

@ -7,8 +7,9 @@ project(Optimal_bounding_box_Benchmark)
# CGAL and its components
find_package(CGAL REQUIRED)
find_package(Eigen3 3.1.0 QUIET) #(3.1.0 or greater)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
if(NOT TARGET CGAL::Eigen3_support)
message("NOTICE: This project requires the Eigen library, and will not be compiled.")
return()

View File

@ -6,8 +6,9 @@ project(Optimal_bounding_box_Examples)
find_package(CGAL REQUIRED)
find_package(Eigen3 3.1.0 QUIET) #(3.1.0 or greater)
find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support)
if(NOT TARGET CGAL::Eigen3_support)
message("NOTICE: This project requires the Eigen library, and will not be compiled.")
return()

Some files were not shown because too many files have changed in this diff Show More