From 40b888f1c35db3ecf3e0f6fa76567d5032f3dc85 Mon Sep 17 00:00:00 2001 From: Florian ROMEO Date: Thu, 7 Jul 2016 00:50:42 +0200 Subject: [PATCH] Lua trim lines --- lcUI/ui/icons/modifytrim.png | Bin 0 -> 4131 bytes lcUI/ui/resource.qrc | 1 + lcUILua/actions/operations.lua | 1 + lcUILua/actions/trimoperation.lua | 116 ++++++++++++++++++++++++ lcUILua/ui/cadmdichild.lua | 6 ++ lcUILua/ui/commandline.lua | 1 + lcUILua/ui/operations.lua | 5 + lcUILua/ui/toolbar.lua | 4 + lcadluascript/cad/lualibrecadbridge.cpp | 18 ++++ lckernel/cad/functions/intersect.cpp | 4 +- lckernel/cad/functions/intersect.h | 2 +- lcviewerqt/lcadviewer.cpp | 15 +-- lcviewerqt/lcadviewer.h | 2 +- 13 files changed, 165 insertions(+), 10 deletions(-) create mode 100644 lcUI/ui/icons/modifytrim.png create mode 100644 lcUILua/actions/trimoperation.lua diff --git a/lcUI/ui/icons/modifytrim.png b/lcUI/ui/icons/modifytrim.png new file mode 100644 index 0000000000000000000000000000000000000000..6cfb1afc18ec81642acdaa3cb7c81cd0f7b652b8 GIT binary patch literal 4131 zcmbtXi8~bD_nsv)jAhC;c9A89(1^;QtTQCpCyEh9NOrOhk&tc5GKerq_L@-H#vsW^ z*(M<>M)oO7w)pw{{)O*-o^#K0&vVan?{nVs-g{2+mCL5QFfkYa0N}-9jI0lJ&VRxQ zIh@hJfFFnINRR>6mh*5#ak}3>Tyyzjt_A@BlF$DW;2Wbt_@PlW*ccaV<3|V%a}D$W zgoTBj^1AI4?VIl^xKO4)0QaBP&}7Mxacgaa7aDr<5>EDc8%d&?tR@!ybEN8f8?LY{F&tn+qF_ zznA=+So8D>()h~v{hgi(?Y|Szqpg1nBR_ugEDjpgez)JLJK*f|t$(0l)Y+%@%_aUU zOzT+fXFemxhbOBs3P!HRr)6MB5|(YICio1cJy_`U4y)5}?qEK(b|FDIk%(#U> zjlZdz@-0q6WwE*$p-1?@>7aLDH=-5o-M6AtdP;C7;~pSsT2>4$!O5et-Rq6@*-=)6 zRrPC7FVb++m}{6~Na(NGtRAFN({1``Y6oqSc7_z=To-s^qniN%L5D_U(>NdwR$XpF zBQ|vtyaX+19#=3R7Zh8UCsO)7Z)}rR{8^r2825MN%8UpWxl`RFb+AbY)l%09*_Fb- zr5x0}iN|#3jREknZxe#g*4s49E}fNt@Wp8#d|KW#!E0m3cOu$YwVxP`;Ez0c3LwjZ zF?Z|$)6r7y(w}{O4*uDR}wlF5C*b4Bck8LP}DY1!>WDflFkMuD+>*F@DdoPWU1eu~rdGZ#>Z ztqZGM8{diaXhPrpOcXuxa}Gzw9P@t4p=>wW`ik zt?rvI%(7m=5X@3yxXZLCN=F9n;wXf50J)e?9rRy&?Wtg^wL5bpVWZhw|8-z$4{1G? zR1TmL*Nfk9`!|uV7hT#i-if355V;5c9{5U4oGA+os8L#7uUvqX0OMjvwGaisLH23U z{q3lBvYqaCM1Wkh^vPZI2v^{qyIAnLM(XPj)Sl_K8Ggit&Fdv8r<($OpbF2+02W!4 ztH}PlFt|Z;z(gb3ULVaVk|2pwwrZDzziC{EqPI%EtYB>7H_}$oW1R4?gGvS|rbnK<%$?qERt$Iq**3&|jA} zapA|H@o%cJ3hMr`E&AUr6Gcv%=cguhwuz}1^Qxez88eG^Yp#Sy%Cp;Y*I^SEDxLP0 zTkF~GUp6oI`sv_(x2GvCNV&xSE|pCK(gr}RyX*jmh~$%`Od~X!1C1v%=YExYZ0c~7 zB^^E+^E&ACt;rt;tt-Y~{t&Kywu?O$YVTOVjo57>G4n=d#KQbYTpz0Ki5TkdM@ z#h?~uXQXOt+qg?H4D}8sGyiw%6iFJ&kcJkWrYdbm*rDZg@5Wx`#z7<~&h!p>)h?%6 zXTmFD4Bvzf(kq3#m>rqRKDg=t28%7bU0!w7pFW1qATHm*Cn67Jw#Uj!#mnK9;(!tQAJD)%iflcXil-9>VToRHx^b3R72dpz zt}+|_$5l4xTnU~){SqG}^Xzm|Lk@D@8Grgzt+jUw+gI5Yh=~BZbnW*Lw+(65C>?E= zxv->!UrQ^$PbSkjX6{YZ)D#f6a!h{ zP7rIC=tcUF>&Q(crvaRwpp$#fk#2hv&Ht6lJ62oE={~T;qJ`9@lT5KoxpfZNGV^Dm zN?vQiT$R3CoJ=gAP2f20bw+O>D2UdAU?-3*`j}N8GK1mQvx{wvI(ZzRyI`e^UF2iIK?*}J7g3eHWyF~9eiWe1g+Je>X0bgS9bys zlLFxk4uy(D(qKck2-4_ffd^L`n#3}mHo~^o*j)el+t+rLvN8p0IXPb$F>E9E)gA}H z!k$Whzv?&G!ok2e<~lCqaYP~V6ulx;J$iA!ro{qrdYwJ%$q21jqlafifHOuc_Mh~BK~i1fom@L1Zu zRKXV!)i@+^9^tVM-|7~_21>m`OY6-t6%jhH*IIa~IKK`3s+2#q9Jf1~JN(S@%Xw~8 zq+pg{ku*m6k5Wzx-8}(zwsltC*fuSW^tR@rLXvFSL$&lKUMpN{=8PdOzPLV%b#+>9 zIs`p$;%Oe5O!1rh=^BtsUjU=VIWjK)i=wqi4P1I1)~gFtGA7zj93E2~q>eycT4Ms8uDdJZ8WG0s8{zud5kqqqQEXo@z5 zEkJZ;v1zwFtO`bQa}*w2BlkxBfXZI#AE>&)-%N*L8gnP({W5DFt%9k;2FJKZjyhHA zVag?n6jUk^Y-+qS_m_P!{Raz{r-SS2ja)b4$re2WzqprQ?rRh!d22{L-nlZZo%Hkb z^CZHYhek3Th9}(ZUm`^9D@UIn)1i%#%FQFhk6$g+gJdLNGE_H@NNG^p8DEwSj`iS_ z7`N1-q^I_QYgJn_b3v_WeJ;ezE|?Wg%RSFA_QA+CJM;dJVy`fId{q%wQCcl z^h*G^=EpXYZ?EbYp$jw{&=`%{)GBrt!OP0Ga{yFmn_K~yk?Dtm!;UbD=^3AO+90{9 zmSrb+#iN1JU2gRT;*KsoCj`8e4nTC#6dhtaxY1`_=lu`w#ai`q^EdR^al~yad?orW zzGmYAc%`d}{4^Y3Nqto^8j)h;6q?A20&kt0E#==2(JqlH1!b-y(dW+y>PDzYJr>)+ z-EA%2jLx7K%`Ge_*NmyjhB>Ne6i^NKry&hE)T z^*_>3-zjtN0R-@z`GQwTv(n9i!)okfCv;xMYLZhTC#eD;*WVd5np7_F5g6k^kp9@2 zTYYm|xQ`J^M`T*^=4pQy$Z48e%yuI*|1dW!d7czPd+t40b3=9V26;@8%`uZ%;Y?@l zh{-Agwp+d!O8<_nQ|q4rj7>Hb!+O5ZJ-ZQ-PzjrS&+x2p++1wr$s2ixPj+O`f#|-f9v=&f?@j>*VF``uI9geW+v3GJTvm)k*1i!JJ3T*O* zJokHT@G}mEA9&6zzo5<`%j{%zJ?TU^!m3DtbK0Y2F;dT^PBz>6eXTlILS#yP#Y&gW zX%j1lgK<=ip(VSlPKe^vqvgU0l2ZE*D zW?FusQvY&T7o&uAQ!0~hR@9R?W{~XV#pb6BNty?3Zuo&Iv+*47BJ5#{6*ut&h!sMc zCmB4CleM^DnBYM$oi2sR%STF_H6HvL)tWN=@LDt79s0+Z)|p_up*wy5WFA!^Q zL}VH|J^n`5=6)42_|IMzafmr^%a&e2+-7d6>>$Ip_TS%qT; z!?AjXwo*Vufmr=p^H-Y)cCnNf?y@SVaq-oiO|Cqbj^;KOPpdGB$Z#uClREVODVqa; z8d){yg$U%3m+=H`KoeN!DZ?qQ&g?vP&}pL*Wqoa7P$+*4gT8e(nDECjicVGiXpnyP zOcRa}D$z!i;2$yE0tE`%6@2z{Jp^J3xbhTjXy$1$?M8|Y$kHlvIbFaF1-i#R%QZ+FXq`a34#RkhZL;9eIHXvI%g=Q#l?h>2iTDdEq>IEJo0d@=_St zn;kA*G^*ZjGM!3Vsea~`#VWTv42MXRaC9(j5A9FdTgt=CWY`W0#XLF;1qfB>U}rpuk63F(pxA(Be+P%HSCZ+#-r)R`2{IMBIL0oqD3W}(T0f} tvfX|m+ixhNRc+#!@jtYzasvC(x4(Gzea((0A2##=tnp=|S_6Fi{{fr$v4{Ww literal 0 HcmV?d00001 diff --git a/lcUI/ui/resource.qrc b/lcUI/ui/resource.qrc index 64dac02bf..20b975e57 100644 --- a/lcUI/ui/resource.qrc +++ b/lcUI/ui/resource.qrc @@ -21,5 +21,6 @@ icons/scale.png icons/delete.svg icons/modifymove.png + icons/modifytrim.png diff --git a/lcUILua/actions/operations.lua b/lcUILua/actions/operations.lua index 69879a8b6..635ff8d0c 100644 --- a/lcUILua/actions/operations.lua +++ b/lcUILua/actions/operations.lua @@ -16,6 +16,7 @@ require 'actions.rotateoperation' require 'actions.copyoperation' require 'actions.scaleoperation' require 'actions.removeoperation' +require 'actions.trimoperation' Operations = {} Operations.__index = Operations diff --git a/lcUILua/actions/trimoperation.lua b/lcUILua/actions/trimoperation.lua new file mode 100644 index 000000000..b4b61a5c6 --- /dev/null +++ b/lcUILua/actions/trimoperation.lua @@ -0,0 +1,116 @@ +TrimOperation = {} +TrimOperation.__index = TrimOperation + +setmetatable(TrimOperation, { + __index = Operations, + __call = function (o, ...) + local self = setmetatable({}, o) + self:_init(...) + return self + end, +}) + +function TrimOperation:_init(id) + Operations._init(self, id) + + self.limit = nil + self.toTrim = nil + self.intersectionPoints = {} + self.toRemovePoint = nil + + event.register("point", self) + event.register("selectionChanged", self) + + message("Select limit entity") +end + +function TrimOperation:onEvent(eventName, ...) + if(Operations.forMe(self) == false) then + return + end + + if(eventName == "selectionChanged") then + self:selectionChanged() + elseif(eventName == "point") then + self:newPoint(...) + end +end + +function TrimOperation:selectionChanged() + if(self.toTrim == nil) then + nbEntities = #active_widget():selection() + if(nbEntities == 1) then + if(self.limit == nil) then + self.limit = active_widget():selection()[1] + + message("Select entity to trim") + elseif(self.toTrim == nil) then + self.toTrim = active_widget():selection()[1] + + self:getIntersectionPoints() + end + elseif(nbEntities > 1) then + message("Select only one entity") + end + end +end + +function TrimOperation:newPoint(point) + if(#self.intersectionPoints >= 1) then + self.toRemovePoint = Operations:getCoordinate(point) + + self:trim() + end +end + +function TrimOperation:getIntersectionPoints() + local intersect = IntersectMany({self.toTrim, self.limit}) + self.intersectionPoints = intersect:result() + + if(#self.intersectionPoints == 0) then + message("No intersection found") + + self:close() + elseif(#self.intersectionPoints >= 1) then + message("Click on the part of the entity to remove") + end +end + +function TrimOperation:trim() + local newEntity + if(self.toTrim.entityType == "line") then + local point = self.toTrim:nearestPointOnEntity(self.toRemovePoint) + + local startToPoint = point:distanceTo(self.toTrim:start()) + local startToIntersect = point:distanceTo(self.intersectionPoints[1]) + + if(startToPoint >= startToIntersect) then + newEntity = Line(self.toTrim:start(), self.intersectionPoints[1], self.toTrim:layer()) + else + newEntity = Line(self.intersectionPoints[1], self.toTrim:finish(), self.toTrim:layer()) + end + end + + local b = Builder(active_widget():document()) + b:append(self.toTrim) + + b:push() + b:remove() + b:processStack() + + b:append(newEntity) + b:execute() + + self:close() +end + +function TrimOperation:close() + if(not self.finished) then + self.finished = true + + event.delete("point", self) + event.delete("selectionChanged", self) + + event.trigger('operationFinished') + end +end \ No newline at end of file diff --git a/lcUILua/ui/cadmdichild.lua b/lcUILua/ui/cadmdichild.lua index 4a1a714af..cb23ec72f 100644 --- a/lcUILua/ui/cadmdichild.lua +++ b/lcUILua/ui/cadmdichild.lua @@ -12,6 +12,10 @@ local function mouseMove() event.trigger('mouseMove', position) end +local function mouseRelease() + event.trigger('selectionChanged') +end + function new_document() cadMdiChild = lc.CadMdiChild() cadMdiChild:newDocument() @@ -19,6 +23,7 @@ function new_document() cadMdiChild:setDestroyCallback(onMdiChildDestroyed) luaInterface:luaConnect(cadMdiChild:view(), "mousePressEvent()", click) + luaInterface:luaConnect(cadMdiChild:view(), "mouseReleaseEvent()", mouseRelease) luaInterface:luaConnect(cadMdiChild:view(), "mouseMoveEvent()", mouseMove) luaInterface:connect(cadMdiChild, "keyPressed(QKeyEvent*)", cliCommand, "onKeyPressed(QKeyEvent*)") @@ -31,6 +36,7 @@ function load_document(fileName) cadMdiChild:viewer():autoScale() luaInterface:luaConnect(cadMdiChild:view(), "mousePressEvent()", click) + luaInterface:luaConnect(cadMdiChild:view(), "mouseReleaseEvent()", mouseRelease) luaInterface:luaConnect(cadMdiChild:view(), "mouseMoveEvent()", mouseMove) luaInterface:connect(cadMdiChild, "keyPressed(QKeyEvent*)", cliCommand, "onKeyPressed(QKeyEvent*)") diff --git a/lcUILua/ui/commandline.lua b/lcUILua/ui/commandline.lua index 8a1257714..e568c5bcb 100644 --- a/lcUILua/ui/commandline.lua +++ b/lcUILua/ui/commandline.lua @@ -69,6 +69,7 @@ function add_commandline() add_command("COPY", copy_selected_entities) add_command("SCALE", scale_selected_entities) add_command("REMOVE", remove_selected_entities) + add_command("TRIM", trim_entity) event.register("point", setLastPoint) end \ No newline at end of file diff --git a/lcUILua/ui/operations.lua b/lcUILua/ui/operations.lua index 063b54e38..64eb1973d 100644 --- a/lcUILua/ui/operations.lua +++ b/lcUILua/ui/operations.lua @@ -139,4 +139,9 @@ end function remove_selected_entities() new_operation() op[active_widget().id] = RemoveOperation(active_widget().id) +end + +function trim_entity() + new_operation() + op[active_widget().id] = TrimOperation(active_widget().id) end \ No newline at end of file diff --git a/lcUILua/ui/toolbar.lua b/lcUILua/ui/toolbar.lua index 78dd13af9..f20ab9338 100644 --- a/lcUILua/ui/toolbar.lua +++ b/lcUILua/ui/toolbar.lua @@ -116,4 +116,8 @@ function add_toolbar() local removeButton = create_button("", ":/icons/delete.svg") quickAccess:addButton(modifyGroup, removeButton, 2, 0, 1, 1) luaInterface:luaConnect(removeButton, "pressed()", remove_selected_entities) + + local removeButton = create_button("", ":/icons/modifytrim.png") + quickAccess:addButton(modifyGroup, removeButton, 2, 1, 1, 1) + luaInterface:luaConnect(removeButton, "pressed()", trim_entity) end diff --git a/lcadluascript/cad/lualibrecadbridge.cpp b/lcadluascript/cad/lualibrecadbridge.cpp index d2171c9a8..7a0f05663 100644 --- a/lcadluascript/cad/lualibrecadbridge.cpp +++ b/lcadluascript/cad/lualibrecadbridge.cpp @@ -177,13 +177,25 @@ void lua_openlckernel(lua_State* L) { .addFunction("move", &entity::CADEntity::move) .addFunction("rotate", &entity::CADEntity::rotate) .addFunction("copy", &entity::CADEntity::copy) + + .addFunction("layer", &entity::CADEntity::layer) + + .addProperty("entityType", [](entity::CADEntity*) { + return "unknown"; + }) .endClass() .beginExtendClass("Line") .addConstructor(LUA_SP(entity::Line_SPtr), LUA_ARGS( const geo::Coordinate & start, const geo::Coordinate & end, const Layer_CSPtr)) + .addProperty("entityType", [](entity::Line*) { + return "line"; + }) + .addFunction("nearestPointOnEntity", &geo::Vector::nearestPointOnEntity) .addFunction("nearestPointOnPath", &geo::Vector::nearestPointOnPath) + .addFunction("start", &geo::Vector::start) + .addFunction("finish", &geo::Vector::end) //"end" will make Lua crash .endClass() .beginExtendClass("Circle") .addConstructor(LUA_SP(entity::Circle_SPtr), LUA_ARGS( @@ -312,6 +324,12 @@ void lua_openlckernel(lua_State* L) { .addFunction("begin", &lc::operation::Builder::begin) .addFunction("selectByLayer", &lc::operation::Builder::selectByLayer) .addFunction("remove", &lc::operation::Builder::remove) + .addFunction("processStack", &lc::operation::Builder::processStack) + .endClass() + + .beginClass("IntersectMany") + .addConstructor(LUA_ARGS(std::vector, _opt, _opt)) + .addFunction("result", &lc::IntersectMany::result) .endClass() .beginClass("Base") diff --git a/lckernel/cad/functions/intersect.cpp b/lckernel/cad/functions/intersect.cpp index dd581ca19..c22c0a372 100644 --- a/lckernel/cad/functions/intersect.cpp +++ b/lckernel/cad/functions/intersect.cpp @@ -607,8 +607,8 @@ std::vector IntersectMany::result() const { Intersect intersect(_method, _tolerance); if (_entities.size() > 1) { for (size_t outer = 0; outer < (_entities.size() - 1); outer++) { - for (size_t inner = ++outer; inner < _entities.size(); inner++) { - // visitorDispatcher(intersect, *_entities.at(outer).get(), *_entities.at(inner).get()); + for (size_t inner = outer + 1; inner < _entities.size(); inner++) { + visitorDispatcher(intersect, *_entities.at(outer).get(), *_entities.at(inner).get()); } } } diff --git a/lckernel/cad/functions/intersect.h b/lckernel/cad/functions/intersect.h index a921bf3aa..1354cf414 100644 --- a/lckernel/cad/functions/intersect.h +++ b/lckernel/cad/functions/intersect.h @@ -184,7 +184,7 @@ namespace lc { */ class IntersectMany { public: - IntersectMany(std::vector, Intersect::Method, double tolerance); + IntersectMany(std::vector, Intersect::Method = Intersect::OnEntity, double tolerance = LCTOLERANCE); std::vector result() const; diff --git a/lcviewerqt/lcadviewer.cpp b/lcviewerqt/lcadviewer.cpp index 7ecdd94f9..1577ec736 100644 --- a/lcviewerqt/lcadviewer.cpp +++ b/lcviewerqt/lcadviewer.cpp @@ -180,12 +180,16 @@ void LCADViewer::mouseMoveEvent(QMouseEvent *event) { void LCADViewer::mousePressEvent(QMouseEvent *event) { QWidget::mousePressEvent(event); + startSelectPos = event->pos(); + + if (!_ctrlKeyActive) { + _docCanvas->removeSelection(); + } + if(!_operationActive) { _dragManager->onMousePress(); _disableSelection = _dragManager->entityDragged(); - startSelectPos = event->pos(); - posX = event->x(); posY = event->y(); @@ -195,10 +199,6 @@ void LCADViewer::mousePressEvent(QMouseEvent *event) { } break; } - - if (!_ctrlKeyActive) { - _docCanvas->removeSelection(); - } } _docCanvas->device_to_user(&posX, &posY); @@ -227,6 +227,9 @@ void LCADViewer::mouseReleaseEvent(QMouseEvent *event) { } _docCanvas->removeSelectionArea(); + + emit mouseReleaseEvent(); + update(); } diff --git a/lcviewerqt/lcadviewer.h b/lcviewerqt/lcadviewer.h index b0de94a9a..dcb160f7f 100644 --- a/lcviewerqt/lcadviewer.h +++ b/lcviewerqt/lcadviewer.h @@ -87,7 +87,7 @@ class LCADViewer : public QWidget { signals: void mouseMoveEvent(); void mousePressEvent(); - void mouseReleaseEvent(const MouseReleaseEvent&); + void mouseReleaseEvent(); void drawEvent(const DrawEvent&); void selectedItemsEvent(const SelectedItemsEvent&); public slots: