我一直在研究CGAL,並且在嘗試定義滿足我需要的內核時遇到了問題。CGAL過濾的內核沒有延遲評估
我需要一個線程安全的內核,但同時我想存儲精確的座標。
如果我的理解CGAL文檔正確:
- 的exact_predicates_inexact_constructions_kernel是線程安全的,但它存儲的座標爲雙值。
- exact_predicates_exact_constructions_kernel存儲確切的座標,但不是線程安全的(因爲懶惰的數字類型)。
- CGAL :: Simple_cartesian是線程安全的,並精確地存儲座標。但是,對於我的應用程序來說,速度要慢很多
我基本斷定我需要這樣的東西:
CGAL::Filtered_kernel<CGAL::Simple_cartesian<mpq_class>>
(一個是採用過濾區間運算性能內核,存儲的精確座標(當過濾器發生故障將被使用)和不使用懶數字類型)。
我認爲這個內核比exact_predicates_exact_constructions_kernel慢,但它比線程安全,比非過濾內核快得多。 (此外,我認爲懶數字類型對於我的應用程序來說不會那麼有用,因爲我想要輸出確切的座標,因此它們必須在某個時刻計算 - 也就是我需要的唯一「優化」是快速過濾的謂詞)
問題是:我試圖用這個內核編譯測試應用程序,編譯總是失敗。是否有一個原因,我爲什麼不能創建一個不僅保留浮點間隔而且還保存精確座標的過濾內核?
PS:我在Linux上使用CGAL 4.10
謝謝!
更新: 最小的例子,失敗:
#include <CGAL/gmpxx.h> //needed to use mpq_class as the field type
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Filtered_kernel.h>
#include <CGAL/Lazy_kernel.h>
//typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel; //works...
//typedef CGAL::Filtered_kernel<CGAL::Simple_cartesian<double>> Kernel; //works...
//typedef CGAL::Simple_cartesian<mpq_class> Kernel; //works!
//typedef CGAL::Filtered_kernel<CGAL::Simple_cartesian<CGAL::Gmpq>> Kernel; //works! (but Gmpq is not thread safe, while mpq_class is)
typedef CGAL::Filtered_kernel<CGAL::Simple_cartesian<mpq_class>> Kernel;
typedef Kernel::Point_3 Point_3;
int main() {
Point_3 a(0,0,0);
Point_3 b(1,0,0);
Point_3 c(0,1,0);
Point_3 d(1,1,1);
//The code compiles if I remove the line below
CGAL::Orientation orientationP0Triangle = CGAL::orientation(a,b,c,d);
}
錯誤消息:
In file included from /usr/local/include/CGAL/Cartesian_converter.h:35:0,
from /usr/local/include/CGAL/Filtered_kernel.h:27,
from /usr/local/include/CGAL/Exact_predicates_inexact_constructions_kernel.h:29,
from cgalSimpleExample.cpp:2:
/usr/local/include/CGAL/NT_converter.h: In instantiation of ‘NT2 CGAL::NT_converter<NT1, NT2>::operator()(const NT1&) const [with NT1 = __gmp_expr<__mpq_struct [1], __mpq_struct [1]>; NT2 = CGAL::Gmpq]’:
/usr/local/include/CGAL/Cartesian_converter.h:293:45: required from ‘typename K2::Point_3 CGAL::Cartesian_converter<K1, K2, Converter>::operator()(const typename K1::Point_3&) const [with K1 = CGAL::Type_equality_wrapper<CGAL::Cartesian_base_no_ref_count<__gmp_expr<__mpq_struct [1], __mpq_struct [1]>, CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> > > >, CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> > > >; K2 = CGAL::Simple_cartesian<CGAL::Gmpq>; Converter = CGAL::NT_converter<__gmp_expr<__mpq_struct [1], __mpq_struct [1]>, CGAL::Gmpq>; typename K2::Point_3 = CGAL::Point_3<CGAL::Simple_cartesian<CGAL::Gmpq> >; typename K1::Point_3 = CGAL::Point_3<CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> > > >]’
/usr/local/include/CGAL/Filtered_predicate.h:175:27: required from ‘CGAL::Filtered_predicate<EP, AP, C2E, C2A, Protection>::result_type CGAL::Filtered_predicate<EP, AP, C2E, C2A, Protection>::operator()(const Args& ...) const [with Args = {CGAL::Point_3<CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> >, true> >, CGAL::Point_3<CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> >, true> >, CGAL::Point_3<CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> >, true> >, CGAL::Point_3<CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> >, true> >}; EP = CGAL::CartesianKernelFunctors::Orientation_3<CGAL::Simple_cartesian<CGAL::Gmpq> >; AP = CGAL::CartesianKernelFunctors::Orientation_3<CGAL::Simple_cartesian<CGAL::Interval_nt<false> > >; C2E = CGAL::Cartesian_converter<CGAL::Type_equality_wrapper<CGAL::Cartesian_base_no_ref_count<__gmp_expr<__mpq_struct [1], __mpq_struct [1]>, CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> > > >, CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> > > >, CGAL::Simple_cartesian<CGAL::Gmpq>, CGAL::NT_converter<__gmp_expr<__mpq_struct [1], __mpq_struct [1]>, CGAL::Gmpq> >; C2A = CGAL::Cartesian_converter<CGAL::Type_equality_wrapper<CGAL::Cartesian_base_no_ref_count<__gmp_expr<__mpq_struct [1], __mpq_struct [1]>, CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> > > >, CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> > > >, CGAL::Simple_cartesian<CGAL::Interval_nt<false> >, CGAL::NT_converter<__gmp_expr<__mpq_struct [1], __mpq_struct [1]>, CGAL::Interval_nt<false> > >; bool Protection = true; CGAL::Filtered_predicate<EP, AP, C2E, C2A, Protection>::result_type = CGAL::Sign]’
/usr/local/include/CGAL/internal/Static_filters/Orientation_3.h:170:41: required from ‘CGAL::internal::Static_filters_predicates::Orientation_3<K_base>::result_type CGAL::internal::Static_filters_predicates::Orientation_3<K_base>::operator()(const Point_3&, const Point_3&, const Point_3&, const Point_3&) const [with K_base = CGAL::Filtered_kernel_base<CGAL::Type_equality_wrapper<CGAL::Cartesian_base_no_ref_count<__gmp_expr<__mpq_struct [1], __mpq_struct [1]>, CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> > > >, CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> > > > >; CGAL::internal::Static_filters_predicates::Orientation_3<K_base>::result_type = CGAL::Sign; CGAL::internal::Static_filters_predicates::Orientation_3<K_base>::Point_3 = CGAL::Point_3<CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> > > >]’
/usr/local/include/CGAL/Kernel/global_functions_internal_3.h:860:45: required from ‘typename K::Orientation CGAL::internal::orientation(const typename K::Point_3&, const typename K::Point_3&, const typename K::Point_3&, const typename K::Point_3&, const K&) [with K = CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> > >; typename K::Orientation = CGAL::Sign; typename K::Point_3 = CGAL::Point_3<CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> > > >]’
/usr/local/include/CGAL/Kernel/global_functions_3.h:1047:47: required from ‘typename K::Orientation CGAL::orientation(const CGAL::Point_3<R>&, const CGAL::Point_3<R>&, const CGAL::Point_3<R>&, const CGAL::Point_3<R>&) [with K = CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> > >; typename K::Orientation = CGAL::Sign]’
cgalSimpleExample.cpp:19:69: required from here
/usr/local/include/CGAL/NT_converter.h:41:21: error: no matching function for call to ‘CGAL::Gmpq::Gmpq(const __gmp_expr<__mpq_struct [1], __mpq_struct [1]>&)’
return NT2(a);
^
/usr/local/include/CGAL/NT_converter.h:41:21: note: candidates are:
In file included from /usr/local/include/CGAL/Gmp_coercion_traits.h:33:0,
from /usr/local/include/CGAL/Gmpz.h:33,
from /usr/local/include/CGAL/internal/Exact_type_selector.h:36,
from /usr/local/include/CGAL/Filtered_kernel.h:35,
from /usr/local/include/CGAL/Exact_predicates_inexact_constructions_kernel.h:29,
from cgalSimpleExample.cpp:2:
/usr/local/include/CGAL/GMP/Gmpq_type.h:193:3: note: CGAL::Gmpq::Gmpq(const string&, int)
Gmpq(const std::string& str, int base = 10)
^
/usr/local/include/CGAL/GMP/Gmpq_type.h:193:3: note: no known conversion for argument 1 from ‘const __gmp_expr<__mpq_struct [1], __mpq_struct [1]>’ to ‘const string& {aka const std::basic_string<char>&}’
/usr/local/include/CGAL/GMP/Gmpq_type.h:174:3: note: CGAL::Gmpq::Gmpq(const CGAL::Gmpfr&)
Gmpq(const Gmpfr &f)
^
/usr/local/include/CGAL/GMP/Gmpq_type.h:174:3: note: no known conversion for argument 1 from ‘const __gmp_expr<__mpq_struct [1], __mpq_struct [1]>’ to ‘const CGAL::Gmpfr&’
/usr/local/include/CGAL/GMP/Gmpq_type.h:168:3: note: CGAL::Gmpq::Gmpq(double)
Gmpq(double d)
^
/usr/local/include/CGAL/GMP/Gmpq_type.h:168:3: note: no known conversion for argument 1 from ‘const __gmp_expr<__mpq_struct [1], __mpq_struct [1]>’ to ‘double’
/usr/local/include/CGAL/GMP/Gmpq_type.h:161:3: note: CGAL::Gmpq::Gmpq(const CGAL::Gmpz&, const CGAL::Gmpz&)
Gmpq(const Gmpz& n, const Gmpz& d)
^
/usr/local/include/CGAL/GMP/Gmpq_type.h:161:3: note: candidate expects 2 arguments, 1 provided
/usr/local/include/CGAL/GMP/Gmpq_type.h:155:3: note: CGAL::Gmpq::Gmpq(long unsigned int, long unsigned int)
Gmpq(unsigned long n, unsigned long d)
^
/usr/local/include/CGAL/GMP/Gmpq_type.h:155:3: note: candidate expects 2 arguments, 1 provided
/usr/local/include/CGAL/GMP/Gmpq_type.h:149:3: note: CGAL::Gmpq::Gmpq(long int, long unsigned int)
Gmpq(signed long n, unsigned long d)
^
/usr/local/include/CGAL/GMP/Gmpq_type.h:149:3: note: candidate expects 2 arguments, 1 provided
/usr/local/include/CGAL/GMP/Gmpq_type.h:139:3: note: CGAL::Gmpq::Gmpq(int, int)
Gmpq(int n, int d)
^
/usr/local/include/CGAL/GMP/Gmpq_type.h:139:3: note: candidate expects 2 arguments, 1 provided
/usr/local/include/CGAL/GMP/Gmpq_type.h:136:3: note: CGAL::Gmpq::Gmpq(const CGAL::Gmpz&)
Gmpq(const Gmpz& n)
^
/usr/local/include/CGAL/GMP/Gmpq_type.h:136:3: note: no known conversion for argument 1 from ‘const __gmp_expr<__mpq_struct [1], __mpq_struct [1]>’ to ‘const CGAL::Gmpz&’
/usr/local/include/CGAL/GMP/Gmpq_type.h:124:3: note: CGAL::Gmpq::Gmpq(long long int)
Gmpq(long long n)
^
/usr/local/include/CGAL/GMP/Gmpq_type.h:124:3: note: no known conversion for argument 1 from ‘const __gmp_expr<__mpq_struct [1], __mpq_struct [1]>’ to ‘long long int’
/usr/local/include/CGAL/GMP/Gmpq_type.h:116:3: note: CGAL::Gmpq::Gmpq(long long unsigned int)
Gmpq(unsigned long long n)
^
/usr/local/include/CGAL/GMP/Gmpq_type.h:116:3: note: no known conversion for argument 1 from ‘const __gmp_expr<__mpq_struct [1], __mpq_struct [1]>’ to ‘long long unsigned int’
/usr/local/include/CGAL/GMP/Gmpq_type.h:104:3: note: CGAL::Gmpq::Gmpq(long unsigned int)
Gmpq(unsigned long n)
^
/usr/local/include/CGAL/GMP/Gmpq_type.h:104:3: note: no known conversion for argument 1 from ‘const __gmp_expr<__mpq_struct [1], __mpq_struct [1]>’ to ‘long unsigned int’
/usr/local/include/CGAL/GMP/Gmpq_type.h:101:3: note: CGAL::Gmpq::Gmpq(long int)
Gmpq(long n)
^
/usr/local/include/CGAL/GMP/Gmpq_type.h:101:3: note: no known conversion for argument 1 from ‘const __gmp_expr<__mpq_struct [1], __mpq_struct [1]>’ to ‘long int’
/usr/local/include/CGAL/GMP/Gmpq_type.h:98:3: note: CGAL::Gmpq::Gmpq(unsigned int)
Gmpq(unsigned int n)
^
/usr/local/include/CGAL/GMP/Gmpq_type.h:98:3: note: no known conversion for argument 1 from ‘const __gmp_expr<__mpq_struct [1], __mpq_struct [1]>’ to ‘unsigned int’
/usr/local/include/CGAL/GMP/Gmpq_type.h:95:3: note: CGAL::Gmpq::Gmpq(int)
Gmpq(int n)
^
/usr/local/include/CGAL/GMP/Gmpq_type.h:95:3: note: no known conversion for argument 1 from ‘const __gmp_expr<__mpq_struct [1], __mpq_struct [1]>’ to ‘int’
/usr/local/include/CGAL/GMP/Gmpq_type.h:92:3: note: CGAL::Gmpq::Gmpq(const __mpq_struct*)
Gmpq(const mpq_t q)
^
/usr/local/include/CGAL/GMP/Gmpq_type.h:92:3: note: no known conversion for argument 1 from ‘const __gmp_expr<__mpq_struct [1], __mpq_struct [1]>’ to ‘const __mpq_struct*’
/usr/local/include/CGAL/GMP/Gmpq_type.h:90:3: note: CGAL::Gmpq::Gmpq()
Gmpq() {}
^
/usr/local/include/CGAL/GMP/Gmpq_type.h:90:3: note: candidate expects 0 arguments, 1 provided
/usr/local/include/CGAL/GMP/Gmpq_type.h:69:7: note: CGAL::Gmpq::Gmpq(const CGAL::Gmpq&)
class Gmpq
^
/usr/local/include/CGAL/GMP/Gmpq_type.h:69:7: note: no known conversion for argument 1 from ‘const __gmp_expr<__mpq_struct [1], __mpq_struct [1]>’ to ‘const CGAL::Gmpq&’
在這裏複製編譯器錯誤信息會很有幫助。 –
謝謝。我用最低限度的例子和錯誤信息編輯了問題。 – Salles
我可以重現它。我通過確保GMPXX在安裝時被CMake發現來修復它。這會導致在中啓用#define CGAL_USE GMPXX,從而使Filtered_kernel在此處工作。 –