diff --git a/binding.gyp b/binding.gyp index fadf4af..d8b83ed 100644 --- a/binding.gyp +++ b/binding.gyp @@ -5,7 +5,7 @@ 'sources': [ 'src/cgal.cc', - # 'src/AffTransformation2.cc', + 'src/AffTransformation2.cc', # 'src/Arrangement2.cc', # 'src/Arrangement2Face.cc', # 'src/Arrangement2Halfedge.cc', diff --git a/spec/Point2.spec.js b/spec/Point2.spec.js index b48cbcb..bbea87d 100644 --- a/spec/Point2.spec.js +++ b/spec/Point2.spec.js @@ -32,11 +32,11 @@ describe("CGAL.Point2", function() { expect(p.x()).toEqual(q.x()); }); - // it("should be transformable", function() { - // var p = new CGAL.Point2([1,2]); - // var q = p.transform([1, 0, 3, 0, 1, 3]); - // expect(q instanceof CGAL.Point2).toBeTruthy(); - // expect(q.x()).toEqual(4); - // expect(q.y()).toEqual(5); - // }); + it("should be transformable", function() { + var p = new CGAL.Point2([1,2]); + var q = p.transform([1, 0, 3, 0, 1, 3]); + expect(q instanceof CGAL.Point2).toBeTruthy(); + expect(q.x()).toEqual(4); + expect(q.y()).toEqual(5); + }); }); diff --git a/spec/Polygon2.spec.js b/spec/Polygon2.spec.js index 495a3b6..b89d9fa 100644 --- a/spec/Polygon2.spec.js +++ b/spec/Polygon2.spec.js @@ -94,10 +94,10 @@ describe("CGAL.Polygon2", function() { expect(p3.area()).toBeCloseTo(-1.0, 4); }); -// it ("should support transformation", function() { -// var p1 = new CGAL.Polygon2([[0, 0], [1, 0], [1, 1], [0, 1]]); -// var p2; -// expect(function() {p2 = CGAL.Polygon2.transform([1, 0, 3, 0, 1, 3], p1);}).not.toThrow(); -// expect(p2.toPOD(false)[0]).toEqual([3,3]); -// }); + it ("should support transformation", function() { + var p1 = new CGAL.Polygon2([[0, 0], [1, 0], [1, 1], [0, 1]]); + var p2; + expect(function() {p2 = CGAL.Polygon2.transform([1, 0, 3, 0, 1, 3], p1);}).not.toThrow(); + expect(p2.toPOD(false)[0]).toEqual([3,3]); + }); }); diff --git a/src/AffTransformation2.cc b/src/AffTransformation2.cc index 6b7496d..8bb18d6 100644 --- a/src/AffTransformation2.cc +++ b/src/AffTransformation2.cc @@ -2,65 +2,60 @@ #include "Direction2.h" #include "cgal_args.h" -using namespace v8; -using namespace node; using namespace std; +AffTransformation2::AffTransformation2(Napi::CallbackInfo const& info) +: CGALWrapper(info) +{ +} + + const char *AffTransformation2::Name = "AffTransformation2"; -void AffTransformation2::RegisterMethods(v8::Isolate *isolate) +void AffTransformation2::AddProperties(std::vector& properties) { } -bool AffTransformation2::ParseArg(Isolate *isolate, Local arg, Aff_transformation_2 &receiver) +bool AffTransformation2::ParseArg(Napi::Env env, Napi::Value arg, Aff_transformation_2& receiver) { - HandleScope scope(isolate); - Local context = isolate->GetCurrentContext(); - - if (sConstructorTemplate.Get(isolate)->HasInstance(arg)) { - receiver = ExtractWrapped(Local::Cast(arg)); + if (arg.IsObject() && arg.As().InstanceOf(sConstructor.Value())) { + receiver = Unwrap(arg.As())->mWrapped; return true; } - if (arg->IsArray()) { - Local inits = Local::Cast(arg); - - if (inits->Length() >= 6 && inits->Length() <= 7) { + if (arg.IsArray()) { + Napi::Array inits = arg.As(); + if (inits.Length() >= 6 && inits.Length() <= 7) { K::RT m00, m01, m02, m10, m11, m12, hw(1); - if (::ParseArg(isolate, inits->Get(context, 0).ToLocalChecked(), m00) && - ::ParseArg(isolate, inits->Get(context, 1).ToLocalChecked(), m01) && - ::ParseArg(isolate, inits->Get(context, 2).ToLocalChecked(), m02) && - ::ParseArg(isolate, inits->Get(context, 3).ToLocalChecked(), m10) && - ::ParseArg(isolate, inits->Get(context, 4).ToLocalChecked(), m11) && - ::ParseArg(isolate, inits->Get(context, 5).ToLocalChecked(), m12)) + if (::ParseNumberArg(env, inits[0u], m00) && + ::ParseNumberArg(env, inits[1], m01) && + ::ParseNumberArg(env, inits[2], m02) && + ::ParseNumberArg(env, inits[3], m10) && + ::ParseNumberArg(env, inits[4], m11) && + ::ParseNumberArg(env, inits[5], m12)) { - if ((inits->Length() == 7) && !::ParseArg(isolate, inits->Get(context, 6).ToLocalChecked(), hw)) + if ((inits.Length() == 7) && !::ParseNumberArg(env, inits[6], hw)) return false; - receiver = Aff_transformation_2(m00, m01, m02, m10, m11, m12, hw); return true; } - } - if (inits->Length() >= 2 && inits->Length() <= 3) { - + if (inits.Length() >= 2 && inits.Length() <= 3) { Direction_2 dir; K::RT num, den(1); - if (Direction2::ParseArg(isolate, inits->Get(context, 0).ToLocalChecked(), dir) && - ::ParseArg(isolate, inits->Get(context, 1).ToLocalChecked(), num)) + if (Direction2::ParseArg(env, inits[0u], dir) && + ::ParseNumberArg(env, inits[1], num)) { - if ((inits->Length() == 3) && !::ParseArg(isolate, inits->Get(context, 2).ToLocalChecked(), den)) + if ((inits.Length() == 3) && !::ParseNumberArg(env, inits[2], den)) return false; - receiver = Aff_transformation_2(Rotation(), dir, num, den); return true; } - } } @@ -69,35 +64,27 @@ bool AffTransformation2::ParseArg(Isolate *isolate, Local arg, Aff_transf } -Local AffTransformation2::ToPOD(Isolate *isolate, const Aff_transformation_2 &aff, bool precise) +Napi::Value AffTransformation2::ToPOD(Napi::Env env, Aff_transformation_2 const& aff, bool precise) { - EscapableHandleScope scope(isolate); - Local context = isolate->GetCurrentContext(); - Local array = Array::New(isolate, 7); - - try { - for(int i=0; i<7; ++i) { - int r = (i == 6) ? 2 : i/3; - int c = (i == 6) ? 2 : i%3; - K::RT a = aff.hm(r, c); - if (precise) { - ostringstream str; + Napi::Array array = Napi::Array::New(env, 7); + + for(int i=0; i<7; ++i) { + int r = (i == 6) ? 2 : i/3; + int c = (i == 6) ? 2 : i%3; + K::RT a = aff.hm(r, c); + if (precise) { + ostringstream str; #ifdef CGAL_USE_EPECK - str << a.exact(); + str << a.exact(); #else - str << a; + str << a; #endif - array->Set(context, i, String::NewFromUtf8(isolate, str.str().c_str(), NewStringType::kNormal).ToLocalChecked()); - } else { - array->Set(context, i, Number::New(isolate, CGAL::to_double(a))); - } + array.Set(i, str.str()); + } else { + array.Set(i, CGAL::to_double(a)); } } - catch (const exception &e) { - isolate->ThrowException(String::NewFromUtf8(isolate, e.what(), NewStringType::kNormal).ToLocalChecked()); - } - - return scope.Escape(array); + return array; } diff --git a/src/AffTransformation2.h b/src/AffTransformation2.h index c3d8add..3c9485b 100644 --- a/src/AffTransformation2.h +++ b/src/AffTransformation2.h @@ -3,28 +3,31 @@ #include "CGALWrapper.h" #include "cgal_types.h" -#include "v8.h" +#include "napi.h" +#include class AffTransformation2 : public CGALWrapper { public: + AffTransformation2(Napi::CallbackInfo const& info); + // The name to be used for our JS class. static const char *Name; - // Add our function templates to the package exports, and return string to be used to name - // the class and constructor in JS. Called indirectly at module load time via the module + // Add our property descriptors (instance and static methods and values) to the list that will + // be used to define our JS class. Called indirectly at module load time via the module // init function. - static void RegisterMethods(v8::Isolate *isolate); + static void AddProperties(std::vector& properties); - // Attempt to parse a v8 argument into the CGAL object referred to by receiver. Returns true + // Attempt to parse a JS argument into the CGAL object referred to by receiver. Returns true // if parse was successful, false otherwise. - static bool ParseArg(v8::Isolate *isolate, v8::Local arg, Aff_transformation_2 &receiver); + static bool ParseArg(Napi::Env env, Napi::Value arg, Aff_transformation_2& receiver); - // Convert a CGAL object of the wrapped class to a POD v8 object. If precise is set to false, + // Convert a CGAL object of the wrapped class to a POD JS object. If precise is set to false, // will attempt to render in terms of doubles for coordinates, and may lose precision. - static v8::Local ToPOD(v8::Isolate *isolate, const Aff_transformation_2 &aff, bool precise=true); + static Napi::Value ToPOD(Napi::Env env, Aff_transformation_2 const& aff, bool precise=true); private: diff --git a/src/Point2.cc b/src/Point2.cc index a1910a0..f46cc00 100644 --- a/src/Point2.cc +++ b/src/Point2.cc @@ -1,5 +1,5 @@ #include "Point2.h" -// #include "AffTransformation2.h" +#include "AffTransformation2.h" #include "cgal_args.h" #include "iomanip" @@ -20,8 +20,8 @@ void Point2::AddProperties(vector& properties) properties.insert(properties.end(), { InstanceMethod("isEqual", &Point2::IsEqual), InstanceMethod("x", &Point2::X), - InstanceMethod("y", &Point2::Y) - // InstanceMethod("transform", &Point2::Transform) + InstanceMethod("y", &Point2::Y), + InstanceMethod("transform", &Point2::Transform) }); } @@ -98,13 +98,13 @@ Napi::Value Point2::Y(Napi::CallbackInfo const& info) } -// Napi::Value Point2::Transform(Napi::CallbackInfo const& info) -// { -// Napi::Env env = info.Env(); -// ARGS_ASSERT(isolate, info.Length() == 1); -// Aff_transformation_2 afft; -// if (AffTransformation2::ParseArg(env, info[0], afft)) { -// return mWrapped.transform(afft); -// } -// ARGS_ASSERT(env, false); -// } +Napi::Value Point2::Transform(Napi::CallbackInfo const& info) +{ + Napi::Env env = info.Env(); + ARGS_ASSERT(isolate, info.Length() == 1); + Aff_transformation_2 aff; + if (AffTransformation2::ParseArg(env, info[0], aff)) { + return Point2::New(env, mWrapped.transform(aff)); + } + ARGS_ASSERT(env, false); +} diff --git a/src/Point2.h b/src/Point2.h index 6bb80f3..eb0da35 100644 --- a/src/Point2.h +++ b/src/Point2.h @@ -39,7 +39,7 @@ class Point2 : public CGALWrapper Napi::Value IsEqual(Napi::CallbackInfo const& info); Napi::Value X(Napi::CallbackInfo const& info); Napi::Value Y(Napi::CallbackInfo const& info); - // Napi::Value Transform(Napi::CallbackInfo const& info); + Napi::Value Transform(Napi::CallbackInfo const& info); }; diff --git a/src/Polygon2.cc b/src/Polygon2.cc index 85e4ecf..826245f 100644 --- a/src/Polygon2.cc +++ b/src/Polygon2.cc @@ -1,6 +1,6 @@ #include "Polygon2.h" #include "Point2.h" -// #include "AffTransformation2.h" +#include "AffTransformation2.h" #include "cgal_args.h" using namespace std; @@ -25,8 +25,8 @@ void Polygon2::AddProperties(std::vector& properties) InstanceMethod("orientedSide", &Polygon2::OrientedSide), InstanceMethod("boundedSide", &Polygon2::BoundedSide), InstanceMethod("area", &Polygon2::Area), - InstanceMethod("coords", &Polygon2::Coords) - // NODE_SET_METHOD(constructorTemplate, "transform", Transform); + InstanceMethod("coords", &Polygon2::Coords), + StaticMethod("transform", &Polygon2::Transform) }); } @@ -103,30 +103,24 @@ Napi::Value Polygon2::Area(Napi::CallbackInfo const& info) } -// void Polygon2::Transform(const FunctionCallbackInfo &info) -// { -// Isolate *isolate = info.GetIsolate(); -// HandleScope scope(isolate); -// try { -// ARGS_ASSERT(isolate, info.Length() == 2); - -// Aff_transformation_2 afft; -// if (!AffTransformation2::ParseArg(isolate, info[0], afft)) { -// ARGS_ASSERT(isolate, false); -// } - -// Polygon_2 poly; -// if (!ParseArg(isolate, info[1], poly)) { -// ARGS_ASSERT(isolate, false); -// } - -// Polygon_2 xpoly = CGAL::transform(afft, poly); -// info.GetReturnValue().Set(New(isolate, xpoly)); -// } -// catch (const exception &e) { -// isolate->ThrowException(String::NewFromUtf8(isolate, e.what(), NewStringType::kNormal).ToLocalChecked()); -// } -// } +Napi::Value Polygon2::Transform(Napi::CallbackInfo const& info) +{ + Napi::Env env = info.Env(); + + ARGS_ASSERT(env, info.Length() == 2); + + Aff_transformation_2 afft; + if (!AffTransformation2::ParseArg(env, info[0u], afft)) { + ARGS_ASSERT(env, false); + } + + Polygon_2 poly; + if (!ParseArg(env, info[1], poly)) { + ARGS_ASSERT(env, false); + } + + return Polygon2::New(env, CGAL::transform(afft, poly)); +} Napi::Value Polygon2::Coords(Napi::CallbackInfo const& info) diff --git a/src/Polygon2.h b/src/Polygon2.h index 8518c0e..034f5ea 100644 --- a/src/Polygon2.h +++ b/src/Polygon2.h @@ -43,7 +43,7 @@ class Polygon2 : public CGALWrapper Napi::Value OrientedSide(Napi::CallbackInfo const& info); Napi::Value BoundedSide(Napi::CallbackInfo const& info); Napi::Value Area(Napi::CallbackInfo const& info); - // Napi::Value Transform(Napi::CallbackInfo const& info); + static Napi::Value Transform(Napi::CallbackInfo const& info); Napi::Value Coords(Napi::CallbackInfo const& info); }; diff --git a/src/cgal.cc b/src/cgal.cc index 766507f..2b6f8ca 100644 --- a/src/cgal.cc +++ b/src/cgal.cc @@ -1,6 +1,6 @@ #include "cgal.h" #include "cgal_types.h" -// #include "AffTransformation2.h" +#include "AffTransformation2.h" // #include "Arrangement2.h" #include "BBox2.h" // #include "Curve2.h" @@ -48,7 +48,7 @@ Napi::Object Init(Napi::Env env, Napi::Object exports) exports.Set("ARR_TOP_BOUNDARY", (int)CGAL::ARR_TOP_BOUNDARY); exports.Set("ARR_INTERIOR", (int)CGAL::ARR_INTERIOR); - // AffTransformation2::Init(env, exports); + AffTransformation2::Init(env, exports); // Arrangement2::Init(env, exports); BBox2::Init(env, exports); // Curve2::Init(env, exports);