mirror of https://github.com/CGAL/cgal
initial version moved from Exacus' GAPS
This commit is contained in:
parent
ae7b171c32
commit
c8ef6179c1
|
|
@ -0,0 +1,214 @@
|
|||
// ============================================================================
|
||||
//
|
||||
// Copyright (c) 2001-2008 Max-Planck-Institut Saarbruecken (Germany).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of EXACUS (http://www.mpi-inf.mpg.de/projects/EXACUS/);
|
||||
// you may redistribute it under the terms of the Q Public License version 1.0.
|
||||
// See the file LICENSE.QPL distributed with EXACUS.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Library : SoX
|
||||
// File : include/SoX/GAPS/Adjacencies_3.h
|
||||
// SoX_release : $Name: $
|
||||
// Revision : $Revision$
|
||||
// Revision_date : $Date$
|
||||
//
|
||||
// Author(s) : Eric Berberich <eric@mpi-inf.mpg.de>
|
||||
// Michael Kerber <mkerber@mpi-inf.mpg.de>
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
#ifndef SoX_GAPS_ADJACENCIES_3_H
|
||||
#define SoX_GAPS_ADJACENCIES_3_H 1
|
||||
|
||||
/*! \file SoX/GAPS/Adjacencies_3
|
||||
\brief Contains Adjacencies_3 class
|
||||
*/
|
||||
|
||||
#include <CGAL/config.h>
|
||||
#include <CGAL/Handle_with_policy.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
namespace SoX {
|
||||
|
||||
|
||||
namespace Intern {
|
||||
|
||||
class Adjacencies_3_rep {
|
||||
|
||||
public:
|
||||
|
||||
//! the class itself
|
||||
typedef Adjacencies_3_rep Self;
|
||||
|
||||
//! a pair of adjacencies
|
||||
typedef std::pair< int, int > Adjacency_pair;
|
||||
|
||||
//! an interval
|
||||
typedef std::pair< int, int > Adjacency_interval;
|
||||
|
||||
//! an adjacency vector
|
||||
typedef std::vector < Adjacency_pair > Adjacency_vector;
|
||||
|
||||
//! Default constructor
|
||||
Adjacencies_3_rep() {
|
||||
}
|
||||
|
||||
//! Constructor with data
|
||||
Adjacencies_3_rep(Adjacency_vector data) :
|
||||
_m_data(data) {
|
||||
}
|
||||
|
||||
Adjacency_vector _m_data;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Intern
|
||||
|
||||
//! The Adjacency output object
|
||||
class Adjacencies_3 :
|
||||
public CGAL::Handle_with_policy< Intern::Adjacencies_3_rep > {
|
||||
|
||||
public:
|
||||
//! the class itself
|
||||
typedef Adjacencies_3 Self;
|
||||
|
||||
//! the rep type
|
||||
typedef Intern::Adjacencies_3_rep Rep;
|
||||
|
||||
//! the base type
|
||||
typedef CGAL::Handle_with_policy< Rep > Base;
|
||||
|
||||
//! a pair of adjacencies
|
||||
typedef std::pair< int, int > Adjacency_pair;
|
||||
|
||||
//! an interval
|
||||
typedef std::pair< int, int > Adjacency_interval;
|
||||
|
||||
//! a vector of adjacency
|
||||
typedef std::vector < Adjacency_pair > Adjacency_vector;
|
||||
|
||||
//! const version
|
||||
typedef Adjacency_vector::const_iterator Const_adjacency_iterator;
|
||||
|
||||
public:
|
||||
|
||||
//! Default constructor
|
||||
Adjacencies_3() :
|
||||
Base(Rep()) {
|
||||
}
|
||||
|
||||
//! Constructor with data
|
||||
Adjacencies_3(Adjacency_vector data) :
|
||||
Base(Rep(data)) {
|
||||
}
|
||||
|
||||
//! Returns an interval [i,j] such that all sheets between
|
||||
//! i and j are adjacenct to index
|
||||
Adjacency_interval interval(int index) const {
|
||||
|
||||
std::vector<int> adjacent_features;
|
||||
|
||||
for (int i = 0;
|
||||
i < static_cast<int>(this->ptr()->_m_data.size());
|
||||
i++) {
|
||||
if (this->ptr()->_m_data[i].first == index) {
|
||||
adjacent_features.push_back(this->ptr()->_m_data[i].second);
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(adjacent_features.begin(), adjacent_features.end());
|
||||
|
||||
int n = static_cast<int>(adjacent_features.size());
|
||||
|
||||
if (n == 0) {
|
||||
return std::make_pair(1,0);
|
||||
}
|
||||
// Make sure that the adjacent features form an interval
|
||||
for (int i = 0; i < n-1; i++) {
|
||||
|
||||
CGAL_assertion( adjacent_features[i] ==
|
||||
adjacent_features[i+1]-1 );
|
||||
|
||||
}
|
||||
|
||||
return std::make_pair(adjacent_features[0],
|
||||
adjacent_features[n-1]);
|
||||
}
|
||||
|
||||
//! beginning of adjacencies
|
||||
Const_adjacency_iterator begin() const {
|
||||
return this->ptr()->_m_data.begin();
|
||||
}
|
||||
|
||||
//! end of adjacencies
|
||||
Const_adjacency_iterator end() const {
|
||||
return this->ptr()->_m_data.end();
|
||||
}
|
||||
|
||||
//! The number of adjacency pairs
|
||||
unsigned int size() const {
|
||||
return this->ptr()->_m_data.size();
|
||||
}
|
||||
|
||||
//! print (for testing only)
|
||||
void print() const {
|
||||
for(int i = 0;
|
||||
i < static_cast<int>(this->ptr()->_m_data.size());
|
||||
i++) {
|
||||
std::cout << "(" << this->ptr()->_m_data[i].first << ", "
|
||||
<< this->ptr()->_m_data[i].second << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
//! swap two instances
|
||||
Self swap() const {
|
||||
Self copy;
|
||||
for(Const_adjacency_iterator it = begin(); it!=end(); it++) {
|
||||
copy.ptr()->_m_data.push_back
|
||||
(std::make_pair(it->second,it->first));
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
//! output operator
|
||||
void pretty_print(std::ostream& os) const {
|
||||
for (int i = 0;
|
||||
i < static_cast<int>(this->ptr()->_m_data.size());
|
||||
i++) {
|
||||
os << "<" << this->ptr()->_m_data[i].first
|
||||
<< "," << this->ptr()->_m_data[i].second << ">";
|
||||
if (i < static_cast<int>(this->ptr()->_m_data.size()) - 1) {
|
||||
os << ",";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}; // end of Adjacencies data structure
|
||||
|
||||
/*!\relates Adjacencies_3
|
||||
* \brief
|
||||
* outputs Adjacencies_3 object to stream \c os
|
||||
*/
|
||||
inline
|
||||
std::ostream& operator<<(
|
||||
std::ostream& os,
|
||||
const Adjacencies_3& adj) {
|
||||
adj.pretty_print(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace SoX
|
||||
|
||||
#endif // SoX_GAPS_ADJACENCIES_3
|
||||
|
|
@ -0,0 +1,471 @@
|
|||
// ============================================================================
|
||||
//
|
||||
// Copyright (c) 2001-2008 Max-Planck-Institut Saarbruecken (Germany).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of EXACUS (http://www.mpi-inf.mpg.de/projects/EXACUS/);
|
||||
// you may redistribute it under the terms of the Q Public License version 1.0.
|
||||
// See the file LICENSE.QPL distributed with EXACUS.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Library : SoX
|
||||
// File : include/SoX/GAPS/Arr_p_dcel_info_overlay_traits.h
|
||||
// SoX_release : $Name: $
|
||||
// Revision : $Revision$
|
||||
// Revision_date : $Date$
|
||||
//
|
||||
// Author(s) : Eric Berberich <eric@mpi-inf.mpg.de>
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
/*! \file SoX/GAPS/Arr_p_dcel_info_overlay_traits.h
|
||||
* \brief definition of Arr_p_dcel_info_overlay_traits class template
|
||||
*/
|
||||
|
||||
#ifndef SoX_GAPS_ARR_P_DCEL_INFO_OVERLAY_TRAITS_H
|
||||
#define SoX_GAPS_ARR_P_DCEL_INFO_OVERLAY_TRAITS_H 1
|
||||
|
||||
#include <CGAL/config.h>
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include <CGAL/Arr_default_overlay_traits.h>
|
||||
|
||||
#include <CGAL/Arrangement_2l/z_stack_predeclarations.h>
|
||||
#include <CGAL/Arrangement_2l/Restricted_cad_3_accessor.h>
|
||||
|
||||
namespace SoX {
|
||||
|
||||
/*!\brief
|
||||
* Model of CGAL::ArrangementOverlayTraits_2 for Arrangements
|
||||
* attached with SoX::P_dcel_info<> data.
|
||||
*/
|
||||
template < class RestrictedCad_3 >
|
||||
class Arr_p_dcel_info_overlay_traits : public
|
||||
CGAL::Arr_default_overlay_traits< typename RestrictedCad_3::Rep > {
|
||||
|
||||
public:
|
||||
//! this instance's first template parameter
|
||||
typedef RestrictedCad_3 Restricted_cad_3;
|
||||
|
||||
//! type of arrangement
|
||||
typedef typename Restricted_cad_3::Rep Arrangement_2;
|
||||
|
||||
//! type of surface
|
||||
typedef typename Restricted_cad_3::Surface_3 Surface_3;
|
||||
|
||||
//! base type
|
||||
//typedef CGAL::Arr_default_overlay_traits< Arrangement_2 > Base;
|
||||
|
||||
typedef Restricted_cad_3 RS_3;
|
||||
|
||||
//! type of accesor
|
||||
typedef Restricted_cad_3_accessor< Restricted_cad_3 > Accessor;
|
||||
|
||||
//! the class itself
|
||||
typedef Arr_p_dcel_info_overlay_traits< Arrangement_2 > Self;
|
||||
|
||||
typedef typename RS_3::Vertex_const_handle Vertex_const_handle_A;
|
||||
typedef typename RS_3::Vertex_const_handle Vertex_const_handle_B;
|
||||
typedef typename RS_3::Vertex_const_handle Vertex_const_handle_R;
|
||||
|
||||
typedef typename RS_3::Halfedge_const_handle Halfedge_const_handle_A;
|
||||
typedef typename RS_3::Halfedge_const_handle Halfedge_const_handle_B;
|
||||
typedef typename RS_3::Halfedge_const_handle Halfedge_const_handle_R;
|
||||
|
||||
typedef typename RS_3::Face_const_handle Face_const_handle_A;
|
||||
typedef typename RS_3::Face_const_handle Face_const_handle_B;
|
||||
typedef typename RS_3::Face_const_handle Face_const_handle_R;
|
||||
|
||||
|
||||
/*!\brief
|
||||
* Constructs a new overlay traits
|
||||
*/
|
||||
Arr_p_dcel_info_overlay_traits(const Surface_3& surface,
|
||||
const Restricted_cad_3& cad,
|
||||
SoX::Nk::Value_type type) :
|
||||
_m_surface_mode(true),
|
||||
_m_surface(surface),
|
||||
_m_cad(cad),
|
||||
_m_acc(cad),
|
||||
_m_type(type),
|
||||
_m_factors_of_same_curve(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*!\brief
|
||||
* Constructs a new overlay traits where \c factors_of_same_curve defines
|
||||
* whether the two parts originate from two factors of the same curve
|
||||
*/
|
||||
Arr_p_dcel_info_overlay_traits(const Restricted_cad_3& cad,
|
||||
bool factors_of_same_curve) :
|
||||
_m_surface_mode(false),
|
||||
_m_cad(cad),
|
||||
_m_acc(cad),
|
||||
_m_factors_of_same_curve(factors_of_same_curve) {
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// for vertex/face
|
||||
inline void merge(Nk nk1, Nk nk2, const Nk& nk,
|
||||
const Dcel_feature& feature) const {
|
||||
|
||||
if (this->_m_type == SoX::Nk::MULT) {
|
||||
// mults!
|
||||
if (feature == SoX::VERTEX) {
|
||||
nk.set_mult(0);
|
||||
} else if (feature == SoX::EDGE) {
|
||||
nk.set_mult(
|
||||
(nk1.mult() > 0 ? nk1.mult() : 0) +
|
||||
(nk2.mult() > 0 ? nk2.mult() : 0)
|
||||
);
|
||||
CGAL_assertion(nk.mult() > 0);
|
||||
}
|
||||
} else {
|
||||
// copy already set values!
|
||||
if (nk1.mult() >= 0) {
|
||||
if (feature == SoX::VERTEX) {
|
||||
nk.set_mult(0);
|
||||
} else {
|
||||
CGAL_assertion(feature == SoX::EDGE);
|
||||
nk.set_mult(nk1.mult());
|
||||
}
|
||||
}
|
||||
if (nk1.n() >= -1) {
|
||||
nk.set_n(nk1.n());
|
||||
}
|
||||
if (nk1.k() >= -1) {
|
||||
nk.set_k(nk1.k());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
|
||||
/*!
|
||||
* Create a vertex v that corresponds to the coinciding vertices v1 and v2.
|
||||
*/
|
||||
virtual void create_vertex (Vertex_const_handle_A v1,
|
||||
Vertex_const_handle_B v2,
|
||||
Vertex_const_handle_R v)
|
||||
{
|
||||
CGAL_precondition(v1->point() == v->point());
|
||||
CGAL_precondition(v2->point() == v->point());
|
||||
CGAL_assertion(v1->data());
|
||||
CGAL_assertion(v2->data());
|
||||
|
||||
if (_m_surface_mode) {
|
||||
CGAL_precondition(!v->data());
|
||||
_m_cad._init_feature(_m_surface, v, SoX::VERTEX);
|
||||
|
||||
v1->data()->_nk(_m_surface);
|
||||
v2->data()->_nk(_m_surface);
|
||||
v->data()->_nk(_m_surface);
|
||||
|
||||
merge(v1->data()->_nk(_m_surface),
|
||||
v2->data()->_nk(_m_surface),
|
||||
v->data()->_nk(_m_surface), SoX::VERTEX);
|
||||
CGAL_postcondition(v->data());
|
||||
|
||||
v->data()->_nk(_m_surface).set_feature1(SoX::VERTEX);
|
||||
v->data()->_nk(_m_surface).set_feature2(SoX::VERTEX);
|
||||
} else {
|
||||
_m_acc.non_const_handle(v)->data() =
|
||||
v1->data()->_overlay_with(*v2->data(),
|
||||
_m_factors_of_same_curve);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Create a vertex v that mathces v1, which lies of the edge e2.
|
||||
*/
|
||||
virtual void create_vertex (Vertex_const_handle_A v1,
|
||||
Halfedge_const_handle_B e2,
|
||||
Vertex_const_handle_R v)
|
||||
{
|
||||
CGAL_precondition(v1->point() == v->point());
|
||||
CGAL_assertion(v1->data());
|
||||
CGAL_assertion(e2->data());
|
||||
|
||||
if (_m_surface_mode) {
|
||||
CGAL_precondition(!v->data());
|
||||
_m_cad._init_feature(_m_surface, v, SoX::VERTEX);
|
||||
merge(v1->data()->_nk(_m_surface),
|
||||
e2->data()->_nk(_m_surface),
|
||||
v->data()->_nk(_m_surface), SoX::VERTEX);
|
||||
CGAL_postcondition(v->data());
|
||||
|
||||
v->data()->_nk(_m_surface).set_feature1(SoX::VERTEX);
|
||||
v->data()->_nk(_m_surface).set_feature2(SoX::EDGE);
|
||||
} else {
|
||||
_m_acc.non_const_handle(v)->data() =
|
||||
v1->data()->_overlay_with(*e2->data(),
|
||||
_m_factors_of_same_curve);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Create a vertex v that mathces v1, contained in the face f2.
|
||||
*/
|
||||
virtual void create_vertex (Vertex_const_handle_A v1,
|
||||
Face_const_handle_B f2,
|
||||
Vertex_const_handle_R v)
|
||||
{
|
||||
CGAL_precondition(v1->point() == v->point());
|
||||
CGAL_assertion(v1->data());
|
||||
CGAL_assertion(f2->data());
|
||||
|
||||
if (_m_surface_mode) {
|
||||
CGAL_precondition(!v->data());
|
||||
_m_cad._init_feature(_m_surface, v, SoX::VERTEX);
|
||||
merge(v1->data()->_nk(_m_surface),
|
||||
f2->data()->_nk(_m_surface),
|
||||
v->data()->_nk(_m_surface), SoX::VERTEX);
|
||||
CGAL_postcondition(v->data());
|
||||
|
||||
v->data()->_nk(_m_surface).set_feature1(SoX::VERTEX);
|
||||
v->data()->_nk(_m_surface).set_feature2(SoX::FACE);
|
||||
|
||||
} else {
|
||||
_m_acc.non_const_handle(v)->data() =
|
||||
v1->data()->_overlay_with(*f2->data(),
|
||||
_m_factors_of_same_curve);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Create a vertex v that mathces v2, which lies of the edge e1.
|
||||
*/
|
||||
virtual void create_vertex (Halfedge_const_handle_A e1,
|
||||
Vertex_const_handle_B v2,
|
||||
Vertex_const_handle_R v)
|
||||
{
|
||||
CGAL_precondition(v2->point() == v->point());
|
||||
CGAL_assertion(e1->data());
|
||||
CGAL_assertion(v2->data());
|
||||
|
||||
if (_m_surface_mode) {
|
||||
CGAL_precondition(!v->data());
|
||||
_m_cad._init_feature(_m_surface, v, SoX::VERTEX);
|
||||
merge(e1->data()->_nk(_m_surface),
|
||||
v2->data()->_nk(_m_surface),
|
||||
v->data()->_nk(_m_surface), SoX::VERTEX);
|
||||
CGAL_postcondition(v->data());
|
||||
|
||||
v->data()->_nk(_m_surface).set_feature1(SoX::EDGE);
|
||||
v->data()->_nk(_m_surface).set_feature2(SoX::VERTEX);
|
||||
} else {
|
||||
_m_acc.non_const_handle(v)->data() =
|
||||
v2->data()->_overlay_with(*e1->data(),
|
||||
_m_factors_of_same_curve);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Create a vertex v that mathces v2, contained in the face f1.
|
||||
*/
|
||||
virtual void create_vertex (Face_const_handle_A f1,
|
||||
Vertex_const_handle_B v2,
|
||||
Vertex_const_handle_R v)
|
||||
{
|
||||
CGAL_precondition(v2->point() == v->point());
|
||||
CGAL_assertion(f1->data());
|
||||
CGAL_assertion(v2->data());
|
||||
|
||||
if (_m_surface_mode) {
|
||||
CGAL_precondition(!v->data());
|
||||
_m_cad._init_feature(_m_surface, v, SoX::VERTEX);
|
||||
merge(f1->data()->_nk(_m_surface),
|
||||
v2->data()->_nk(_m_surface),
|
||||
v->data()->_nk(_m_surface), SoX::VERTEX);
|
||||
CGAL_postcondition(v->data());
|
||||
|
||||
v->data()->_nk(_m_surface).set_feature1(SoX::FACE);
|
||||
v->data()->_nk(_m_surface).set_feature2(SoX::VERTEX);
|
||||
} else {
|
||||
_m_acc.non_const_handle(v)->data() =
|
||||
v2->data()->_overlay_with(*f1->data(),
|
||||
_m_factors_of_same_curve);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Create a vertex v that mathces the intersection of the edges e1 and e2.
|
||||
*/
|
||||
virtual void create_vertex (Halfedge_const_handle_A e1,
|
||||
Halfedge_const_handle_B e2,
|
||||
Vertex_const_handle_R v)
|
||||
{
|
||||
CGAL_assertion(e1->data());
|
||||
CGAL_assertion(e2->data());
|
||||
|
||||
if (_m_surface_mode) {
|
||||
CGAL_precondition(!v->data());
|
||||
_m_cad._init_feature(_m_surface, v, SoX::VERTEX);
|
||||
merge(e1->data()->_nk(_m_surface),
|
||||
e2->data()->_nk(_m_surface),
|
||||
v->data()->_nk(_m_surface), SoX::VERTEX);
|
||||
CGAL_postcondition(v->data());
|
||||
|
||||
v->data()->_nk(_m_surface).set_feature1(SoX::EDGE);
|
||||
v->data()->_nk(_m_surface).set_feature2(SoX::EDGE);
|
||||
} else {
|
||||
_m_acc.non_const_handle(v)->data() =
|
||||
e1->data()->_overlay_with(*e2->data(),
|
||||
_m_factors_of_same_curve);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Create an edge e that matches the overlap between e1 and e2.
|
||||
*/
|
||||
virtual void create_edge (Halfedge_const_handle_A e1,
|
||||
Halfedge_const_handle_B e2,
|
||||
Halfedge_const_handle_R e)
|
||||
{
|
||||
CGAL_assertion(e1->data());
|
||||
CGAL_assertion(e2->data());
|
||||
|
||||
if (_m_surface_mode) {
|
||||
CGAL_precondition(!e->data());
|
||||
_m_cad._init_feature(_m_surface, e, SoX::EDGE);
|
||||
merge(e1->data()->_nk(_m_surface),
|
||||
e2->data()->_nk(_m_surface),
|
||||
e->data()->_nk(_m_surface), SoX::EDGE);
|
||||
CGAL_postcondition(e->data());
|
||||
|
||||
e->data()->_nk(_m_surface).set_feature1(SoX::EDGE);
|
||||
e->data()->_nk(_m_surface).set_feature2(SoX::EDGE);
|
||||
} else {
|
||||
_m_acc.non_const_handle(e)->data() =
|
||||
e1->data()->_overlay_with(*e2->data(),
|
||||
_m_factors_of_same_curve);
|
||||
}
|
||||
CGAL_assertion(!e->twin()->data());
|
||||
_m_acc.non_const_handle(e->twin())->data() = *e->data();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Create an edge e that matches the edge e1, contained in the face f2.
|
||||
*/
|
||||
virtual void create_edge (Halfedge_const_handle_A e1,
|
||||
Face_const_handle_B f2,
|
||||
Halfedge_const_handle_R e)
|
||||
{
|
||||
CGAL_assertion(e1->data());
|
||||
CGAL_assertion(f2->data());
|
||||
|
||||
if (_m_surface_mode) {
|
||||
CGAL_precondition(!e->data());
|
||||
_m_cad._init_feature(_m_surface, e, SoX::EDGE);
|
||||
merge(e1->data()->_nk(_m_surface),
|
||||
f2->data()->_nk(_m_surface),
|
||||
e->data()->_nk(_m_surface), SoX::EDGE);
|
||||
CGAL_postcondition(e->data());
|
||||
|
||||
e->data()->_nk(_m_surface).set_feature1(SoX::EDGE);
|
||||
e->data()->_nk(_m_surface).set_feature2(SoX::FACE);
|
||||
} else {
|
||||
_m_acc.non_const_handle(e)->data() =
|
||||
e1->data()->_overlay_with(*f2->data(),
|
||||
_m_factors_of_same_curve);
|
||||
}
|
||||
CGAL_assertion(!e->twin()->data());
|
||||
_m_acc.non_const_handle(e->twin())->data() = *e->data();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Create an edge e that matches the edge e2, contained in the face f1.
|
||||
*/
|
||||
virtual void create_edge (Face_const_handle_A f1,
|
||||
Halfedge_const_handle_B e2,
|
||||
Halfedge_const_handle_R e)
|
||||
{
|
||||
CGAL_assertion(f1->data());
|
||||
CGAL_assertion(e2->data());
|
||||
|
||||
if (_m_surface_mode) {
|
||||
CGAL_precondition(!e->data());
|
||||
_m_cad._init_feature(_m_surface, e, SoX::EDGE);
|
||||
merge(f1->data()->_nk(_m_surface),
|
||||
e2->data()->_nk(_m_surface),
|
||||
e->data()->_nk(_m_surface), SoX::EDGE);
|
||||
CGAL_postcondition(e->data());
|
||||
|
||||
e->data()->_nk(_m_surface).set_feature1(SoX::FACE);
|
||||
e->data()->_nk(_m_surface).set_feature2(SoX::EDGE);
|
||||
} else {
|
||||
_m_acc.non_const_handle(e)->data() =
|
||||
e2->data()->_overlay_with(*f1->data(),
|
||||
_m_factors_of_same_curve);
|
||||
}
|
||||
CGAL_assertion(!e->twin()->data());
|
||||
_m_acc.non_const_handle(e->twin())->data() = *e->data();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Create a face f that matches the overlapping region between f1 and f2.
|
||||
*/
|
||||
virtual void create_face (Face_const_handle_A f1,
|
||||
Face_const_handle_B f2,
|
||||
Face_const_handle_R f)
|
||||
{
|
||||
CGAL_assertion(f1->data());
|
||||
CGAL_assertion(f2->data());
|
||||
|
||||
if (_m_surface_mode) {
|
||||
CGAL_precondition(!f->data());
|
||||
_m_cad._init_feature(_m_surface, f, SoX::FACE);
|
||||
CGAL_assertion(f1->data()->_nk(_m_surface).mult() == -1);
|
||||
CGAL_assertion(f2->data()->_nk(_m_surface).mult() == -1);
|
||||
merge(f1->data()->_nk(_m_surface),
|
||||
f2->data()->_nk(_m_surface),
|
||||
f->data()->_nk(_m_surface), SoX::FACE);
|
||||
CGAL_postcondition(f->data());
|
||||
|
||||
f->data()->_nk(_m_surface).set_feature1(SoX::FACE);
|
||||
f->data()->_nk(_m_surface).set_feature2(SoX::FACE);
|
||||
} else {
|
||||
_m_acc.non_const_handle(f)->data() =
|
||||
f1->data()->_overlay_with(*f2->data(),
|
||||
_m_factors_of_same_curve);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// members
|
||||
//! surface mode?
|
||||
bool _m_surface_mode;
|
||||
|
||||
//! surface
|
||||
Surface_3 _m_surface;
|
||||
|
||||
//! cad
|
||||
Restricted_cad_3 _m_cad;
|
||||
|
||||
//! accessor
|
||||
Accessor _m_acc;
|
||||
|
||||
//! overlay type
|
||||
SoX::Nk::Value_type _m_type;
|
||||
|
||||
//! factors of same curve
|
||||
bool _m_factors_of_same_curve;
|
||||
};
|
||||
|
||||
|
||||
} // namespace SoX
|
||||
|
||||
#endif // SoX_GAPS_ARR_P_DCEL_INFO_OVERLAY_TRAITS_H
|
||||
// EO
|
||||
|
|
@ -0,0 +1,725 @@
|
|||
// ============================================================================
|
||||
//
|
||||
// Copyright (c) 2001-2008 Max-Planck-Institut Saarbruecken (Germany).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of EXACUS (http://www.mpi-inf.mpg.de/projects/EXACUS/);
|
||||
// you may redistribute it under the terms of the Q Public License version 1.0.
|
||||
// See the file LICENSE.QPL distributed with EXACUS.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Library : SoX
|
||||
// File : include/SoX/GAPS/Curve_3.h
|
||||
// SoX_release : $Name: $
|
||||
// Revision : $Revision$
|
||||
// Revision_date : $Date$
|
||||
//
|
||||
// Author(s) : Eric Berberich <eric@mpi-inf.mpg.de>
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
#ifndef SoX_GAPS_CURVE_3_H
|
||||
#define SoX_GAPS_CURVE_3_H 1
|
||||
|
||||
/*!\file SoX/GAPS/Curve_3.h
|
||||
* \brief
|
||||
* definition of \c Curve_3<>
|
||||
*/
|
||||
|
||||
#include <CGAL/config.h>
|
||||
|
||||
#include <CGAL/Arrangement_2l/macros.h>
|
||||
|
||||
#include <CGAL/Arrangement_2l/z_stack_predeclarations.h>
|
||||
#include <CGAL/Arrangement_2l/Restricted_cad_3.h>
|
||||
#include <CGAL/Arrangement_2l/Restricted_cad_3_functors.h>
|
||||
|
||||
#include <CGAL/Arrangement_2l/Surface_pair_3.h>
|
||||
|
||||
namespace SoX {
|
||||
|
||||
namespace Intern {
|
||||
|
||||
template < class SurfaceZAtXyIsolatorTraits >
|
||||
class Curve_3_rep :
|
||||
public SoX::Intern::Surface_pair_3_rep< SurfaceZAtXyIsolatorTraits > {
|
||||
|
||||
public:
|
||||
//! this instance's template parameter
|
||||
typedef SurfaceZAtXyIsolatorTraits Surface_z_at_xy_isolator_traits;
|
||||
|
||||
SoX_SURFACE_Z_AT_XY_ISOLATOR_TRAITS_SNAP_TYPEDEFS(
|
||||
Surface_z_at_xy_isolator_traits
|
||||
);
|
||||
|
||||
//! this instance itself
|
||||
typedef Curve_3_rep< Surface_z_at_xy_isolator_traits > Self;
|
||||
|
||||
//! the base classe
|
||||
typedef SoX::Intern::Surface_pair_3_rep< Surface_z_at_xy_isolator_traits >
|
||||
Base;
|
||||
|
||||
//! type of restricted cad
|
||||
typedef typename Base::Restricted_cad_3 Restricted_cad_3;
|
||||
|
||||
//! type of creator
|
||||
typedef typename Base::Creator Creator;
|
||||
|
||||
//! type of creator
|
||||
typedef typename Base::Overlayer Overlayer;
|
||||
|
||||
public:
|
||||
//!\name Constructors
|
||||
//!@{
|
||||
|
||||
Curve_3_rep(const Surface_3& surface1, const Surface_3& surface2) :
|
||||
Base(surface1, surface2) {
|
||||
}
|
||||
|
||||
//!@}
|
||||
|
||||
// add special members??
|
||||
|
||||
};
|
||||
|
||||
} // namespace Intern
|
||||
|
||||
template <
|
||||
class SurfaceZAtXyIsolatorTraits,
|
||||
class Rep_ = SoX::Intern::Curve_3_rep< SurfaceZAtXyIsolatorTraits >
|
||||
>
|
||||
class Curve_3 :
|
||||
public Surface_pair_3<SurfaceZAtXyIsolatorTraits, Rep_ > {
|
||||
|
||||
public:
|
||||
//! this instance's first template parameter
|
||||
typedef SurfaceZAtXyIsolatorTraits Surface_z_at_xy_isolator_traits;
|
||||
|
||||
//! this instance's second template parameter
|
||||
typedef Rep_ Rep;
|
||||
|
||||
SoX_SURFACE_Z_AT_XY_ISOLATOR_TRAITS_SNAP_TYPEDEFS(
|
||||
Surface_z_at_xy_isolator_traits
|
||||
);
|
||||
|
||||
//! type of Base
|
||||
typedef SoX::Surface_pair_3< Surface_z_at_xy_isolator_traits, Rep > Base;
|
||||
|
||||
//! type of restricted cad
|
||||
typedef typename Base::Restricted_cad_3 Restricted_cad_3;
|
||||
|
||||
//!\name Constructors
|
||||
//!@{
|
||||
|
||||
Curve_3(const Surface_3& surface1, const Surface_3& surface2) :
|
||||
Base(surface1, surface2) {
|
||||
}
|
||||
|
||||
//!@}
|
||||
|
||||
private: // make public members inaccessible
|
||||
//!\name Cads
|
||||
//!@{
|
||||
|
||||
//! rscad of first silhouette
|
||||
Restricted_cad_3 silhouette1() const {
|
||||
return Base::silhouette1();
|
||||
}
|
||||
|
||||
//! rscad of second silhouette
|
||||
Restricted_cad_3 silhouette2() const {
|
||||
return Base::silhouette1();
|
||||
}
|
||||
|
||||
//! rscad of cut
|
||||
Restricted_cad_3 cut() const {
|
||||
return Base::cut();
|
||||
}
|
||||
|
||||
//! rscad of first silhouette with cut
|
||||
Restricted_cad_3 silhouettes_cut() const {
|
||||
return Base::silhouettes_cut();
|
||||
}
|
||||
|
||||
//!@}
|
||||
|
||||
private: // make public members inaccessible
|
||||
//!\name Curves
|
||||
//!@{
|
||||
|
||||
/*!\brief
|
||||
* returns silhouettes curves and points for a given \c surface in pair
|
||||
*/
|
||||
template < class CurveOutputIterator, class PointOutputIterator >
|
||||
void silhouette_objects(
|
||||
const Surface_3& surface,
|
||||
CurveOutputIterator coi, PointOutputIterator poi) const {
|
||||
return Base::silhouette_objects(surface, coi, poi);
|
||||
|
||||
}
|
||||
|
||||
/*!\brief
|
||||
* returns projected intersection curves and points of the pair
|
||||
*/
|
||||
template < class CurveOutputIterator, class PointOutputIterator >
|
||||
void cut_objects(
|
||||
CurveOutputIterator coi, PointOutputIterator poi) const {
|
||||
return Base::cut_objects(coi, poi);
|
||||
}
|
||||
|
||||
//!@}
|
||||
|
||||
public:
|
||||
|
||||
//!\name Space Curve Objects
|
||||
//!@{
|
||||
/*!\brief
|
||||
* returns spatial curves/points as combination of curve/sheet or
|
||||
* point/sheet, where sheet is an int wrt to smaller-degree surface
|
||||
*/
|
||||
template <
|
||||
class SurfaceArc_3,
|
||||
class CurveOutputIterator,
|
||||
class PointOutputIterator
|
||||
>
|
||||
void objects(
|
||||
SurfaceArc_3 dummy,
|
||||
Surface_3& support,
|
||||
CurveOutputIterator coi, PointOutputIterator poi
|
||||
) const {
|
||||
|
||||
typedef SurfaceArc_3 Surface_arc_3;
|
||||
typedef typename Surface_arc_3::Surface_point_2l Surface_point_3;
|
||||
|
||||
typedef typename Restricted_cad_3::Vertex_const_iterator
|
||||
Vertex_const_iterator;
|
||||
typedef typename Restricted_cad_3::Edge_const_iterator
|
||||
Edge_const_iterator;
|
||||
typedef typename Restricted_cad_3::Z_stack Z_stack;
|
||||
|
||||
// Remark (1):
|
||||
// The simple case is an edge with mult == 1, ask member for it
|
||||
// -> Refine until only one z-cell of f remains (f is simpler than g!)
|
||||
// Else: Multiple intersection can occur.
|
||||
// Either use local gcd (point_on_curve for SR_i, i > 0!!!, as point
|
||||
// already lies on SR_0,
|
||||
// or use silhouette of g (costly?!?!) to determine isolator :-(
|
||||
|
||||
Surface_3 other;
|
||||
|
||||
// TODO select smaller surface out of the two by traits?!?!
|
||||
if (this->surface2().f().degree() < this->surface1().f().degree()) {
|
||||
support = this->surface2();
|
||||
other = this->surface1();
|
||||
} else {
|
||||
support = this->surface1();
|
||||
other = this->surface2();
|
||||
}
|
||||
|
||||
// TODO support is not allowed to be vertical!
|
||||
CGAL_assertion(support.f().degree() > 0);
|
||||
if (support.f().degree() != CGAL::total_degree(support.f())) {
|
||||
// TODO what if support is not z-regular
|
||||
// and what if other is not z-regular??!
|
||||
std::cerr << "Warning: Support is not z-regular, "
|
||||
<< "we might encounter problems with vertical "
|
||||
<< "objects, or asympotes!"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
Restricted_cad_3 cad =
|
||||
(support.id() == this->surface1().id() ?
|
||||
this->_silhouette1_cut() :
|
||||
this->_silhouette2_cut());
|
||||
// we won't access z-stacks of cad directly, only for support!
|
||||
|
||||
SoX::Intern::Refineable_interval_helper< Z_at_xy_isolator >
|
||||
iv_helper;
|
||||
|
||||
// iterate over all features of cut
|
||||
for (Edge_const_iterator eit = cad.edges_begin();
|
||||
eit != cad.edges_end(); eit++) {
|
||||
|
||||
if (cad.has_cut(eit)) {
|
||||
|
||||
boost::optional< int > mult =
|
||||
eit->data()->multiplicity_of_cut(support, other);
|
||||
CGAL_assertion(mult);
|
||||
|
||||
Point_2 point = cad.sample_point(eit);
|
||||
|
||||
typename
|
||||
Surface_z_at_xy_isolator_traits::Construct_isolator
|
||||
construct_isolator; // TODO single instance
|
||||
|
||||
Z_at_xy_isolator support_isolator =
|
||||
construct_isolator(support, point,
|
||||
cad.nk(eit, support),
|
||||
(cad.has_silhouette(eit) ?
|
||||
SoX::EDGE : SoX::FACE)
|
||||
);
|
||||
|
||||
int n = support_isolator.number_of_real_roots();
|
||||
if (n == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::list< int > sheets;
|
||||
|
||||
if (*mult == 1) {
|
||||
|
||||
Z_at_xy_isolator other_isolator =
|
||||
construct_isolator(
|
||||
other, point,
|
||||
cad.nk(cad.faces_begin(), support),
|
||||
SoX::FACE
|
||||
);
|
||||
std::cout << "RRs"
|
||||
<< support_isolator.number_of_real_roots()
|
||||
<< std::endl;
|
||||
|
||||
|
||||
std::cout << "RRo"
|
||||
<< other_isolator.number_of_real_roots()
|
||||
<< std::endl;
|
||||
|
||||
CGAL_assertion(other_isolator.number_of_real_roots() > 0);
|
||||
|
||||
CGAL_assertion(point == other_isolator.traits().point());
|
||||
|
||||
std::list< std::pair< int, int > > overlaps;
|
||||
|
||||
iv_helper.refined_overlaps(
|
||||
support_isolator, other_isolator,
|
||||
std::back_inserter(overlaps)
|
||||
);
|
||||
|
||||
CGAL_assertion(!overlaps.empty());
|
||||
|
||||
std::pair< int, int > overlap =
|
||||
iv_helper.unique_overlap(
|
||||
support_isolator, other_isolator,
|
||||
overlaps.begin(), overlaps.end()
|
||||
);
|
||||
|
||||
sheets.push_back(overlap.first);
|
||||
|
||||
} else {
|
||||
|
||||
typename
|
||||
Surface_z_at_xy_isolator_traits::Equal_z
|
||||
equal_z; // TODO single instance
|
||||
|
||||
typename
|
||||
Surface_z_at_xy_isolator_traits::Point_on_curve_2
|
||||
point_on_curve; // TODO single instance
|
||||
|
||||
// can start with 1 as it lies on k = 0
|
||||
int k = 1;
|
||||
|
||||
// TODO what happens if surfaces are not z-regular??!
|
||||
Polynomial_3 local_gcd =
|
||||
equal_z.local_gcd(support, other,
|
||||
support_isolator.traits(), k);
|
||||
|
||||
// TODO make use of k
|
||||
|
||||
// TODO be careful if a surface has a vertical line!
|
||||
|
||||
Surface_3 gcd_surface =
|
||||
Surface_3::surface_cache()(local_gcd);
|
||||
|
||||
Polynomial_2 sil_local_gcd = gcd_surface.resultant_f_fz();
|
||||
|
||||
bool on_gcd_sil = point_on_curve(point, sil_local_gcd);
|
||||
|
||||
Z_at_xy_isolator gcd_isolator =
|
||||
construct_isolator(
|
||||
local_gcd, point,
|
||||
cad.nk(eit, support),
|
||||
(on_gcd_sil ? SoX::EDGE : SoX::FACE)
|
||||
);
|
||||
|
||||
// compute overlaps
|
||||
std::vector< std::pair< int, int > > overlaps;
|
||||
|
||||
iv_helper.refined_overlaps(
|
||||
support_isolator, gcd_isolator,
|
||||
std::back_inserter(overlaps)
|
||||
);
|
||||
|
||||
// refine until a gcd-interval is fully include in
|
||||
// support interval or has moved away
|
||||
for (int k = 0; k < static_cast< int >(overlaps.size());
|
||||
k++) {
|
||||
|
||||
while (true) {
|
||||
|
||||
if (iv_helper.overlap_or_order(
|
||||
gcd_isolator, overlaps[k].second,
|
||||
support_isolator, overlaps[k].first
|
||||
) != CGAL::EQUAL) {
|
||||
break;
|
||||
}
|
||||
// else
|
||||
|
||||
if (iv_helper.is_included(
|
||||
gcd_isolator, overlaps[k].second,
|
||||
support_isolator, overlaps[k].first,
|
||||
true
|
||||
)
|
||||
) {
|
||||
sheets.push_back(overlaps[k].first);
|
||||
break;
|
||||
}
|
||||
|
||||
// else
|
||||
gcd_isolator.refine_interval(overlaps[k].second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (std::list< int >::const_iterator sit = sheets.begin();
|
||||
sit != sheets.end(); sit++) {
|
||||
|
||||
//std::cout << "cv: " << eit->curve() << std::endl;
|
||||
|
||||
bool min_finite =
|
||||
eit->curve().is_finite(CGAL::ARR_MIN_END);
|
||||
bool max_finite =
|
||||
eit->curve().is_finite(CGAL::ARR_MAX_END);
|
||||
|
||||
bool src_at_min =
|
||||
(eit->direction() == CGAL::ARR_LEFT_TO_RIGHT);
|
||||
|
||||
Surface_point_3 min, max;
|
||||
|
||||
int sheet = *sit;
|
||||
int sheet_at_min = -2;
|
||||
int sheet_at_max = -2;
|
||||
bool z_inf_at_min = false;
|
||||
bool z_inf_at_max = false;
|
||||
|
||||
if (min_finite) {
|
||||
Point_2 pmin =
|
||||
eit->curve().curve_end(CGAL::ARR_MIN_END);
|
||||
|
||||
std::pair< Z_stack, std::pair< int, int > > adjmin =
|
||||
cad.surface_adjacency(eit, support, sheet,
|
||||
(src_at_min ?
|
||||
eit->source() :
|
||||
eit->target()));
|
||||
|
||||
sheet_at_min = adjmin.second.first;
|
||||
z_inf_at_min =
|
||||
(sheet_at_min == -1 || sheet_at_min == n);
|
||||
if (!z_inf_at_min) {
|
||||
min = Surface_point_3(pmin, support, sheet_at_min);
|
||||
}
|
||||
}
|
||||
|
||||
if (max_finite) {
|
||||
Point_2 pmax =
|
||||
eit->curve().curve_end(CGAL::ARR_MAX_END);
|
||||
|
||||
std::pair< Z_stack, std::pair< int, int > > adjmax =
|
||||
cad.surface_adjacency(eit, support, sheet,
|
||||
(src_at_min ?
|
||||
eit->target() :
|
||||
eit->source()));
|
||||
|
||||
sheet_at_max = adjmax.second.first;
|
||||
z_inf_at_max =
|
||||
(sheet_at_max == -1 || sheet_at_max == n);
|
||||
if (!z_inf_at_max) {
|
||||
max = Surface_point_3(pmax, support, sheet_at_max);
|
||||
}
|
||||
}
|
||||
|
||||
if (min_finite && max_finite) {
|
||||
// arc is bounded
|
||||
|
||||
if (z_inf_at_min && z_inf_at_max) {
|
||||
// no z-asymptote
|
||||
*coi++ = Surface_arc_3(
|
||||
eit->curve(), min, max, support,
|
||||
sheet, sheet_at_min, sheet_at_max
|
||||
);
|
||||
} else if (!z_inf_at_min && !z_inf_at_max) {
|
||||
// z-asymptotes at both sides
|
||||
*coi++ = Surface_arc_3(
|
||||
eit->curve(),
|
||||
(sheet_at_min == -1 ?
|
||||
CGAL::ARR_MIN_END : CGAL::ARR_MAX_END),
|
||||
(sheet_at_max == -1 ?
|
||||
CGAL::ARR_MIN_END : CGAL::ARR_MAX_END),
|
||||
support,
|
||||
sheet
|
||||
);
|
||||
} else {
|
||||
// z-asymptote at one-side
|
||||
int sheet_at_point = sheet_at_min;
|
||||
if (!z_inf_at_min) {
|
||||
sheet_at_point = sheet_at_max;
|
||||
}
|
||||
*coi++ = Surface_arc_3(
|
||||
eit->curve(),
|
||||
(z_inf_at_min ? max : min),
|
||||
(sheet_at_point == -1 ?
|
||||
CGAL::ARR_MIN_END : CGAL::ARR_MAX_END),
|
||||
support,
|
||||
sheet,
|
||||
(z_inf_at_min ? sheet_at_max : sheet_at_min)
|
||||
);
|
||||
}
|
||||
} else if (!min_finite && !max_finite) {
|
||||
// planar arc is a branch
|
||||
*coi++ = Surface_arc_3(
|
||||
eit->curve(),
|
||||
support,
|
||||
sheet
|
||||
);
|
||||
} else {
|
||||
// arc is ray
|
||||
if (!z_inf_at_min && !z_inf_at_max) {
|
||||
// usual one
|
||||
*coi++ = Surface_arc_3(
|
||||
eit->curve(),
|
||||
(min_finite ? min : max),
|
||||
support,
|
||||
sheet,
|
||||
(min_finite ? sheet_at_min : sheet_at_max)
|
||||
);
|
||||
|
||||
} else {
|
||||
int sheet_at_point = sheet_at_min;
|
||||
if (!z_inf_at_min) {
|
||||
sheet_at_point = sheet_at_max;
|
||||
}
|
||||
// z-asymptote at finite-side
|
||||
*coi++ = Surface_arc_3 (
|
||||
eit->curve(),
|
||||
(sheet_at_point == -1 ?
|
||||
CGAL::ARR_MIN_END : CGAL::ARR_MAX_END),
|
||||
support,
|
||||
sheet
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// search only for isolated points in support and
|
||||
// check only them with the help of local gcd!
|
||||
|
||||
// iterate over all features of cut
|
||||
for (Vertex_const_iterator vit = cad.vertices_begin();
|
||||
vit != cad.vertices_end(); vit++) {
|
||||
if (vit->is_at_infinity()) {
|
||||
continue;
|
||||
}
|
||||
if (cad.has_cut(vit)) {
|
||||
|
||||
// check whether vertex is isolated or whether support
|
||||
// has an isolated event here
|
||||
|
||||
// actually we test whether each sheet k at vit is connected
|
||||
// to something
|
||||
|
||||
Point_2 point = cad.sample_point(vit);
|
||||
|
||||
typename
|
||||
Surface_z_at_xy_isolator_traits::Construct_isolator
|
||||
construct_isolator; // TODO single instance
|
||||
|
||||
Z_at_xy_isolator support_isolator =
|
||||
// edge is ok, as we don't want to activate artifical
|
||||
// x-interval, but other isolators (m-k..)
|
||||
construct_isolator(
|
||||
support, point,
|
||||
cad.nk(vit, support),
|
||||
(cad.has_silhouette(vit) ?
|
||||
SoX::EDGE : SoX::FACE)
|
||||
);
|
||||
|
||||
int n = support_isolator.number_of_real_roots();
|
||||
|
||||
if (cad.nk(vit, support).n() == -1) { // vertical line
|
||||
// TODO sufficient condition? actually both surfaces
|
||||
// need to be vertical, right?
|
||||
// better criterion: both polynomials vanish?
|
||||
|
||||
if (n == 0) {
|
||||
// whole line
|
||||
*coi++ = Surface_arc_3(point, support);
|
||||
} else {
|
||||
CGAL_assertion(n > 0);
|
||||
Surface_point_3 min, max;
|
||||
min = Surface_point_3(point, support, 0);
|
||||
for (int sheet = 0; sheet < n; sheet++) {
|
||||
if (sheet == 0) {
|
||||
// ray from z=-oo
|
||||
*coi++ = Surface_arc_3(min,
|
||||
CGAL::ARR_MIN_END,
|
||||
support);
|
||||
}
|
||||
if (sheet + 1 == n) {
|
||||
// ray to z==oo
|
||||
*coi++ = Surface_arc_3(min,
|
||||
CGAL::ARR_MAX_END,
|
||||
support);
|
||||
break;
|
||||
}
|
||||
CGAL_assertion(sheet + 1 < n);
|
||||
max = Surface_point_3(point, support, sheet + 1);
|
||||
// bounded vertical arc
|
||||
*coi++ = Surface_arc_3(min, max, support);
|
||||
min = max;
|
||||
}
|
||||
}
|
||||
return; // as no further isolated vertices will occur
|
||||
}
|
||||
|
||||
// else
|
||||
|
||||
if (n == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::set< int > sheets;
|
||||
|
||||
if (!vit->is_isolated()) {
|
||||
for (int k = 0; k < n; k++) {
|
||||
typename Restricted_cad_3::
|
||||
Halfedge_around_vertex_const_circulator circ,
|
||||
start =
|
||||
vit->incident_halfedges();
|
||||
circ = start;
|
||||
bool isolated = true;
|
||||
do {
|
||||
++circ;
|
||||
|
||||
std::pair< Z_stack, std::pair< int, int > >
|
||||
adjmin =
|
||||
cad.surface_adjacency(vit, support, k,
|
||||
circ);
|
||||
|
||||
if (adjmin.second.first <= adjmin.second.second) {
|
||||
isolated = false;
|
||||
break;
|
||||
}
|
||||
|
||||
} while (circ != start);
|
||||
|
||||
if (isolated) {
|
||||
sheets.insert(k);
|
||||
}
|
||||
}
|
||||
|
||||
if (sheets.empty()) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
for (int k = 0; k < n; k++) {
|
||||
sheets.insert(k);
|
||||
}
|
||||
}
|
||||
|
||||
typename
|
||||
Surface_z_at_xy_isolator_traits::Equal_z
|
||||
equal_z; // TODO single instance
|
||||
|
||||
typename
|
||||
Surface_z_at_xy_isolator_traits::Point_on_curve_2
|
||||
point_on_curve; // TODO single instance
|
||||
|
||||
int k = 1;
|
||||
|
||||
Polynomial_3 local_gcd =
|
||||
equal_z.local_gcd(support, other,
|
||||
support_isolator.traits(), k);
|
||||
|
||||
// TODO make use of k
|
||||
|
||||
// TODO be carefull if one of the surfaces has a vertical line
|
||||
|
||||
Surface_3 gcd_surface =
|
||||
Surface_3::surface_cache()(local_gcd);
|
||||
|
||||
Polynomial_2 sil_local_gcd = gcd_surface.resultant_f_fz();
|
||||
|
||||
bool on_gcd_sil = point_on_curve(point, sil_local_gcd);
|
||||
|
||||
Z_at_xy_isolator gcd_isolator =
|
||||
construct_isolator(
|
||||
local_gcd, point,
|
||||
cad.nk(vit, support),
|
||||
(on_gcd_sil ? SoX::EDGE : SoX::FACE)
|
||||
);
|
||||
|
||||
// compute overlaps
|
||||
std::vector< std::pair< int, int > > overlaps;
|
||||
|
||||
iv_helper.refined_overlaps(
|
||||
support_isolator, gcd_isolator,
|
||||
std::back_inserter(overlaps)
|
||||
);
|
||||
|
||||
// refine until a gcd-interval is fully include in
|
||||
// support interval or has moved away
|
||||
for (int k = 0; k < static_cast< int >(overlaps.size());
|
||||
k++) {
|
||||
|
||||
if (sheets.find(overlaps[k].first) == sheets.end()) {
|
||||
// the overlaps[k].first sheets is not isolated!
|
||||
continue;
|
||||
}
|
||||
|
||||
// here we are only faces with sheet levels
|
||||
// that form an isolated point of support :-)
|
||||
|
||||
while (true) {
|
||||
|
||||
if (iv_helper.overlap_or_order(
|
||||
gcd_isolator, overlaps[k].second,
|
||||
support_isolator, overlaps[k].first
|
||||
) != CGAL::EQUAL) {
|
||||
break;
|
||||
}
|
||||
// else
|
||||
|
||||
if (iv_helper.is_included(
|
||||
gcd_isolator, overlaps[k].second,
|
||||
support_isolator, overlaps[k].first,
|
||||
true
|
||||
)
|
||||
) {
|
||||
*poi++ = Surface_point_3(vit->point(),support,
|
||||
overlaps[k].first);
|
||||
break;
|
||||
}
|
||||
|
||||
// else
|
||||
gcd_isolator.refine_interval(overlaps[k].second);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//!@}
|
||||
|
||||
}; // Curve_3
|
||||
|
||||
} // namespace SoX
|
||||
|
||||
#endif // SoX_GAPS_CURVE_3_H
|
||||
// EOF
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,441 @@
|
|||
// ============================================================================
|
||||
//
|
||||
// Copyright (c) 2001-2008 Max-Planck-Institut Saarbruecken (Germany).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of EXACUS (http://www.mpi-inf.mpg.de/projects/EXACUS/);
|
||||
// you may redistribute it under the terms of the Q Public License version 1.0.
|
||||
// See the file LICENSE.QPL distributed with EXACUS.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Library : SoX
|
||||
// File : include/SoX/GAPS/Restricted_cad_3_accessor.h
|
||||
// SoX_release : $Name: $
|
||||
// Revision : $Revision$
|
||||
// Revision_date : $Date$
|
||||
//
|
||||
// Author(s) : Eric Berberich <eric@mpi-inf.mpg.de>
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
#ifndef SoX_GAPS_RESTRICTED_CAD_3_ACCESSOR_H
|
||||
#define SoX_GAPS_RESTRICTED_CAD_3_ACCESSOR_H 1
|
||||
|
||||
/*! \file SoX/GAPS/Restricted_cad_3_accessor.h
|
||||
\brief Contains class template Restricted_cad_3_accessor
|
||||
*/
|
||||
|
||||
#include <CGAL/config.h>
|
||||
|
||||
#include <CGAL/Arrangement_2l/Restricted_cad_3_enums.h>
|
||||
|
||||
namespace SoX {
|
||||
|
||||
/*!\brief
|
||||
* Accessor class for private types and members of RestrictedCad_3
|
||||
*/
|
||||
template < class RestrictedCad_3 >
|
||||
class Restricted_cad_3_accessor {
|
||||
public:
|
||||
|
||||
//! this instance's first template parameter
|
||||
typedef RestrictedCad_3 Restricted_cad_3;
|
||||
|
||||
//! type of instantiated class
|
||||
typedef Restricted_cad_3_accessor< Restricted_cad_3 > Self;
|
||||
|
||||
//! standard constructor
|
||||
Restricted_cad_3_accessor(const Restricted_cad_3& rscad) :
|
||||
_m_rscad(rscad) {
|
||||
}
|
||||
|
||||
private:
|
||||
typedef Restricted_cad_3 RSC_3;
|
||||
|
||||
public:
|
||||
//! rep class
|
||||
typedef typename RSC_3::Rep Rep;
|
||||
|
||||
//! base class
|
||||
typedef typename RSC_3::Base Base;
|
||||
|
||||
//! type of Surface
|
||||
typedef typename RSC_3::Surface_3 Surface_3;
|
||||
|
||||
//! Z_Stack type
|
||||
typedef typename RSC_3::Z_stack Z_stack;
|
||||
|
||||
//! Z_at_xy_isolator type
|
||||
typedef typename RSC_3::Z_at_xy_isolator Z_at_xy_isolator;
|
||||
|
||||
// from arrangement
|
||||
typedef typename RSC_3::Size Size;
|
||||
|
||||
typedef typename RSC_3::Curve_analysis_2 Curve_analysis_2;
|
||||
|
||||
typedef typename RSC_3::Point_2 Point_2;
|
||||
typedef typename RSC_3::X_monotone_curve_2 X_monotone_curve_2;
|
||||
|
||||
typedef typename RSC_3::Vertex_const_iterator Vertex_const_iterator;
|
||||
|
||||
typedef typename RSC_3::Edge_const_iterator Edge_const_iterator;
|
||||
|
||||
typedef typename RSC_3::Halfedge_const_iterator Halfedge_const_iterator;
|
||||
|
||||
typedef typename RSC_3::Face_const_iterator Face_const_iterator;
|
||||
|
||||
typedef typename RSC_3::Ccb_halfedge_const_circulator
|
||||
Ccb_halfedge_const_circulator;
|
||||
|
||||
typedef typename RSC_3::Outer_ccb_const_iterator Outer_ccb_const_iterator;
|
||||
|
||||
typedef typename RSC_3::Inner_ccb_const_iterator Inner_ccb_const_iterator;
|
||||
|
||||
typedef typename RSC_3::Vertex_const_handle Vertex_const_handle;
|
||||
typedef typename RSC_3::Halfedge_const_handle Halfedge_const_handle;
|
||||
typedef typename RSC_3::Edge_const_handle Edge_const_handle;
|
||||
typedef typename RSC_3::Face_const_handle Face_const_handle;
|
||||
|
||||
typedef typename RSC_3::Vertex_handle Vertex_handle;
|
||||
typedef typename RSC_3::Halfedge_handle Halfedge_handle;
|
||||
typedef typename RSC_3::Edge_handle Edge_handle;
|
||||
typedef typename RSC_3::Face_handle Face_handle;
|
||||
|
||||
typedef typename RSC_3::Point_location Point_location;
|
||||
|
||||
//! type of X_coordinate
|
||||
typedef typename RSC_3::X_coordinate_1 X_coordinate_1;
|
||||
|
||||
//! type of Boundary
|
||||
typedef typename RSC_3::Boundary Boundary;
|
||||
|
||||
//!\name Global
|
||||
//!@{
|
||||
|
||||
//! Returns a pointer to the representation of the cad
|
||||
inline const Rep* rep() const {
|
||||
return _m_rscad.ptr();
|
||||
}
|
||||
|
||||
//! make id unique and clear the rep
|
||||
inline void renew() {
|
||||
_m_rscad._renew();
|
||||
}
|
||||
|
||||
//! construct cad for curve
|
||||
static
|
||||
Restricted_cad_3 construct_for_curve(const Curve_analysis_2& curve) {
|
||||
return Restricted_cad_3::_construct_for_curve(curve);
|
||||
}
|
||||
|
||||
//! initialize data objects
|
||||
inline void init(const Surface_3& surface) {
|
||||
_m_rscad._init(surface);
|
||||
}
|
||||
|
||||
//! set final data
|
||||
inline void finalize(const Surface_3& surface) {
|
||||
_m_rscad._finalize(surface);
|
||||
}
|
||||
|
||||
//!@}
|
||||
|
||||
//!\name Arrangement methods
|
||||
//!@{
|
||||
|
||||
/*! insert a range of curves */
|
||||
template < class InputIterator >
|
||||
inline
|
||||
void insert_non_intersecting_curves(
|
||||
InputIterator begin, InputIterator end
|
||||
) {
|
||||
_m_rscad._insert_non_intersecting_curves(begin, end);
|
||||
}
|
||||
|
||||
/*! insert a range of curves */
|
||||
template < class CurveInputIterator, class PointInputIterator >
|
||||
inline
|
||||
void insert_empty(
|
||||
CurveInputIterator cbegin, CurveInputIterator cend,
|
||||
PointInputIterator pbegin, PointInputIterator pend
|
||||
|
||||
) {
|
||||
_m_rscad._insert_empty(cbegin, cend, pbegin, pend);
|
||||
}
|
||||
|
||||
|
||||
/*! inserts an isolated point */
|
||||
inline
|
||||
void insert_point(Point_2 pt) {
|
||||
_m_rscad._insert_point(pt);
|
||||
}
|
||||
|
||||
/*! remove edge from arrangement */
|
||||
void remove_edge(Halfedge_handle he) {
|
||||
_m_rscad._remove_edge(he);
|
||||
}
|
||||
|
||||
/*! remove edge from arrangement */
|
||||
void remove_vertex(Vertex_handle vh) {
|
||||
_m_rscad._remove_vertex(vh);
|
||||
}
|
||||
|
||||
/*! overlays two instances */
|
||||
inline
|
||||
void overlay(Restricted_cad_3 rscad1,
|
||||
Restricted_cad_3 rscad2, bool factors_of_same_curve) {
|
||||
_m_rscad._overlay(rscad1, rscad2, factors_of_same_curve);
|
||||
}
|
||||
|
||||
/*! overlays two instances */
|
||||
inline
|
||||
void overlay(Restricted_cad_3 rscad1,
|
||||
Restricted_cad_3 rscad2,
|
||||
Surface_3 surface, SoX::Nk::Value_type type) {
|
||||
_m_rscad._overlay(rscad1, rscad2, surface, type);
|
||||
}
|
||||
|
||||
//!@}
|
||||
|
||||
//!\name Geometry and the Dcel
|
||||
//!@{
|
||||
|
||||
/*!\brief
|
||||
* use point location to check whether \c pt is part of given
|
||||
* \c handle
|
||||
*/
|
||||
template < class DcelConstHandle >
|
||||
inline
|
||||
bool point_on_dcel_handle(const Point_2& pt,
|
||||
DcelConstHandle handle) const {
|
||||
return _m_rscad._point_on_dcel_handle(pt, handle);
|
||||
}
|
||||
|
||||
/*!\brief
|
||||
* constructs a rational point at coordinate \c x0, \c y0
|
||||
*/
|
||||
static
|
||||
Point_2 construct_point_with_rational_y(X_coordinate_1 x0, Boundary y0) {
|
||||
return RSC_3::_construct_point_with_rational_y(x0, y0);
|
||||
}
|
||||
|
||||
//! construct point, with rational x (or y) in interior of \c heh's curve
|
||||
static
|
||||
Point_2 point_in_interior(const Halfedge_const_handle& heh) {
|
||||
return RSC_3::_point_in_interior(heh);
|
||||
}
|
||||
|
||||
//! construct point, with rational x (or y) in interior of \c cv
|
||||
static
|
||||
Point_2 point_in_interior(const X_monotone_curve_2& cv) {
|
||||
return RSC_3::_point_in_interior(cv);
|
||||
}
|
||||
|
||||
//!@}
|
||||
|
||||
//!\name Counting
|
||||
//!@{
|
||||
/*! Check whether the arrangement is empty. */
|
||||
|
||||
/*! Get the number of arrangement halfedges (the result is always even). */
|
||||
inline
|
||||
Size number_of_halfedges () const
|
||||
{
|
||||
return (_m_rscad.number_of_halfedges());
|
||||
}
|
||||
|
||||
//!@}
|
||||
|
||||
//\name Traversal functions for the arrangement halfedges.
|
||||
//!@{
|
||||
|
||||
/*! Get a const iterator for the first halfedge in the arrangement. */
|
||||
inline
|
||||
Halfedge_const_iterator halfedges_begin() const
|
||||
{
|
||||
return (_m_rscad.halfedges_begin());
|
||||
}
|
||||
|
||||
/*! Get a past-the-end const iterator for the arrangement halfedges. */
|
||||
inline
|
||||
Halfedge_const_iterator halfedges_end() const
|
||||
{
|
||||
return (_m_rscad.halfedges_end());
|
||||
}
|
||||
//!@}
|
||||
|
||||
//!\name Casting away constness for handle types.
|
||||
//!@{
|
||||
|
||||
//! converts const vertex handle to non-const vertex handle
|
||||
inline
|
||||
typename Rep::Vertex_handle non_const_handle (Vertex_const_handle vh)
|
||||
{
|
||||
return (_m_rscad.non_const_handle(vh));
|
||||
}
|
||||
|
||||
//! converts const halfedge handle to non-const halfedge handle
|
||||
inline
|
||||
typename Rep::Halfedge_handle non_const_handle (Halfedge_const_handle hh)
|
||||
{
|
||||
return (_m_rscad.non_const_handle(hh));
|
||||
}
|
||||
|
||||
//! converts const face handle to non-const face handle
|
||||
inline
|
||||
typename Rep::Face_handle non_const_handle (Face_const_handle fh)
|
||||
{
|
||||
return (_m_rscad.non_const_handle(fh));
|
||||
}
|
||||
//!@}
|
||||
|
||||
//!\name Nk
|
||||
//!@{
|
||||
|
||||
|
||||
//! set value for vertex handle
|
||||
inline void set_nk_value(const Vertex_const_handle& vh,
|
||||
const Surface_3& surface,
|
||||
SoX::Nk::Value_type type,
|
||||
int value) const {
|
||||
_m_rscad._set_nk_value(vh, surface, type, value);
|
||||
}
|
||||
|
||||
//! set value for halfedge handle
|
||||
inline void set_nk_value(const Halfedge_const_handle& heh,
|
||||
const Surface_3& surface,
|
||||
SoX::Nk::Value_type type,
|
||||
int value) const {
|
||||
_m_rscad._set_nk_value(heh, surface, type, value);
|
||||
}
|
||||
|
||||
//! set value for edge handle
|
||||
inline void set_nk_value(const Edge_const_handle& eh,
|
||||
const Surface_3& surface,
|
||||
SoX::Nk::Value_type type,
|
||||
int value) const {
|
||||
_m_rscad._set_nk_value(eh, surface, type, value);
|
||||
}
|
||||
|
||||
//! set value for face handle
|
||||
inline void set_nk_value(const Face_const_handle& fh,
|
||||
const Surface_3& surface,
|
||||
SoX::Nk::Value_type type,
|
||||
int value) const {
|
||||
_m_rscad._set_nk_value(fh, surface, type, value);
|
||||
}
|
||||
|
||||
//! nk for halfedge handle
|
||||
const SoX::Nk& nk(const Halfedge_const_handle& heh,
|
||||
const Surface_3& surface) const {
|
||||
return _m_rscad.nk(heh, surface);
|
||||
}
|
||||
|
||||
//!@}
|
||||
|
||||
|
||||
//!\name Silhouette/Cut
|
||||
//!@{
|
||||
|
||||
//! returns whether silhouette at given halfedge handle exists
|
||||
bool has_silhouette(const Halfedge_const_handle& heh) const {
|
||||
return (_m_rscad.has_silhouette(heh));
|
||||
}
|
||||
|
||||
//! returns whether cut at given halfedge handle exists
|
||||
bool has_cut(const Halfedge_const_handle& heh) const {
|
||||
return (_m_rscad.has_cut(heh));
|
||||
}
|
||||
|
||||
//! returns whether silhouette of \c surface at \c heh exists
|
||||
bool has_silhouette(const Halfedge_const_handle& heh,
|
||||
const Surface_3& surface) const {
|
||||
return (_m_rscad.has_silhouette(heh,surface));
|
||||
}
|
||||
|
||||
//! returns whether cut the two surface at \c heh exisst
|
||||
bool has_cut(const Halfedge_const_handle& heh,
|
||||
const Surface_3& surface1,
|
||||
const Surface_3& surface2) const {
|
||||
return (_m_rscad.has_cut(heh,surface1, surface2));
|
||||
}
|
||||
|
||||
//!@}
|
||||
|
||||
//!@{
|
||||
|
||||
//! returns sample point for halfedge handle
|
||||
inline
|
||||
Point_2 sample_point(const Halfedge_const_handle& heh) const {
|
||||
return _m_rscad.sample_point(heh);
|
||||
}
|
||||
|
||||
//!@}
|
||||
|
||||
//!\name Isolators
|
||||
//!@{
|
||||
|
||||
//! returns isolator (if existing) for given surface at given handle
|
||||
boost::optional< Z_at_xy_isolator>
|
||||
isolator(const Halfedge_const_handle& heh,
|
||||
const Surface_3& surface) const {
|
||||
return _m_rscad_isolator(heh, surface);
|
||||
}
|
||||
|
||||
//!@}
|
||||
|
||||
//!\name Z_Stacks
|
||||
//!@{
|
||||
|
||||
//! returns whether z_stack is known
|
||||
bool knows_z_stack(const Vertex_const_handle& vh) const {
|
||||
return vh->data()->_knows_z_stack();
|
||||
}
|
||||
|
||||
//! returns whether z_stack is known
|
||||
bool knows_z_stack(const Halfedge_const_handle& heh) const {
|
||||
return heh->data()->_knows_z_stack();
|
||||
}
|
||||
|
||||
//! returns whether z_stack is known
|
||||
bool knows_z_stack(const Edge_const_handle& eh) const {
|
||||
return eh->data()->_knows_z_stack();
|
||||
}
|
||||
|
||||
//! returns whether z_stack is known
|
||||
bool knows_z_stack(const Face_const_handle& fh) const {
|
||||
return fh->data()->_knows_z_stack();
|
||||
}
|
||||
|
||||
//! returns z_stack for given edge handle
|
||||
inline
|
||||
Z_stack z_stack(const Halfedge_const_handle& heh) const {
|
||||
return _m_rscad.z_stack(heh);
|
||||
}
|
||||
|
||||
//! returns z_stack of silhouette-curve of \c surface at halfedge handle
|
||||
inline
|
||||
std::pair< Z_stack, SoX::Dcel_feature >
|
||||
z_stack(const Halfedge_const_handle& heh,
|
||||
const Surface_3& surface) const {
|
||||
return _m_rscad.z_stack(heh, surface);
|
||||
}
|
||||
|
||||
//!@}
|
||||
|
||||
private:
|
||||
Restricted_cad_3 _m_rscad;
|
||||
|
||||
};
|
||||
|
||||
} // namespace SoX
|
||||
|
||||
#endif // SoX_GAPS_RESTRICTED_CAD_3_ACCESSOR_H
|
||||
// EOF
|
||||
|
|
@ -0,0 +1,171 @@
|
|||
// ============================================================================
|
||||
//
|
||||
// Copyright (c) 2001-2008 Max-Planck-Institut Saarbruecken (Germany).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of EXACUS (http://www.mpi-inf.mpg.de/projects/EXACUS/);
|
||||
// you may redistribute it under the terms of the Q Public License version 1.0.
|
||||
// See the file LICENSE.QPL distributed with EXACUS.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Library : SoX
|
||||
// File : include/SoX/GAPS/Restricted_cad_3_enums.h
|
||||
// SoX_release : $Name: $
|
||||
// Revision : $Revision$
|
||||
// Revision_date : $Date$
|
||||
//
|
||||
// Author(s) : Eric Berberich <eric@mpi-inf.mpg.de>
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
#ifndef SoX_GAPS_RESTRICTED_CAD_3_ENUMS_H
|
||||
#define SoX_GAPS_RESTRICTED_CAD_3_ENUMS_H 1
|
||||
|
||||
/*! \file SoX/GAPS/Restricted_cad_3_enums.h
|
||||
\brief Contains enumeration related to
|
||||
\link Restricted_cad_3 \endlink
|
||||
*/
|
||||
|
||||
#include <CGAL/basic.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace SoX {
|
||||
|
||||
//! distinguishes between the three possible dcel-features
|
||||
enum Dcel_feature {
|
||||
VERTEX = 0, //!< identifies a vertex
|
||||
EDGE = 1, //!< identifies an edge
|
||||
FACE = 2 //!< identifies a face
|
||||
};
|
||||
|
||||
/*!\relates Dcel_feature
|
||||
\brief output operator
|
||||
|
||||
The output is intended for debugging purposes only and hence always
|
||||
is in a human-readable pretty-print format.
|
||||
|
||||
|
||||
*/
|
||||
// \pre ::CGAL::is_pretty(os)
|
||||
inline std::ostream& operator<< (std::ostream& os, Dcel_feature feat) {
|
||||
//CGAL_precondition(::CGAL::is_pretty(os));
|
||||
static const char* names[] = { "VERTEX", "EDGE", "FACE" };
|
||||
|
||||
CGAL_assertion(feat >= 0 &&
|
||||
feat < static_cast<int>(sizeof names / sizeof *names));
|
||||
return os << names[feat];
|
||||
}
|
||||
|
||||
|
||||
//! container for integers
|
||||
class Nk {
|
||||
public:
|
||||
|
||||
enum Value_type {
|
||||
MULT = 1,
|
||||
N = 2,
|
||||
K = 3
|
||||
};
|
||||
|
||||
Nk() :
|
||||
_m_feat1(SoX::VERTEX),
|
||||
_m_feat2(SoX::VERTEX),
|
||||
_m_mult(-1),
|
||||
// TODO other initial value?
|
||||
_m_n(-2),
|
||||
_m_k(-2),
|
||||
_m_fixed(false) {
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
SoX::Dcel_feature feature1() const {
|
||||
return _m_feat1;
|
||||
}
|
||||
|
||||
SoX::Dcel_feature feature2() const {
|
||||
return _m_feat2;
|
||||
}
|
||||
|
||||
void set_feature1(SoX::Dcel_feature feature) const {
|
||||
CGAL_precondition(!_m_fixed);
|
||||
_m_feat1 = feature;
|
||||
}
|
||||
|
||||
void set_feature2(SoX::Dcel_feature feature) const {
|
||||
CGAL_precondition(!_m_fixed);
|
||||
_m_feat2 = feature;
|
||||
}
|
||||
|
||||
int mult() const {
|
||||
return _m_mult;
|
||||
}
|
||||
|
||||
int n() const {
|
||||
return _m_n;
|
||||
}
|
||||
|
||||
int k() const {
|
||||
return _m_k;
|
||||
}
|
||||
|
||||
void set_mult(int mult) const {
|
||||
CGAL_precondition(mult >= 0);
|
||||
CGAL_precondition(!_m_fixed);
|
||||
_m_mult = mult;
|
||||
}
|
||||
|
||||
void set_n(int n) const {
|
||||
CGAL_precondition(n >= -1);
|
||||
CGAL_precondition(!_m_fixed);
|
||||
_m_n = n;
|
||||
}
|
||||
|
||||
void set_k(int k) const {
|
||||
CGAL_precondition(k >= -1);
|
||||
CGAL_precondition(!_m_fixed);
|
||||
_m_k = k;
|
||||
}
|
||||
|
||||
void fix() const {
|
||||
_m_fixed = true;
|
||||
}
|
||||
|
||||
bool same_nk(const Nk& nk) const {
|
||||
return
|
||||
(this->_m_n == nk._m_n) &&
|
||||
(this->_m_k == nk._m_k);
|
||||
}
|
||||
|
||||
private:
|
||||
// members
|
||||
mutable SoX::Dcel_feature _m_feat1;
|
||||
mutable SoX::Dcel_feature _m_feat2;
|
||||
|
||||
|
||||
mutable int _m_mult;
|
||||
mutable int _m_n;
|
||||
mutable int _m_k;
|
||||
|
||||
mutable bool _m_fixed;
|
||||
};
|
||||
|
||||
|
||||
inline
|
||||
std::ostream& operator<<(std::ostream& out, const SoX::Nk& nk) {
|
||||
out << "NK(mult=" << nk.mult() << ",n=" << nk.n()
|
||||
<< ",k=" << nk.k() << ")";
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace SoX
|
||||
|
||||
#endif // SoX_GAPS_RESTRICTED_CAD_3_ENUMS_H
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,841 @@
|
|||
// ============================================================================
|
||||
//
|
||||
// Copyright (c) 2001-2008 Max-Planck-Institut Saarbruecken (Germany).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of EXACUS (http://www.mpi-inf.mpg.de/projects/EXACUS/);
|
||||
// you may redistribute it under the terms of the Q Public License version 1.0.
|
||||
// See the file LICENSE.QPL distributed with EXACUS.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Library : QdX
|
||||
// File : include/SoX/GAPS/Surface_3_envelope_traits.h
|
||||
// QdX_release : $Name: $
|
||||
// Revision : $Revision$
|
||||
// Revision_date : $Date$
|
||||
//
|
||||
// Author(s) : Eric Berberich <eric@mpi-inf.mpg.de>
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
#ifndef SoX_GAPS_SURFACE_3_ENVELOPE_TRAITS
|
||||
#define SoX_GAPS_SURFACE_3_ENVELOPE_TRAITS 1
|
||||
|
||||
/*!\file SoX/GAPS/Surface_3_envelope_traits.h
|
||||
* \brief Model for CGAL's EnvelopeTraits_3 concept.
|
||||
*/
|
||||
|
||||
#ifndef CGAL_ENVELOPE_3_USE_EDGE_HANDLES
|
||||
#define CGAL_ENVELOPE_3_USE_EDGE_HANDLES 0
|
||||
#endif
|
||||
|
||||
#include <CGAL/config.h>
|
||||
|
||||
#include <CGAL/Handle_with_policy.h>
|
||||
|
||||
#include <CGAL/Arr_enums.h>
|
||||
#include <CGAL/Arr_curve_data_traits_2.h>
|
||||
#include <CGAL/Envelope_3/Envelope_base.h>
|
||||
|
||||
#include <CGAL/Arrangement_2l/Restricted_cad_3_accessor.h>
|
||||
|
||||
namespace SoX {
|
||||
|
||||
namespace Intern {
|
||||
|
||||
#if CGAL_ENVELOPE_3_USE_EDGE_HANDLES
|
||||
template < class SurfacePair_3 >
|
||||
struct Intersection_info : public CGAL::Handle_with_policy<
|
||||
std::map< SurfacePair_3,
|
||||
typename SurfacePair_3::Restricted_cad_3::Edge_const_handle,
|
||||
CGAL::Handle_id_less_than< SurfacePair_3 >
|
||||
>
|
||||
> {
|
||||
|
||||
typedef SurfacePair_3 Surface_pair_3;
|
||||
|
||||
typedef typename Surface_pair_3::Restricted_cad_3::Edge_const_handle
|
||||
Edge_const_handle;
|
||||
|
||||
typedef CGAL::Handle_id_less_than< Surface_pair_3 > Less;
|
||||
|
||||
typedef std::map< SurfacePair_3, Edge_const_handle, Less > Rep;
|
||||
|
||||
typedef CGAL::Handle_with_policy< Rep > Base;
|
||||
|
||||
typedef Intersection_info< Surface_pair_3 > Self;
|
||||
|
||||
typedef typename Rep::const_iterator const_iterator;
|
||||
|
||||
typedef typename Rep::value_type value_type;
|
||||
|
||||
private:
|
||||
typedef typename Rep::iterator iterator;
|
||||
|
||||
public:
|
||||
|
||||
Intersection_info() {
|
||||
}
|
||||
|
||||
Intersection_info(const Surface_pair_3& surface,
|
||||
const Edge_const_handle& eh) {
|
||||
CGAL_precondition(this->ptr()->empty());
|
||||
this->ptr()->insert(std::make_pair(surface, eh));
|
||||
}
|
||||
|
||||
const_iterator begin() const {
|
||||
return this->ptr()->begin();
|
||||
}
|
||||
|
||||
const_iterator end() const {
|
||||
return this->ptr()->end();
|
||||
}
|
||||
|
||||
const_iterator find(const Surface_pair_3& pair) const {
|
||||
return this->ptr()->find(pair);
|
||||
}
|
||||
|
||||
Self operator() (Self d1, Self d2) {
|
||||
Self tmp = d2;
|
||||
tmp.copy_on_write();
|
||||
|
||||
for (iterator it1 = d1.ptr()->begin();
|
||||
it1 != d1.ptr()->end(); it1++) {
|
||||
iterator it2 = tmp.ptr()->find(it1->first);
|
||||
if (it2 == tmp.ptr()->end()) {
|
||||
tmp.ptr()->insert(it2, *it1);
|
||||
}
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool operator== (Self self) const {
|
||||
return this->id() == self.id();
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace Intern
|
||||
|
||||
|
||||
// TODO implement Apollonius-Mode
|
||||
// TODO implicitly requires Surface_pair_3::surface_pair_cache()
|
||||
template < class SurfacePair_3 >
|
||||
class Surface_3_envelope_traits : public
|
||||
#if CGAL_ENVELOPE_3_USE_EDGE_HANDLES
|
||||
CGAL::Arr_curve_data_traits_2<
|
||||
typename SurfacePair_3::Surface_z_at_xy_isolator_traits::Arrangement_traits_2,
|
||||
Intern::Intersection_info< SurfacePair_3 >,
|
||||
Intern::Intersection_info< SurfacePair_3 >
|
||||
>
|
||||
#else
|
||||
SurfacePair_3::Surface_z_at_xy_isolator_traits::Arrangement_traits_2
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
//! this instance template parameter
|
||||
typedef SurfacePair_3 Surface_pair_3;
|
||||
|
||||
//! the class itself
|
||||
typedef Surface_3_envelope_traits< Surface_pair_3 > Self;
|
||||
|
||||
// types for EnvelopeTraits
|
||||
//! type of surfaces
|
||||
typedef typename Surface_pair_3::Surface_3 Surface_3;
|
||||
|
||||
//! type of Xy_monotone_surface_3
|
||||
typedef Surface_3 Xy_monotone_surface_3;
|
||||
|
||||
//! type of multiplicity
|
||||
typedef unsigned int Multiplicity;
|
||||
|
||||
private:
|
||||
//! type of Restricted_cad
|
||||
typedef typename Surface_pair_3::Restricted_cad_3 Restricted_cad_3;
|
||||
|
||||
//! type of surface traits
|
||||
typedef typename Surface_pair_3::Surface_z_at_xy_isolator_traits
|
||||
Surface_z_at_xy_isolator_traits;
|
||||
|
||||
//! type of basic traits
|
||||
typedef typename Surface_z_at_xy_isolator_traits::Arrangement_traits_2
|
||||
Arrangement_traits_2;
|
||||
|
||||
//! type of Edge_const_handle
|
||||
typedef typename Restricted_cad_3::Edge_const_handle Edge_const_handle;
|
||||
|
||||
#if CGAL_ENVELOPE_3_USE_EDGE_HANDLES
|
||||
typedef Intern::Intersection_info< Surface_pair_3 > Info;
|
||||
|
||||
//! type of base class
|
||||
typedef
|
||||
CGAL::Arr_curve_data_traits_2< Arrangement_traits_2, Info, Info > Base;
|
||||
#else
|
||||
//! type of base class
|
||||
typedef Arrangement_traits_2 Base;
|
||||
#endif
|
||||
|
||||
//! type of Z_Stack
|
||||
typedef typename Restricted_cad_3::Z_stack Z_stack;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//! class of point
|
||||
typedef typename Base::Point_2 Point_2;
|
||||
|
||||
//! class of x-monotone curve
|
||||
typedef typename Base::X_monotone_curve_2 X_monotone_curve_2;
|
||||
|
||||
public:
|
||||
|
||||
/*!\brief
|
||||
* Subdivide the given surface into envelope relevant xy-monotone
|
||||
* parts, and insert them into the output iterator.
|
||||
*
|
||||
* The iterator value-type is Xy_monotone_surface_3
|
||||
*/
|
||||
class Make_xy_monotone_3
|
||||
{
|
||||
protected:
|
||||
const Self *parent;
|
||||
public:
|
||||
Make_xy_monotone_3(const Self* p)
|
||||
: parent(p)
|
||||
{}
|
||||
|
||||
|
||||
template <class OutputIterator>
|
||||
OutputIterator operator()(
|
||||
const Surface_3& s,
|
||||
bool is_lower,
|
||||
OutputIterator oi)
|
||||
{
|
||||
//parent->total_timer.start();
|
||||
|
||||
// TODO surfaces must be coprime?
|
||||
// TASK Ask RW, MM for triangles, and planes
|
||||
|
||||
// we just apply the sophisticated stuff in sqff_3
|
||||
// that also deals with the case of vertical components
|
||||
typename
|
||||
Surface_z_at_xy_isolator_traits::Square_free_factorization_3
|
||||
sqff_3; // TODO unique instance!
|
||||
|
||||
std::list< int > mults;
|
||||
sqff_3(s.f(), oi, std::back_inserter(mults));
|
||||
|
||||
//parent->total_timer.stop();
|
||||
|
||||
return oi;
|
||||
}
|
||||
};
|
||||
|
||||
/*! Get a Make_xy_monotone_3 functor object. */
|
||||
Make_xy_monotone_3 make_xy_monotone_3_object()
|
||||
{
|
||||
return Make_xy_monotone_3(this);
|
||||
}
|
||||
|
||||
/*!\brief
|
||||
* Insert all 2D curves, which form of the boundary of the
|
||||
* vertical projection of s onto the xy-plane, into the output iterator.
|
||||
* The iterator value-type is Curve_2.
|
||||
*/
|
||||
class Construct_projected_boundary_2 {
|
||||
protected:
|
||||
const Self *parent;
|
||||
public:
|
||||
Construct_projected_boundary_2(const Self* p)
|
||||
: parent(p)
|
||||
{}
|
||||
|
||||
template <class OutputIterator>
|
||||
OutputIterator operator()(
|
||||
const Xy_monotone_surface_3& s,
|
||||
OutputIterator oi) {
|
||||
|
||||
#if !NDEBUG
|
||||
std::cout << "Construct_projected_boundary ... " << std::flush;
|
||||
#endif
|
||||
//parent->total_timer.start();
|
||||
//parent->pboundary_timer.start();
|
||||
|
||||
// create cached instance
|
||||
Restricted_cad_3 cad = Restricted_cad_3::cad_cache()(s);
|
||||
|
||||
// we run over all segments/isolated points of cad and
|
||||
// check whether they belong to boundary of s
|
||||
|
||||
for (typename Restricted_cad_3::Vertex_const_iterator vit =
|
||||
cad.vertices_begin();
|
||||
vit != cad.vertices_end(); vit++) {
|
||||
if (vit->is_isolated() && cad.has_silhouette(vit)) {
|
||||
Z_stack z_stack = cad.z_stack(vit);
|
||||
// we are only interested in the lowest boundary!
|
||||
if (!z_stack.is_empty()) {
|
||||
if (z_stack.level_of_surface_in_z_cell(s,0) == 0) {
|
||||
*oi++ = CGAL::make_object(vit->point());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (typename Restricted_cad_3::Edge_const_iterator eit =
|
||||
cad.edges_begin();
|
||||
eit != cad.edges_end(); eit++) {
|
||||
if (cad.has_silhouette(eit)) {
|
||||
Z_stack z_stack = cad.z_stack(eit);
|
||||
if (!z_stack.is_empty()) {
|
||||
// we are only interested in the lowest boundary
|
||||
// TODO check whether it is cheaper to check z_stacks
|
||||
// of incident faces first, instead of
|
||||
// checking z_stacks for eit
|
||||
if (z_stack.level_of_surface_in_z_cell(s,0) == 0) {
|
||||
CGAL::Arr_halfedge_direction dir =
|
||||
eit->direction();
|
||||
// check both incident faces of eit:
|
||||
// 1) both stacks are empty:
|
||||
// return ON_ORIENTED_BOUNDARY
|
||||
// 2) both stacks are non-empty:
|
||||
// this part of the curve isn't
|
||||
// a true boundary of s
|
||||
// 3) one is empty, the other not
|
||||
// we indicate the non-empty side!
|
||||
int k = cad.z_stack(
|
||||
eit->face()
|
||||
).number_of_z_cells();
|
||||
int l = cad.z_stack(
|
||||
eit->twin()->face()
|
||||
).number_of_z_cells();
|
||||
CGAL_assertion(k >= 0);
|
||||
CGAL_assertion(l >= 0);
|
||||
CGAL::Oriented_side side =
|
||||
CGAL::ON_ORIENTED_BOUNDARY;
|
||||
if (k > 0) {
|
||||
if (l > 0) {
|
||||
continue;
|
||||
} else {
|
||||
CGAL_assertion(l == 0);
|
||||
side = CGAL::ON_NEGATIVE_SIDE;
|
||||
}
|
||||
} else {
|
||||
CGAL_assertion(k == 0);
|
||||
if (l > 0) {
|
||||
side = CGAL::ON_POSITIVE_SIDE;
|
||||
}
|
||||
}
|
||||
if (dir == CGAL::ARR_LEFT_TO_RIGHT) {
|
||||
side = -side;
|
||||
}
|
||||
Edge_const_handle invalid_eh;
|
||||
*oi++ = CGAL::make_object(
|
||||
std::make_pair(
|
||||
X_monotone_curve_2(eit->curve()),
|
||||
side
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//parent->total_timer.stop();
|
||||
//parent->pboundary_timer.stop();
|
||||
|
||||
#if !NDEBUG
|
||||
std::cout << "done." << std::endl;
|
||||
#endif
|
||||
return oi;
|
||||
}
|
||||
};
|
||||
|
||||
/*! Get a Construct_projected_boundary_2 functor object. */
|
||||
Construct_projected_boundary_2
|
||||
construct_projected_boundary_2_object() const
|
||||
{
|
||||
return Construct_projected_boundary_2(this);
|
||||
}
|
||||
|
||||
|
||||
/*!\brief
|
||||
* Insert all the 2D projections (onto the xy-plane) of the
|
||||
* intersection objects between s1 and s2 into the output iterator.
|
||||
*
|
||||
* The iterator value-type is Object. An Object may be:
|
||||
* 1. A pair<Curve_2,Intersection_type>, where the intersection
|
||||
* type is an enumeration that can take the values
|
||||
* {Transversal, Tangency, Unknown}.
|
||||
* 2. A Point_2 instance (in degenerate cases).
|
||||
*/
|
||||
class Construct_projected_intersections_2 {
|
||||
protected:
|
||||
const Self *parent;
|
||||
public:
|
||||
Construct_projected_intersections_2(const Self* p)
|
||||
: parent(p)
|
||||
{}
|
||||
|
||||
template <class OutputIterator>
|
||||
OutputIterator operator()(
|
||||
const Xy_monotone_surface_3& s1,
|
||||
const Xy_monotone_surface_3& s2,
|
||||
OutputIterator oi) {
|
||||
#if !NDEBUG
|
||||
std::cout << "Construct_projected_intersections ... "
|
||||
<< std::flush;
|
||||
#endif
|
||||
//parent->total_timer.start();
|
||||
//parent->intersection_timer.start();
|
||||
|
||||
Surface_pair_3 pair =
|
||||
Surface_pair_3::surface_pair_cache()(std::make_pair(s1, s2));
|
||||
|
||||
Restricted_cad_3 cad = pair.silhouettes_cut();
|
||||
|
||||
// run over all segments/isolated points of cad and
|
||||
// check whether they belong to intersection of s1 and s2
|
||||
for (typename Restricted_cad_3::Vertex_const_iterator vit =
|
||||
cad.vertices_begin();
|
||||
vit != cad.vertices_end(); vit++) {
|
||||
if (vit->is_isolated() && cad.has_cut(vit)) {
|
||||
Z_stack z_stack = cad.z_stack(vit);
|
||||
if (!z_stack.is_empty()) {
|
||||
if (z_stack.level_of_surface_in_z_cell(s1,0) == 0 &&
|
||||
z_stack.level_of_surface_in_z_cell(s2,0) == 0) {
|
||||
*oi++ = CGAL::make_object(vit->point());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (typename Restricted_cad_3::Edge_const_iterator eit =
|
||||
cad.edges_begin();
|
||||
eit != cad.edges_end(); eit++) {
|
||||
if (cad.has_cut(eit)) {
|
||||
Z_stack z_stack = cad.z_stack(eit);
|
||||
if (!z_stack.is_empty()) {
|
||||
if (z_stack.level_of_surface_in_z_cell(s1,0) == 0 &&
|
||||
z_stack.level_of_surface_in_z_cell(s2,0) == 0) {
|
||||
// TODO compute multiplicity of intersection
|
||||
// if mult = 1 -> give 1
|
||||
// if mult = 2
|
||||
// -> check if unique intersection - give 2
|
||||
// if mult > 2
|
||||
// -> complex intersections destroy picture
|
||||
Multiplicity multiplicity = 0;
|
||||
#if CGAL_ENVELOPE_3_USE_EDGE_HANDLES
|
||||
Info info(pair, eit);
|
||||
#endif
|
||||
*oi++ = CGAL::make_object(
|
||||
std::make_pair(
|
||||
// store eit in info
|
||||
#if CGAL_ENVELOPE_3_USE_EDGE_HANDLES
|
||||
X_monotone_curve_2(eit->curve(),
|
||||
info),
|
||||
#else
|
||||
X_monotone_curve_2(eit->curve()),
|
||||
#endif
|
||||
multiplicity
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//parent->total_timer.stop();
|
||||
//parent->intersection_timer.stop();
|
||||
|
||||
#if !NDEBUG
|
||||
std::cout << "done." << std::endl;
|
||||
#endif
|
||||
|
||||
return oi;
|
||||
}
|
||||
};
|
||||
|
||||
/*! Get a Construct_projected_intersections_2 functor object. */
|
||||
Construct_projected_intersections_2
|
||||
construct_projected_intersections_2_object() const
|
||||
{
|
||||
return Construct_projected_intersections_2(this);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
//! compares the vertical alignment of \c s1 and \c s2 along \c z_stack
|
||||
static
|
||||
CGAL::Comparison_result _intern_compare(const Xy_monotone_surface_3& s1,
|
||||
const Xy_monotone_surface_3& s2,
|
||||
const Z_stack& z_stack,
|
||||
bool reverse) {
|
||||
CGAL_assertion(!z_stack.is_empty());
|
||||
int i1 = z_stack.level_of_surface_in_z_cell(s1,0);
|
||||
int i2 = z_stack.level_of_surface_in_z_cell(s2,0);
|
||||
|
||||
CGAL_assertion(i1 >= -1 || i2 >= -1);
|
||||
CGAL_assertion(i1 < 1);
|
||||
CGAL_assertion(i2 < 1);
|
||||
if (i1 == i2) {
|
||||
CGAL_assertion(i1 == 0);
|
||||
CGAL_assertion(i2 == 0);
|
||||
return CGAL::EQUAL;
|
||||
} else if (i1 == 0) {
|
||||
if (reverse) {
|
||||
return CGAL::LARGER;
|
||||
}
|
||||
return CGAL::SMALLER;
|
||||
}
|
||||
// else
|
||||
CGAL_assertion(i2 == 0);
|
||||
if (reverse) {
|
||||
return CGAL::SMALLER;
|
||||
}
|
||||
return CGAL::LARGER;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/*!\brief
|
||||
* Check if the surface s1 is closer/equally distanced/farther
|
||||
* from the envelope with respect to s2 at the xy-coordinates of p/c.
|
||||
*/
|
||||
class Compare_z_at_xy_3 {
|
||||
protected:
|
||||
const Self *parent;
|
||||
public:
|
||||
Compare_z_at_xy_3(const Self* p)
|
||||
: parent(p)
|
||||
{}
|
||||
|
||||
//! compare over point
|
||||
CGAL::Comparison_result operator()(
|
||||
const Point_2& p,
|
||||
const Xy_monotone_surface_3& s1,
|
||||
const Xy_monotone_surface_3& s2) const {
|
||||
#if !NDEBUG
|
||||
std::cout << "Compare over point ... " << std::flush;
|
||||
#endif
|
||||
//parent->total_timer.start();
|
||||
//parent->compare_timer.start();
|
||||
|
||||
Surface_pair_3 pair =
|
||||
Surface_pair_3::surface_pair_cache()(std::make_pair(s1, s2));
|
||||
|
||||
bool reverse = (s1 == pair.surface2());
|
||||
|
||||
Restricted_cad_3 cad = pair.silhouettes_cut();
|
||||
|
||||
// locate point
|
||||
// TODO develop strategy to avoid point location!
|
||||
Z_stack z_stack = cad.z_stack_for(p);
|
||||
|
||||
// and compare lowest z-cells of s1 and s2
|
||||
CGAL::Comparison_result result =
|
||||
_intern_compare(s1, s2, z_stack, reverse);
|
||||
|
||||
//parent->total_timer.stop();
|
||||
//parent->compare_timer.stop();
|
||||
#if !NDEBUG
|
||||
std::cout << "done." << std::endl;
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//! compare over curve
|
||||
CGAL::Comparison_result operator() (
|
||||
const X_monotone_curve_2& cv,
|
||||
const Xy_monotone_surface_3& s1,
|
||||
const Xy_monotone_surface_3& s2) const {
|
||||
|
||||
#if !NDEBUG
|
||||
std::cout << "Compare over curve ... " << std::flush;
|
||||
#endif
|
||||
//parent->total_timer.start();
|
||||
//parent->compare_on_cv_timer.start();
|
||||
|
||||
Surface_pair_3 pair =
|
||||
Surface_pair_3::surface_pair_cache()(std::make_pair(s1, s2));
|
||||
|
||||
bool reverse = (s1 == pair.surface2());
|
||||
|
||||
Restricted_cad_3 cad = pair.silhouettes_cut();
|
||||
|
||||
typedef Restricted_cad_3_accessor< Restricted_cad_3 > Accessor;
|
||||
Accessor acc(cad);
|
||||
|
||||
// construct point on c
|
||||
Point_2 p = acc.point_in_interior(cv);
|
||||
|
||||
// locate point
|
||||
// TODO develop strategy to avoid construction/point location!
|
||||
Z_stack z_stack = cad.z_stack_for(p);
|
||||
|
||||
// and compare lowest z-cells of s1 and s2
|
||||
CGAL::Comparison_result result =
|
||||
_intern_compare(s1, s2, z_stack, reverse);
|
||||
|
||||
// the two surfaces are not allowed to intersect ove c
|
||||
CGAL_postcondition(result != CGAL::EQUAL);
|
||||
|
||||
//parent->total_timer.stop();
|
||||
//parent->compare_on_cv_timer.stop();
|
||||
|
||||
#if !NDEBUG
|
||||
std::cout << "done." << std::endl;
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//! compare over full surfaces
|
||||
CGAL::Comparison_result operator() (
|
||||
const Xy_monotone_surface_3& s1,
|
||||
const Xy_monotone_surface_3& s2) const {
|
||||
#if !NDEBUG
|
||||
std::cout << "Compare over face ... " << std::flush;
|
||||
#endif
|
||||
//parent->total_timer.start();
|
||||
//parent->compare_on_face_timer.stare();
|
||||
|
||||
Surface_pair_3 pair =
|
||||
Surface_pair_3::surface_pair_cache()(std::make_pair(s1, s2));
|
||||
|
||||
bool reverse = (s1 == pair.surface2());
|
||||
|
||||
Restricted_cad_3 cad = pair.silhouettes_cut();
|
||||
|
||||
// use z_stack of only existing face
|
||||
Z_stack z_stack = cad.z_stack(cad.faces_begin());
|
||||
|
||||
// and compare lowest z-cells of s1 and s2
|
||||
CGAL::Comparison_result result =
|
||||
_intern_compare(s1, s2, z_stack, reverse);
|
||||
|
||||
// the two surfaces are not allowed to intersect at all
|
||||
CGAL_postcondition(result != CGAL::EQUAL);
|
||||
|
||||
//parent->total_timer.stop();
|
||||
//parent->compare_on_face_timer.stop();
|
||||
|
||||
#if !NDEBUG
|
||||
std::cout << "done." << std::endl;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
/*! Get a Compare_z_at_xy_3 functor object. */
|
||||
Compare_z_at_xy_3
|
||||
compare_z_at_xy_3_object() const
|
||||
{
|
||||
return Compare_z_at_xy_3(this);
|
||||
}
|
||||
|
||||
/*!\brief
|
||||
* Check if the surface s1 is closer/equally distanced/farther
|
||||
* from the envelope with
|
||||
* respect to s2 immediately below the curve c.
|
||||
*/
|
||||
class Compare_z_at_xy_below_3 {
|
||||
protected:
|
||||
const Self *parent;
|
||||
public:
|
||||
Compare_z_at_xy_below_3(const Self* p)
|
||||
: parent(p)
|
||||
{}
|
||||
CGAL::Comparison_result operator() (
|
||||
const X_monotone_curve_2& c,
|
||||
const Xy_monotone_surface_3& s1,
|
||||
const Xy_monotone_surface_3& s2) const {
|
||||
#if !NDEBUG
|
||||
std::cout << "Compare below curve ... " << std::flush;
|
||||
#endif
|
||||
//parent->total_timer.start();
|
||||
//parent->compare_side_timer.start();
|
||||
|
||||
Surface_pair_3 pair =
|
||||
Surface_pair_3::surface_pair_cache()(std::make_pair(s1, s2));
|
||||
|
||||
bool reverse = (s1 == pair.surface2());
|
||||
|
||||
Restricted_cad_3 cad = pair.silhouettes_cut();
|
||||
|
||||
// not invalid, i.e., formed by an intersection and not a boundary
|
||||
#if CGAL_ENVELOPE_3_USE_EDGE_HANDLES
|
||||
typename Info::const_iterator dit = c.data().find(pair);
|
||||
CGAL_assertion(dit != c.data().end());
|
||||
Edge_const_handle eh = dit->second;
|
||||
|
||||
CGAL_assertion(cad.has_cut(eh,s1,s2));
|
||||
|
||||
// locate halfedge of c in cad using stored information
|
||||
// as we want to compare "below" we chose the face incident the
|
||||
// the halfegde of the pair that is directed from RIGHT_TO_LEFT
|
||||
// and compare the lowest z-cells over this face
|
||||
// Remark: This also works when c is vertical!
|
||||
typename Restricted_cad_3::Face_const_handle fh =
|
||||
(eh->direction() == CGAL::ARR_RIGHT_TO_LEFT ?
|
||||
eh->face() : eh->twin()->face());
|
||||
Z_stack z_stack = cad.z_stack(fh);
|
||||
#else
|
||||
typedef Restricted_cad_3_accessor< Restricted_cad_3 > Accessor;
|
||||
Accessor acc(cad);
|
||||
|
||||
// construct point on c
|
||||
Point_2 p = acc.point_in_interior(c);
|
||||
|
||||
// TODO develop strategy to avoid point location!
|
||||
CGAL::Object obj = cad.locate(p);
|
||||
typename Accessor::Halfedge_const_handle heh;
|
||||
CGAL_assertion_code(bool check = )
|
||||
CGAL::assign(heh, obj);
|
||||
CGAL_assertion(check);
|
||||
|
||||
// locate halfedge of c in cad using stored information
|
||||
// as we want to compare "below" we chose the face incident the
|
||||
// the halfegde of the pair that is directed from RIGHT_TO_LEFT
|
||||
// and compare the lowest z-cells over this face
|
||||
// Remark: This also works when c is vertical!
|
||||
typename Restricted_cad_3::Face_const_handle fh =
|
||||
(heh->direction() == CGAL::ARR_RIGHT_TO_LEFT ?
|
||||
heh->face() : heh->twin()->face());
|
||||
Z_stack z_stack = cad.z_stack(fh);
|
||||
#endif
|
||||
|
||||
// and compare lowest z-cells of s1 and s2
|
||||
CGAL::Comparison_result result =
|
||||
_intern_compare(s1, s2, z_stack, reverse);
|
||||
|
||||
// the two surfaces are not allowed to intersect in a
|
||||
// two-dimensional patch
|
||||
CGAL_postcondition(result != CGAL::EQUAL);
|
||||
|
||||
//parent->total_timer.stop();
|
||||
//parent->compare_side_timer.stop();
|
||||
|
||||
#if !NDEBUG
|
||||
std::cout << "done." << std::endl;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/*! Get a Compare_z_at_xy_below_3 functor object. */
|
||||
Compare_z_at_xy_below_3
|
||||
compare_z_at_xy_below_3_object() const
|
||||
{
|
||||
return Compare_z_at_xy_below_3(this);
|
||||
}
|
||||
|
||||
/*!\brief
|
||||
* Check if the surface s1 is closer/equally distanced/farther
|
||||
* from the envelope with
|
||||
* respect to s2 immediately above the curve c.
|
||||
*/
|
||||
class Compare_z_at_xy_above_3 {
|
||||
protected:
|
||||
const Self *parent;
|
||||
public:
|
||||
Compare_z_at_xy_above_3(const Self* p)
|
||||
: parent(p)
|
||||
{}
|
||||
|
||||
CGAL::Comparison_result operator()(
|
||||
const X_monotone_curve_2& c,
|
||||
const Xy_monotone_surface_3& s1,
|
||||
const Xy_monotone_surface_3& s2) {
|
||||
#if !NDEBUG
|
||||
std::cout << "Compare above curve ... " << std::flush;
|
||||
#endif
|
||||
//parent->total_timer.start();
|
||||
//parent->compare_side_timer.start();
|
||||
|
||||
Surface_pair_3 pair =
|
||||
Surface_pair_3::surface_pair_cache()(std::make_pair(s1, s2));
|
||||
|
||||
bool reverse = (s1 == pair.surface2());
|
||||
|
||||
Restricted_cad_3 cad = pair.silhouettes_cut();
|
||||
|
||||
#if CGAL_ENVELOPE_3_USE_EDGE_HANDLES
|
||||
// not invalid, i.e., formed by an intersection and not a boundary
|
||||
typename Info::const_iterator dit = c.data().find(pair);
|
||||
CGAL_assertion(dit != c.data().end());
|
||||
Edge_const_handle eh = dit->second;
|
||||
|
||||
CGAL_assertion(cad.has_cut(eh,s1,s2));
|
||||
|
||||
// locate halfedge of c in cad using stored information
|
||||
// as we want to compare "above" we chose the face incident the
|
||||
// the halfegde of the pair that is directed from LEFT_TO_RIGHT
|
||||
// and compare the lowest z-cells over this face
|
||||
// Remark: This also works when c is vertical!
|
||||
typename Restricted_cad_3::Face_const_handle fh =
|
||||
(eh->direction() == CGAL::ARR_LEFT_TO_RIGHT ?
|
||||
eh->face() : eh->twin()->face());
|
||||
Z_stack z_stack = cad.z_stack(fh);
|
||||
#else
|
||||
typedef Restricted_cad_3_accessor< Restricted_cad_3 > Accessor;
|
||||
Accessor acc(cad);
|
||||
|
||||
// construct point on c
|
||||
Point_2 p = acc.point_in_interior(c);
|
||||
|
||||
// TODO develop strategy to avoid point location!
|
||||
CGAL::Object obj = cad.locate(p);
|
||||
typename Accessor::Halfedge_const_handle heh;
|
||||
CGAL_assertion_code(bool check = )
|
||||
CGAL::assign(heh, obj);
|
||||
CGAL_assertion(check);
|
||||
|
||||
// locate halfedge of c in cad using stored information
|
||||
// as we want to compare "below" we chose the face incident the
|
||||
// the halfegde of the pair that is directed from RIGHT_TO_LEFT
|
||||
// and compare the lowest z-cells over this face
|
||||
// Remark: This also works when c is vertical!
|
||||
typename Restricted_cad_3::Face_const_handle fh =
|
||||
(heh->direction() == CGAL::ARR_LEFT_TO_RIGHT ?
|
||||
heh->face() : heh->twin()->face());
|
||||
Z_stack z_stack = cad.z_stack(fh);
|
||||
#endif
|
||||
// and compare lowest z-cells of s1 and s2
|
||||
CGAL::Comparison_result result =
|
||||
_intern_compare(s1, s2, z_stack, reverse);
|
||||
|
||||
// the two surfaces are not allowed to intersect in a
|
||||
// two-dimensional patch
|
||||
CGAL_postcondition(result != CGAL::EQUAL);
|
||||
|
||||
//parent->total_timer.stop();
|
||||
//parent->compare_side_timer.stop();
|
||||
|
||||
#if !NDEBUG
|
||||
std::cout << "done." << std::endl;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
/*! Get a Compare_z_at_xy_above_3 functor object. */
|
||||
Compare_z_at_xy_above_3
|
||||
compare_z_at_xy_above_3_object() const
|
||||
{
|
||||
return Compare_z_at_xy_above_3(this);
|
||||
}
|
||||
|
||||
}; // Surface_3_envelope_traits
|
||||
|
||||
} // namespace SoX
|
||||
|
||||
#endif // SoX_GAPS_SURFACE_3_ENVELOPE_TRAITS
|
||||
// EOF
|
||||
|
|
@ -0,0 +1,324 @@
|
|||
// ============================================================================
|
||||
//
|
||||
// Copyright (c) 2001-2008 Max-Planck-Institut Saarbruecken (Germany).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of EXACUS (http://www.mpi-inf.mpg.de/projects/EXACUS/);
|
||||
// you may redistribute it under the terms of the Q Public License version 1.0.
|
||||
// See the file LICENSE.QPL distributed with EXACUS.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Library : SoX
|
||||
// File : include/SoX/GAPS/Surface_pair_3.h
|
||||
// SoX_release : $Name: $
|
||||
// Revision : $Revision$
|
||||
// Revision_date : $Date$
|
||||
//
|
||||
// Author(s) : Eric Berberich <eric@mpi-inf.mpg.de>
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
#ifndef SoX_GAPS_SURFACE_PAIR_3_H
|
||||
#define SoX_GAPS_SURFACE_PAIR_3_H 1
|
||||
|
||||
/*!\file SoX/GAPS/Surface_pair_3.h
|
||||
* \brief
|
||||
* definition of \c Surface_pair_3<>
|
||||
*/
|
||||
|
||||
#include <CGAL/config.h>
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include <CGAL/Handle_with_policy.h>
|
||||
|
||||
#include <CGAL/Arrangement_2l/macros.h>
|
||||
#include <CGAL/Arrangement_2l/z_stack_predeclarations.h>
|
||||
#include <CGAL/Arrangement_2l/Restricted_cad_3.h>
|
||||
#include <CGAL/Arrangement_2l/Restricted_cad_3_functors.h>
|
||||
|
||||
namespace SoX {
|
||||
|
||||
namespace Intern {
|
||||
|
||||
template < class SurfaceZAtXyIsolatorTraits >
|
||||
class Surface_pair_3_rep {
|
||||
|
||||
public:
|
||||
//! this instance's template parameter
|
||||
typedef SurfaceZAtXyIsolatorTraits Surface_z_at_xy_isolator_traits;
|
||||
|
||||
SoX_SURFACE_Z_AT_XY_ISOLATOR_TRAITS_SNAP_TYPEDEFS(
|
||||
Surface_z_at_xy_isolator_traits
|
||||
);
|
||||
|
||||
//! this instance itself
|
||||
typedef Surface_pair_3_rep< Surface_z_at_xy_isolator_traits > Self;
|
||||
|
||||
//! type of restricted cad
|
||||
typedef Restricted_cad_3< Surface_z_at_xy_isolator_traits >
|
||||
Restricted_cad_3;
|
||||
|
||||
//! type of creator
|
||||
typedef Create_restricted_cad_3< Surface_z_at_xy_isolator_traits > Creator;
|
||||
|
||||
//! type of creator
|
||||
typedef Overlay_restricted_cad_3< Surface_z_at_xy_isolator_traits >
|
||||
Overlayer;
|
||||
|
||||
public:
|
||||
//!\name Constructors
|
||||
//!@{
|
||||
|
||||
Surface_pair_3_rep(const Surface_3& surface1, const Surface_3& surface2) :
|
||||
_m_surface1(surface1),
|
||||
_m_surface2(surface2) {
|
||||
}
|
||||
|
||||
//!@}
|
||||
|
||||
// TODO make again private:
|
||||
|
||||
//! surface1
|
||||
mutable Surface_3 _m_surface1;
|
||||
|
||||
//! surface2
|
||||
mutable Surface_3 _m_surface2;
|
||||
|
||||
//! restricted cad of surface1
|
||||
mutable boost::optional< Restricted_cad_3 > _m_silhouette1;
|
||||
|
||||
//! restricted cad of surface2
|
||||
mutable boost::optional< Restricted_cad_3 > _m_silhouette2;
|
||||
|
||||
//! restricted cad of surface2
|
||||
mutable boost::optional< Restricted_cad_3 > _m_silhouettes;
|
||||
|
||||
//! restricted cad of intersection
|
||||
mutable boost::optional< Restricted_cad_3 > _m_cut;
|
||||
|
||||
//! restricted cad of first silhouette with x
|
||||
mutable boost::optional< Restricted_cad_3 > _m_silhouette1cut;
|
||||
|
||||
//! restricted cad of second silhouette with x
|
||||
mutable boost::optional< Restricted_cad_3 > _m_silhouette2cut;
|
||||
|
||||
//! restricted cad
|
||||
mutable boost::optional< Restricted_cad_3 > _m_silhouettescut;
|
||||
|
||||
//! friends
|
||||
friend class Surface_pair_3< Surface_z_at_xy_isolator_traits, Self > ;
|
||||
};
|
||||
|
||||
} // namespace Intern
|
||||
|
||||
template <
|
||||
class SurfaceZAtXyIsolatorTraits,
|
||||
class Rep_ = Intern::Surface_pair_3_rep < SurfaceZAtXyIsolatorTraits >
|
||||
>
|
||||
class Surface_pair_3 :
|
||||
public ::CGAL::Handle_with_policy< Rep_ > {
|
||||
|
||||
public:
|
||||
//! this instance's first template parameter
|
||||
typedef SurfaceZAtXyIsolatorTraits Surface_z_at_xy_isolator_traits;
|
||||
|
||||
//! this instance's second template parameter
|
||||
typedef Rep_ Rep;
|
||||
|
||||
SoX_SURFACE_Z_AT_XY_ISOLATOR_TRAITS_SNAP_TYPEDEFS(
|
||||
Surface_z_at_xy_isolator_traits
|
||||
);
|
||||
|
||||
//! type of Base
|
||||
typedef ::CGAL::Handle_with_policy< Rep > Base;
|
||||
|
||||
//! type of restricted cad
|
||||
typedef typename Rep::Restricted_cad_3 Restricted_cad_3;
|
||||
|
||||
//! type of creator
|
||||
typedef typename Rep::Creator Creator;
|
||||
|
||||
//! type of overlayer
|
||||
typedef typename Rep::Overlayer Overlayer;
|
||||
|
||||
//! type of Z_stack
|
||||
typedef typename Restricted_cad_3::Z_stack Z_stack;
|
||||
|
||||
//!\name Constructors
|
||||
//!@{
|
||||
|
||||
Surface_pair_3(const Surface_3& surface1, const Surface_3& surface2) :
|
||||
Base(Rep(surface1, surface2)) {
|
||||
}
|
||||
|
||||
//!@}
|
||||
|
||||
//!\name Access members
|
||||
//!@{
|
||||
|
||||
//! the first surface
|
||||
Surface_3 surface1() const {
|
||||
return this->ptr()->_m_surface1;
|
||||
}
|
||||
|
||||
//! the second surface
|
||||
Surface_3 surface2() const {
|
||||
return this->ptr()->_m_surface2;
|
||||
}
|
||||
|
||||
//!@}
|
||||
|
||||
//!\name Cads
|
||||
//!@{
|
||||
|
||||
//! rscad of first silhouette
|
||||
Restricted_cad_3 silhouette1() const {
|
||||
if (!this->ptr()->_m_silhouette1) {
|
||||
Creator creator; // TODO static??
|
||||
// create rs_cad_3 for surface1
|
||||
this->ptr()->_m_silhouette1 = creator(this->ptr()->_m_surface1);
|
||||
}
|
||||
return *this->ptr()->_m_silhouette1;
|
||||
}
|
||||
|
||||
//! rscad of second silhouette
|
||||
Restricted_cad_3 silhouette2() const {
|
||||
if (!this->ptr()->_m_silhouette2) {
|
||||
Creator creator; // TODO static??
|
||||
// create rs_cad_3 for surface2
|
||||
this->ptr()->_m_silhouette2 = creator(this->ptr()->_m_surface2);
|
||||
}
|
||||
return *this->ptr()->_m_silhouette2;
|
||||
}
|
||||
|
||||
protected:
|
||||
//! rscad of both silhouettes
|
||||
Restricted_cad_3 _silhouettes() const {
|
||||
if (!this->ptr()->_m_silhouettes) {
|
||||
Overlayer overlay; // TODO static?
|
||||
this->ptr()->_m_silhouettes =
|
||||
overlay(silhouette1(), silhouette2());
|
||||
}
|
||||
return *this->ptr()->_m_silhouettes;
|
||||
}
|
||||
|
||||
public:
|
||||
//! rscad of cut
|
||||
Restricted_cad_3 cut() const {
|
||||
if (!this->ptr()->_m_cut) {
|
||||
// create rs_cad_3 for intersection of surface1 and surface2
|
||||
Creator creator; // TODO static??
|
||||
this->ptr()->_m_cut =
|
||||
creator(this->ptr()->_m_surface1, this->ptr()->_m_surface2);
|
||||
}
|
||||
return *this->ptr()->_m_cut;
|
||||
}
|
||||
|
||||
protected:
|
||||
//! rscad of first silhouette with cut
|
||||
Restricted_cad_3 _silhouette1_cut() const {
|
||||
if (!this->ptr()->_m_silhouette1cut) {
|
||||
Overlayer overlay; // TODO static?
|
||||
this->ptr()->_m_silhouette1cut = overlay(silhouette1(), cut());
|
||||
}
|
||||
return *this->ptr()->_m_silhouette1cut;
|
||||
}
|
||||
|
||||
//! rscad of first silhouette with cut
|
||||
Restricted_cad_3 _silhouette2_cut() const {
|
||||
if (!this->ptr()->_m_silhouette2cut) {
|
||||
Overlayer overlay; // TODO static?
|
||||
this->ptr()->_m_silhouette2cut = overlay(silhouette2(), cut());
|
||||
}
|
||||
return *this->ptr()->_m_silhouette2cut;
|
||||
}
|
||||
|
||||
public:
|
||||
//! rscad of first silhouette with cut
|
||||
Restricted_cad_3 silhouettes_cut() const {
|
||||
if (!this->ptr()->_m_silhouettescut) {
|
||||
Overlayer overlay; // TODO static?
|
||||
this->ptr()->_m_silhouettescut = overlay(_silhouettes(), cut());
|
||||
}
|
||||
return *this->ptr()->_m_silhouettescut;
|
||||
}
|
||||
|
||||
//!@}
|
||||
|
||||
//!\name Curves
|
||||
//!@{
|
||||
|
||||
/*!\brief
|
||||
* returns boundary curves and points for a given \c surface in pair
|
||||
*/
|
||||
template < class CurveOutputIterator, class PointOutputIterator >
|
||||
void silhouette_objects(
|
||||
const Surface_3& surface,
|
||||
CurveOutputIterator coi, PointOutputIterator poi) const {
|
||||
|
||||
const Restricted_cad_3& rsc = (surface == this->surface1() ?
|
||||
this->silhouette1() :
|
||||
this->silhouette2());
|
||||
|
||||
for (typename Restricted_cad_3::Vertex_const_iterator vit =
|
||||
rsc.vertices_begin();
|
||||
vit != rsc.vertices_end(); vit++) {
|
||||
if (vit->is_isolated()) {
|
||||
*poi++ = vit->point();
|
||||
}
|
||||
}
|
||||
for (typename Restricted_cad_3::Edge_const_iterator eit =
|
||||
rsc.edges_begin();
|
||||
eit != rsc.edges_end(); eit++) {
|
||||
*coi++ = eit->curve();
|
||||
}
|
||||
}
|
||||
|
||||
/*!\brief
|
||||
* returns projected intersection curves and points of the pair
|
||||
*/
|
||||
template < class CurveOutputIterator, class PointOutputIterator >
|
||||
void cut_objects(
|
||||
CurveOutputIterator coi, PointOutputIterator poi) const {
|
||||
|
||||
const Restricted_cad_3& rsc = this->cut();
|
||||
|
||||
for (typename Restricted_cad_3::Vertex_const_iterator vit =
|
||||
rsc.vertices_begin();
|
||||
vit != rsc.vertices_end(); vit++) {
|
||||
if (vit->is_isolated()) {
|
||||
*poi++ = vit->point();
|
||||
}
|
||||
}
|
||||
for (typename Restricted_cad_3::Edge_const_iterator eit =
|
||||
rsc.edges_begin();
|
||||
eit != rsc.edges_end(); eit++) {
|
||||
*coi++ = eit->curve();
|
||||
}
|
||||
}
|
||||
|
||||
//!@}
|
||||
|
||||
//!\name Z_stack for compare_xyz
|
||||
//!@{
|
||||
|
||||
//! returns z-stack of silhouttes_cut() for \c point
|
||||
Z_stack z_stack_for(const Point_2& point) const {
|
||||
return silhouettes_cut().z_stack_for(point);
|
||||
}
|
||||
|
||||
//!@}
|
||||
};
|
||||
|
||||
} // namespace SoX
|
||||
|
||||
#endif // SoX_GAPS_SURFACE_PAIR_3_H
|
||||
// EOF
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,309 @@
|
|||
// ============================================================================
|
||||
//
|
||||
// Copyright (c) 2001-2008 Max-Planck-Institut Saarbruecken (Germany).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of EXACUS (http://www.mpi-inf.mpg.de/projects/EXACUS/);
|
||||
// you may redistribute it under the terms of the Q Public License version 1.0.
|
||||
// See the file LICENSE.QPL distributed with EXACUS.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Library : SoX
|
||||
// File : include/SoX/GAPS/Z_stack_helpers.h
|
||||
// SoX_release : $Name: $
|
||||
// Revision : $Revision$
|
||||
// Revision_date : $Date$
|
||||
//
|
||||
// Author(s) : Eric Berberich <eric@mpi-inf.mpg.de>
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
/*! \file SoX/GAPS/Z_stack_helpers.h
|
||||
* \brief definition of Z_stack helpers
|
||||
*/
|
||||
|
||||
#ifndef SoX_GAPS_Z_STACK_HELPERS_H
|
||||
#define SoX_GAPS_Z_STACK_HELPERS_H 1
|
||||
|
||||
#include <CGAL/config.h>
|
||||
|
||||
namespace SoX {
|
||||
|
||||
namespace Intern {
|
||||
|
||||
/*!\brief
|
||||
* Functor to determine the order and overlaps of two realrootisolators
|
||||
*/
|
||||
template < class RealRootIsolator >
|
||||
class Refineable_interval_helper {
|
||||
public:
|
||||
//! this instance's template parameter
|
||||
typedef RealRootIsolator Real_root_isolator;
|
||||
|
||||
/*!\brief
|
||||
* Compute order of two refineable intervals given by
|
||||
* pair \c isolator1 and \c i1 and the pair
|
||||
* \c isolator2 and \c i2
|
||||
*
|
||||
* Returns \c CGAL::SMALLER if \c i1 -th interval of \c isolator1
|
||||
* is strictly less then the other, CGAL::LARGER, if strictly
|
||||
* greater, and CGAL::EQUAL in case of an overlap of the two
|
||||
* given intervals.
|
||||
*/
|
||||
::CGAL::Comparison_result overlap_or_order(
|
||||
const Real_root_isolator& isolator1, int i1,
|
||||
const Real_root_isolator& isolator2, int i2) const {
|
||||
|
||||
if (isolator1.right_boundary(i1) < isolator2.left_boundary(i2)) {
|
||||
return CGAL::SMALLER;
|
||||
}
|
||||
if (isolator2.right_boundary(i2) < isolator1.left_boundary(i1)) {
|
||||
return CGAL::LARGER;
|
||||
}
|
||||
return CGAL::EQUAL;
|
||||
}
|
||||
|
||||
/*!\brief
|
||||
* Return whether interval defined by the pair \c isolator1 and \c i1
|
||||
* is included in intervals defined by pair \c isolator2 and \c i2
|
||||
*
|
||||
* \c strict = true indicates a inclusion in interior
|
||||
*/
|
||||
bool is_included(
|
||||
const Real_root_isolator& isolator1, int i1,
|
||||
const Real_root_isolator& isolator2, int i2,
|
||||
bool strict = false) const {
|
||||
|
||||
if (strict) {
|
||||
return
|
||||
(isolator1.left_boundary(i1) > isolator2.left_boundary(i2)) &&
|
||||
(isolator1.right_boundary(i1) < isolator2.right_boundary(i2));
|
||||
}
|
||||
// else
|
||||
return
|
||||
(isolator1.left_boundary(i1) >= isolator2.left_boundary(i2)) &&
|
||||
(isolator1.right_boundary(i1) <= isolator2.right_boundary(i2));
|
||||
}
|
||||
|
||||
|
||||
/*!\brief
|
||||
* computs all pairwise refined overlapping id
|
||||
*
|
||||
* value_type of OutputIterator is std::pair< int, int >
|
||||
*/
|
||||
template < class OutputIterator >
|
||||
OutputIterator refined_overlaps(
|
||||
const Real_root_isolator& isolator1,
|
||||
const Real_root_isolator& isolator2,
|
||||
OutputIterator oi
|
||||
) const {
|
||||
|
||||
// obtain minimal number of overlaps, i.e., all each interval
|
||||
// of one isolator overlaps with at most one interval of the
|
||||
// other isolator
|
||||
|
||||
const int num1 = isolator1.number_of_real_roots();
|
||||
const int num2 = isolator2.number_of_real_roots();
|
||||
CGAL_precondition(num1 > 0);
|
||||
CGAL_precondition(num2 > 0);
|
||||
|
||||
// TASK cache result for two isolators?
|
||||
|
||||
// compute all overlaps
|
||||
|
||||
std::list< int > empty;
|
||||
|
||||
std::vector< std::list< int > > ovl1(num1, empty);
|
||||
std::vector< std::list< int > > ovl2(num2, empty);
|
||||
|
||||
int i1 = 0;
|
||||
int i2 = 0;
|
||||
while (true) {
|
||||
if (i1 == num1) {
|
||||
// no further overlaps possible
|
||||
break;
|
||||
}
|
||||
if (i2 == num2) {
|
||||
// no further overlaps possible
|
||||
break;
|
||||
}
|
||||
CGAL::Comparison_result res =
|
||||
this->overlap_or_order(isolator1, i1, isolator2, i2);
|
||||
|
||||
switch (res) {
|
||||
case CGAL::SMALLER:
|
||||
//std::cout << "SM" << std::endl;
|
||||
i1++;
|
||||
break;
|
||||
case CGAL::EQUAL:
|
||||
//std::cout << "EQUAL " << i1 << " " << i2 << std::endl;
|
||||
ovl1[i1].push_back(i2);
|
||||
ovl2[i2].push_back(i1);
|
||||
if (isolator1.right_boundary(i1) <=
|
||||
isolator2.right_boundary(i2)) {
|
||||
i1++;
|
||||
} else if (isolator1.right_boundary(i1) >=
|
||||
isolator2.right_boundary(i2)) {
|
||||
i2++;
|
||||
}
|
||||
break;
|
||||
case CGAL::LARGER:
|
||||
//std::cout << "LA" << std::endl;
|
||||
i2++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i1 = 0; i1 < num1; i1++) {
|
||||
switch (ovl1[i1].size()) {
|
||||
case 0:
|
||||
// nothing to do
|
||||
case 1:
|
||||
// is also fine
|
||||
break;
|
||||
default:
|
||||
// size is greater than 1, refine against all found interval
|
||||
do {
|
||||
std::list< typename std::list< int >::iterator > erase;
|
||||
for (typename std::list< int >::iterator it =
|
||||
ovl1[i1].begin();
|
||||
it != ovl1[i1].end(); it++) {
|
||||
isolator1.refine_interval(i1);
|
||||
isolator2.refine_interval(*it);
|
||||
if (this->overlap_or_order(isolator1, i1,
|
||||
isolator2, *it) !=
|
||||
CGAL::EQUAL) {
|
||||
erase.push_back(it);
|
||||
}
|
||||
}
|
||||
for (typename
|
||||
std::list<
|
||||
typename std::list< int >::iterator >::iterator
|
||||
eit = erase.begin(); eit != erase.end(); eit++) {
|
||||
ovl2[*(*eit)].remove(i1);
|
||||
ovl1[i1].erase(*eit);
|
||||
}
|
||||
} while (static_cast< int >(ovl1[i1].size()) > 1);
|
||||
}
|
||||
}
|
||||
|
||||
for (i2 = 0; i2 < num2; i2++) {
|
||||
switch (ovl2[i2].size()) {
|
||||
case 0:
|
||||
// nothing to do
|
||||
case 1:
|
||||
// is also fine
|
||||
break;
|
||||
default:
|
||||
// size is greater than 1, refine against all found interval
|
||||
do {
|
||||
std::list< typename std::list< int >::iterator > erase;
|
||||
for (typename std::list< int >::iterator it =
|
||||
ovl2[i2].begin();
|
||||
it != ovl2[i2].end(); it++) {
|
||||
isolator1.refine_interval(*it);
|
||||
isolator2.refine_interval(i2);
|
||||
if (this->overlap_or_order(isolator1, *it,
|
||||
isolator2, i2) !=
|
||||
CGAL::EQUAL) {
|
||||
erase.push_back(it);
|
||||
}
|
||||
}
|
||||
for (typename
|
||||
std::list< typename std::list< int >::iterator >::
|
||||
iterator
|
||||
eit = erase.begin(); eit != erase.end(); eit++) {
|
||||
ovl1[*(*eit)].remove(i2);
|
||||
ovl2[i2].erase(*eit);
|
||||
}
|
||||
} while (static_cast< int >(ovl2[i2].size()) > 1);
|
||||
}
|
||||
}
|
||||
|
||||
for (i1 = 0; i1 < num1; i1++) {
|
||||
switch (ovl1[i1].size()) {
|
||||
case 0:
|
||||
// nothing to do
|
||||
break;
|
||||
case 1: {
|
||||
// check whether it exist in other
|
||||
int i2 = ovl1[i1].front();
|
||||
CGAL_assertion(static_cast< int >(ovl2[i2].size()) == 1);
|
||||
CGAL_assertion(ovl2[i2].front() == i1);
|
||||
*oi++ = std::make_pair(i1,i2);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
CGAL_error_msg("should not occur");
|
||||
}
|
||||
}
|
||||
|
||||
return oi;
|
||||
}
|
||||
|
||||
//! returns the unique overlapping pair of intervals of two isolators
|
||||
template< class InputIterator >
|
||||
std::pair< int, int > unique_overlap(
|
||||
const Real_root_isolator& isolator1,
|
||||
const Real_root_isolator& isolator2,
|
||||
InputIterator begin,
|
||||
InputIterator end
|
||||
) const {
|
||||
|
||||
// obtain the unique overlap by further refinement, as we know
|
||||
// from the external that is is exactly one overlap
|
||||
std::list< std::pair< int, int > > overlaps;
|
||||
std::copy(begin,end, std::back_inserter(overlaps));
|
||||
|
||||
CGAL_precondition(static_cast< int >(overlaps.size()) > 0);
|
||||
|
||||
while (static_cast< int >(overlaps.size()) > 1) {
|
||||
std::list< typename std::list< std::pair< int, int > >::iterator >
|
||||
erase;
|
||||
|
||||
// for each overlapping pair
|
||||
for (typename std::list< std::pair< int, int > >::iterator
|
||||
it = overlaps.begin(); it != overlaps.end(); it++) {
|
||||
// refine overlapping intervals
|
||||
isolator1.refine_interval(it->first);
|
||||
isolator2.refine_interval(it->second);
|
||||
|
||||
// and remove non-overlapping pairs
|
||||
if (this->overlap_or_order(
|
||||
isolator1, it->first, isolator2, it->second
|
||||
) != CGAL::EQUAL) {
|
||||
erase.push_back(it);
|
||||
}
|
||||
}
|
||||
for (typename
|
||||
std::list< typename std::list<
|
||||
std::pair< int, int > >::iterator >::iterator it =
|
||||
erase.begin(); it != erase.end(); it++) {
|
||||
overlaps.erase(*it);
|
||||
}
|
||||
}
|
||||
CGAL_assertion(static_cast< int >(overlaps.size()) == 1);
|
||||
|
||||
CGAL_postcondition(overlaps.begin()->first >= 0);
|
||||
CGAL_postcondition(overlaps.begin()->second >= 0);
|
||||
return std::make_pair(
|
||||
overlaps.begin()->first, overlaps.begin()->second
|
||||
);
|
||||
}
|
||||
|
||||
}; // Refineable_interval_helper
|
||||
|
||||
|
||||
} // namespace Intern
|
||||
|
||||
} // namespace SoX
|
||||
|
||||
#endif // SoX_GAPS_Z_STACK_HELPERS_H
|
||||
// EOF
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
// ============================================================================
|
||||
//
|
||||
// Copyright (c) 2001-2008 Max-Planck-Institut Saarbruecken (Germany).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of EXACUS (http://www.mpi-inf.mpg.de/projects/EXACUS/);
|
||||
// you may redistribute it under the terms of the Q Public License version 1.0.
|
||||
// See the file LICENSE.QPL distributed with EXACUS.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Library : SoX
|
||||
// File : include/SoX/GAPS/macros.h
|
||||
// SoX_release : $Name: $
|
||||
// Revision : $Revision$
|
||||
// Revision_date : $Date$
|
||||
//
|
||||
// Author(s) : Eric Berberich <eric@mpi-inf.mpg.de>
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
/*! \file SoX/GAPS/macros.h
|
||||
\brief some basic macro declarations
|
||||
*/
|
||||
|
||||
#ifndef SoX_GAPS_MACROS_H
|
||||
#define SoX_GAPS_MACROS_H 1
|
||||
|
||||
#include <CGAL/config.h>
|
||||
|
||||
// TASK document
|
||||
#define SoX_SURFACE_Z_AT_XY_ISOLATOR_TRAITS_SNAP_TYPEDEFS(Traits) \
|
||||
typedef typename Traits::Surface_3 Surface_3; \
|
||||
typedef typename Traits::Arrangement_traits_2 Arrangement_traits_2; \
|
||||
typedef typename Arrangement_traits_2::Curve_kernel_2 Curve_kernel_2; \
|
||||
typedef typename Traits::Z_at_xy_isolator Z_at_xy_isolator;\
|
||||
typedef typename Traits::Polynomial_3 Polynomial_3; \
|
||||
typedef typename Traits::Polynomial_2 Polynomial_2; \
|
||||
typedef typename Curve_kernel_2::Curve_analysis_2 Curve_analysis_2; \
|
||||
typedef typename Traits::Point_2 Point_2; \
|
||||
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; \
|
||||
// end #define SoX_SURFACE_Z_AT_XY_ISOLATOR_TRAITS_SNAP_TYPEDEFS(Traits)
|
||||
|
||||
|
||||
#endif // SoX_GAPS_MACROS_H
|
||||
// EOF
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
// ============================================================================
|
||||
//
|
||||
// Copyright (c) 2001-2008 Max-Planck-Institut Saarbruecken (Germany).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of EXACUS (http://www.mpi-inf.mpg.de/projects/EXACUS/);
|
||||
// you may redistribute it under the terms of the Q Public License version 1.0.
|
||||
// See the file LICENSE.QPL distributed with EXACUS.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Library : SoX
|
||||
// File : include/SoX/GAPS/z_stack_predclarations.h
|
||||
// SoX_release : $Name: $
|
||||
// Revision : $Revision$
|
||||
// Revision_date : $Date$
|
||||
//
|
||||
// Author(s) : Eric Berberich <eric@mpi-inf.mpg.de>
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
/*! \file SoX/GAPS/z_stack_predeclarations.h
|
||||
\brief contains all required pre-declarations
|
||||
*/
|
||||
|
||||
#ifndef SoX_GAPS_Z_STACK_PREDECLARATIONS_H
|
||||
#define SoX_GAPS_Z_STACK_PREDECLARATIONS_H 1
|
||||
|
||||
#include <CGAL/config.h>
|
||||
|
||||
namespace SoX {
|
||||
|
||||
// pre-declaration
|
||||
template < class SurfaceZAtXyIsolatorTraits >
|
||||
class Restricted_cad_3;
|
||||
|
||||
// pre-declaration
|
||||
template < class SurfaceZAtXyIsolatorTraits >
|
||||
class P_dcel_info;
|
||||
|
||||
// pre-declaration
|
||||
template < class SurfaceZAtXyIsolatorTraits, class DcelData >
|
||||
class Z_stack;
|
||||
|
||||
// pre-declaration
|
||||
template < class SurfaceZAtXyIsolatorTraits >
|
||||
class Create_restricted_cad_3;
|
||||
|
||||
// pre-declaration
|
||||
template < class SurfaceZAtXyIsolatorTraits >
|
||||
class Overlay_restricted_cad_3;
|
||||
|
||||
// pre-declaration
|
||||
template < class Arrangement_2_ >
|
||||
class Arr_p_dcel_info_overlay_traits;
|
||||
|
||||
// pre-declaration
|
||||
template < class SurfaceZAtXyIsolatorTraits, class Rep_ >
|
||||
class Surface_pair_3;
|
||||
|
||||
namespace Intern {
|
||||
|
||||
// pre-declaration
|
||||
template < class SurfaceZAtXyIsolatorTraits >
|
||||
class Restricted_cad_3_cache;
|
||||
|
||||
// pre-declaration
|
||||
template < class SurfaceZAtXyIsolatorTraits, class DcelData >
|
||||
class Z_cell;
|
||||
|
||||
} // namespace Intern
|
||||
|
||||
} // namespace SoX
|
||||
|
||||
#endif // SoX_GAPS_Z_STACK_PREDECLARATIONS_H
|
||||
// EOF
|
||||
Loading…
Reference in New Issue