diff --git a/ChangeLog.txt b/ChangeLog.txt index 0539717c8..6363689a1 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -50,6 +50,10 @@ - [#589] Valentina lock up if not enough space for label. - [#606] Mac OS X. Can’t type in measurements due to digit count limitation. - [#612] Valentina crashes when network is disabled on Linux. +- [#406] New feature: Seam allowance tool -> Preview. +- [#88] New feature: Variable width seam allowances. +- [#280] New tool: 'Hem' in Detail mode. +- [#509] Improve feature: Support internal Paths in Detail tool. # Version 0.4.6 - [#594] Broken export on Mac. diff --git a/src/app/share/collection/MaleShirt/MaleShirt.val b/src/app/share/collection/MaleShirt/MaleShirt.val index cec3bc8f0..1ac2621df 100644 --- a/src/app/share/collection/MaleShirt/MaleShirt.val +++ b/src/app/share/collection/MaleShirt/MaleShirt.val @@ -1,7 +1,7 @@ <?xml version='1.0' encoding='UTF-8'?> <pattern> <!--Pattern created with Valentina (http://www.valentina-project.org/).--> - <version>0.3.1</version> + <version>0.4.0</version> <unit>cm</unit> <author>Timo Virtaneva</author> <description>This a male shirt pattern. @@ -14,7 +14,7 @@ The design is based on the measuring table. The table must be loaded, but the va Adjust/verify curves after parameter modifications. Delete layouts which are not needed.</description> - <notes></notes> + <notes/> <measurements>MaleShirt.vit</measurements> <increments> <increment name="#ToBeVerified" description="" formula="0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0"/> @@ -197,49 +197,55 @@ Delete layouts which are not needed.</description> <point type="modeling" inUse="true" id="440" idObject="55" mx="0.132292" my="0.264583"/> </modeling> <details> - <detail closed="1" id="174" name="Yoke" supplement="1" mx="-8.05221" width="1" my="3.27846"> - <node type="NodePoint" nodeType="Contour" idObject="167" mx="0" my="0"/> - <node type="NodeSplinePath" reverse="0" nodeType="Contour" idObject="168" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="169" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="170" mx="0" my="0"/> - <node type="NodeSpline" reverse="0" nodeType="Contour" idObject="171" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="172" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="173" mx="0" my="0"/> + <detail closed="1" id="174" name="Yoke" seamAllowance="1" mx="-8.05221" width="1" my="3.27846" version="2"> + <nodes> + <node type="NodePoint" idObject="167"/> + <node type="NodeSplinePath" reverse="0" idObject="168"/> + <node type="NodePoint" idObject="169"/> + <node type="NodePoint" idObject="170"/> + <node type="NodeSpline" reverse="0" idObject="171"/> + <node type="NodePoint" idObject="172"/> + <node type="NodePoint" idObject="173"/> + </nodes> </detail> - <detail closed="1" id="401" name="FrontPanel" supplement="1" mx="-11.0934" width="1" my="6.43098"> - <node type="NodePoint" nodeType="Contour" idObject="389" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="390" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="391" mx="0" my="0"/> - <node type="NodeSpline" reverse="0" nodeType="Contour" idObject="392" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="393" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="394" mx="0" my="0"/> - <node type="NodeSplinePath" reverse="0" nodeType="Contour" idObject="395" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="396" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="397" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="398" mx="0" my="0"/> - <node type="NodeSplinePath" reverse="1" nodeType="Contour" idObject="399" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="400" mx="0" my="0"/> + <detail closed="1" id="401" name="FrontPanel" seamAllowance="1" mx="-11.0934" width="1" my="6.43098" version="2"> + <nodes> + <node type="NodePoint" idObject="389"/> + <node type="NodePoint" idObject="390"/> + <node type="NodePoint" idObject="391"/> + <node type="NodeSpline" reverse="0" idObject="392"/> + <node type="NodePoint" idObject="393"/> + <node type="NodePoint" idObject="394"/> + <node type="NodeSplinePath" reverse="0" idObject="395"/> + <node type="NodePoint" idObject="396"/> + <node type="NodePoint" idObject="397"/> + <node type="NodePoint" idObject="398"/> + <node type="NodeSplinePath" reverse="1" idObject="399"/> + <node type="NodePoint" idObject="400"/> + </nodes> </detail> - <detail closed="1" id="441" name="BackPanel" supplement="1" mx="-7.55641" width="1" my="6.27021"> - <node type="NodePoint" nodeType="Contour" idObject="422" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="423" mx="0" my="0"/> - <node type="NodeSplinePath" reverse="1" nodeType="Contour" idObject="424" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="425" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="426" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="427" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="428" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="429" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="430" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="431" mx="0" my="0"/> - <node type="NodeSplinePath" reverse="1" nodeType="Contour" idObject="432" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="433" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="434" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="435" mx="0" my="0"/> - <node type="NodeSplinePath" reverse="0" nodeType="Contour" idObject="436" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="437" mx="0" my="0"/> - <node type="NodeSpline" reverse="0" nodeType="Contour" idObject="438" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="439" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="440" mx="0" my="0"/> + <detail closed="1" id="441" name="BackPanel" seamAllowance="1" mx="-7.55641" width="1" my="6.27021" version="2"> + <nodes> + <node type="NodePoint" idObject="422"/> + <node type="NodePoint" idObject="423"/> + <node type="NodeSplinePath" reverse="1" idObject="424"/> + <node type="NodePoint" idObject="425"/> + <node type="NodePoint" idObject="426"/> + <node type="NodePoint" idObject="427"/> + <node type="NodePoint" idObject="428"/> + <node type="NodePoint" idObject="429"/> + <node type="NodePoint" idObject="430"/> + <node type="NodePoint" idObject="431"/> + <node type="NodeSplinePath" reverse="1" idObject="432"/> + <node type="NodePoint" idObject="433"/> + <node type="NodePoint" idObject="434"/> + <node type="NodePoint" idObject="435"/> + <node type="NodeSplinePath" reverse="0" idObject="436"/> + <node type="NodePoint" idObject="437"/> + <node type="NodeSpline" reverse="0" idObject="438"/> + <node type="NodePoint" idObject="439"/> + <node type="NodePoint" idObject="440"/> + </nodes> </detail> </details> <groups/> @@ -310,36 +316,44 @@ Delete layouts which are not needed.</description> <spline type="modelingPath" inUse="true" id="331" idObject="312"/> </modeling> <details> - <detail closed="1" id="182" name="Pocket" supplement="1" mx="68.0595" width="1" my="45.4124"> - <node type="NodePoint" nodeType="Contour" idObject="175" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="176" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="177" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="178" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="179" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="180" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="181" mx="0" my="0"/> + <detail closed="1" id="182" name="Pocket" seamAllowance="1" mx="68.0595" width="1" my="45.4124" version="2"> + <nodes> + <node type="NodePoint" idObject="175"/> + <node type="NodePoint" idObject="176"/> + <node type="NodePoint" idObject="177"/> + <node type="NodePoint" idObject="178"/> + <node type="NodePoint" idObject="179"/> + <node type="NodePoint" idObject="180"/> + <node type="NodePoint" idObject="181"/> + </nodes> </detail> - <detail closed="1" id="320" name="PocketRound" supplement="1" mx="81.7244" width="1" my="45.8357"> - <node type="NodePoint" nodeType="Contour" idObject="314" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="315" mx="0" my="0"/> - <node type="NodeSplinePath" reverse="0" nodeType="Contour" idObject="316" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="317" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="318" mx="0" my="0"/> - <node type="NodeSplinePath" reverse="1" nodeType="Contour" idObject="319" mx="0" my="0"/> + <detail closed="1" id="320" name="PocketRound" seamAllowance="1" mx="81.7244" width="1" my="45.8357" version="2"> + <nodes> + <node type="NodePoint" idObject="314"/> + <node type="NodePoint" idObject="315"/> + <node type="NodeSplinePath" reverse="0" idObject="316"/> + <node type="NodePoint" idObject="317"/> + <node type="NodePoint" idObject="318"/> + <node type="NodeSplinePath" reverse="1" idObject="319"/> + </nodes> </detail> - <detail closed="1" id="326" name="PocketFlap" supplement="1" mx="67.876" width="1" my="32.9628"> - <node type="NodePoint" nodeType="Contour" idObject="321" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="322" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="323" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="324" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="325" mx="0" my="0"/> + <detail closed="1" id="326" name="PocketFlap" seamAllowance="1" mx="67.876" width="1" my="32.9628" version="2"> + <nodes> + <node type="NodePoint" idObject="321"/> + <node type="NodePoint" idObject="322"/> + <node type="NodePoint" idObject="323"/> + <node type="NodePoint" idObject="324"/> + <node type="NodePoint" idObject="325"/> + </nodes> </detail> - <detail closed="1" id="332" name="PocketFlapRound" supplement="1" mx="81.7244" width="1" my="32.9627"> - <node type="NodePoint" nodeType="Contour" idObject="327" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="328" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="329" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="330" mx="0" my="0"/> - <node type="NodeSplinePath" reverse="1" nodeType="Contour" idObject="331" mx="0" my="0"/> + <detail closed="1" id="332" name="PocketFlapRound" seamAllowance="1" mx="81.7244" width="1" my="32.9627" version="2"> + <nodes> + <node type="NodePoint" idObject="327"/> + <node type="NodePoint" idObject="328"/> + <node type="NodePoint" idObject="329"/> + <node type="NodePoint" idObject="330"/> + <node type="NodeSplinePath" reverse="1" idObject="331"/> + </nodes> </detail> </details> <groups/> @@ -393,7 +407,7 @@ Delete layouts which are not needed.</description> <line typeLine="hair" id="107" firstPoint="99" secondPoint="96" lineColor="black"/> <line typeLine="hair" id="108" firstPoint="98" secondPoint="94" lineColor="black"/> <line typeLine="hair" id="109" firstPoint="100" secondPoint="93" lineColor="black"/> - <spline type="simpleInteractive" point4="89" angle1="12.2644" angle2="338.776" id="110" color="black" length1="4.83467" length2="0.851297" point1="104"/> + <spline type="simpleInteractive" point4="89" angle1="12.2644" angle2="208.953" id="110" color="black" length1="4.83467" length2="0.750071" point1="104"/> <spline type="simpleInteractive" point4="100" angle1="164.47" angle2="0" id="111" color="black" length1="2.91869" length2="0" point1="106"/> <line typeLine="hair" id="112" firstPoint="96" secondPoint="95" lineColor="black"/> <line typeLine="hair" id="113" firstPoint="94" secondPoint="92" lineColor="black"/> @@ -447,45 +461,53 @@ Delete layouts which are not needed.</description> <point type="modeling" inUse="true" id="299" idObject="97" mx="-0.222289" my="0.696084"/> </modeling> <details> - <detail closed="1" id="204" name="Collar" supplement="1" mx="27.4551" width="1" my="0.587081"> - <node type="NodePoint" nodeType="Contour" idObject="200" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="201" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="202" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="203" mx="0" my="0"/> + <detail closed="1" id="204" name="Collar" seamAllowance="1" mx="27.4551" width="1" my="0.587081" version="2"> + <nodes> + <node type="NodePoint" idObject="200"/> + <node type="NodePoint" idObject="201"/> + <node type="NodePoint" idObject="202"/> + <node type="NodePoint" idObject="203"/> + </nodes> </detail> - <detail closed="1" id="209" name="CuffInterface" supplement="0" mx="26.9909" width="1" my="-8.22145"> - <node type="NodePoint" nodeType="Contour" idObject="205" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="206" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="207" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="208" mx="0" my="0"/> + <detail closed="1" id="209" name="CuffInterface" seamAllowance="0" mx="26.9909" width="1" my="-8.22145" version="2"> + <nodes> + <node type="NodePoint" idObject="205"/> + <node type="NodePoint" idObject="206"/> + <node type="NodePoint" idObject="207"/> + <node type="NodePoint" idObject="208"/> + </nodes> </detail> - <detail closed="1" id="217" name="ShortSleeve" supplement="1" mx="-16.9664" width="1" my="-23.4126"> - <node type="NodePoint" nodeType="Contour" idObject="210" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="211" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="212" mx="0" my="0"/> - <node type="NodeSplinePath" reverse="0" nodeType="Contour" idObject="213" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="214" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="215" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="216" mx="0" my="0"/> + <detail closed="1" id="217" name="ShortSleeve" seamAllowance="1" mx="-16.9664" width="1" my="-23.4126" version="2"> + <nodes> + <node type="NodePoint" idObject="210"/> + <node type="NodePoint" idObject="211"/> + <node type="NodePoint" idObject="212"/> + <node type="NodeSplinePath" reverse="0" idObject="213"/> + <node type="NodePoint" idObject="214"/> + <node type="NodePoint" idObject="215"/> + <node type="NodePoint" idObject="216"/> + </nodes> </detail> - <detail closed="1" id="300" name="FullSleeve" supplement="1" mx="-16.0896" width="1" my="15.2013"> - <node type="NodePoint" nodeType="Contour" idObject="283" mx="0" my="0"/> - <node type="NodeSpline" reverse="1" nodeType="Contour" idObject="284" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="285" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="286" mx="0" my="0"/> - <node type="NodeSplinePath" reverse="0" nodeType="Contour" idObject="287" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="288" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="289" mx="0" my="0"/> - <node type="NodeSpline" reverse="0" nodeType="Contour" idObject="290" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="291" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="292" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="293" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="294" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="295" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="296" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="297" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="298" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="299" mx="0" my="0"/> + <detail closed="1" id="300" name="FullSleeve" seamAllowance="1" mx="-16.0896" width="1" my="15.2013" version="2"> + <nodes> + <node type="NodePoint" idObject="283"/> + <node type="NodeSpline" reverse="1" idObject="284"/> + <node type="NodePoint" idObject="285"/> + <node type="NodePoint" idObject="286"/> + <node type="NodeSplinePath" reverse="0" idObject="287"/> + <node type="NodePoint" idObject="288"/> + <node type="NodePoint" idObject="289"/> + <node type="NodeSpline" reverse="0" idObject="290"/> + <node type="NodePoint" idObject="291"/> + <node type="NodePoint" idObject="292"/> + <node type="NodePoint" idObject="293"/> + <node type="NodePoint" idObject="294"/> + <node type="NodePoint" idObject="295"/> + <node type="NodePoint" idObject="296"/> + <node type="NodePoint" idObject="297"/> + <node type="NodePoint" idObject="298"/> + <node type="NodePoint" idObject="299"/> + </nodes> </detail> </details> <groups/> @@ -543,37 +565,45 @@ Delete layouts which are not needed.</description> <spline type="modelingSpline" inUse="true" id="254" idObject="248"/> </modeling> <details> - <detail closed="1" id="224" name="CollarBase" supplement="1" mx="28.4767" width="1" my="21.6501"> - <node type="NodePoint" nodeType="Contour" idObject="218" mx="0" my="0"/> - <node type="NodeSplinePath" reverse="1" nodeType="Contour" idObject="219" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="220" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="221" mx="0" my="0"/> - <node type="NodeSpline" reverse="1" nodeType="Contour" idObject="222" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="223" mx="0" my="0"/> + <detail closed="1" id="224" name="CollarBase" seamAllowance="1" mx="28.4767" width="1" my="21.6501" version="2"> + <nodes> + <node type="NodePoint" idObject="218"/> + <node type="NodeSplinePath" reverse="1" idObject="219"/> + <node type="NodePoint" idObject="220"/> + <node type="NodePoint" idObject="221"/> + <node type="NodeSpline" reverse="1" idObject="222"/> + <node type="NodePoint" idObject="223"/> + </nodes> </detail> - <detail closed="1" id="231" name="CollarBaseInterface" supplement="0" mx="28.6569" width="1" my="15.2047"> - <node type="NodePoint" nodeType="Contour" idObject="225" mx="0" my="0"/> - <node type="NodeSplinePath" reverse="1" nodeType="Contour" idObject="226" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="227" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="228" mx="0" my="0"/> - <node type="NodeSpline" reverse="1" nodeType="Contour" idObject="229" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="230" mx="0" my="0"/> + <detail closed="1" id="231" name="CollarBaseInterface" seamAllowance="0" mx="28.6569" width="1" my="15.2047" version="2"> + <nodes> + <node type="NodePoint" idObject="225"/> + <node type="NodeSplinePath" reverse="1" idObject="226"/> + <node type="NodePoint" idObject="227"/> + <node type="NodePoint" idObject="228"/> + <node type="NodeSpline" reverse="1" idObject="229"/> + <node type="NodePoint" idObject="230"/> + </nodes> </detail> - <detail closed="1" id="238" name="CollarTop" supplement="1" mx="28.0866" width="1" my="9.53729"> - <node type="NodePoint" nodeType="Contour" idObject="232" mx="0" my="0"/> - <node type="NodeSpline" reverse="0" nodeType="Contour" idObject="233" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="234" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="235" mx="0" my="0"/> - <node type="NodeSpline" reverse="0" nodeType="Contour" idObject="236" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="237" mx="0" my="0"/> + <detail closed="1" id="238" name="CollarTop" seamAllowance="1" mx="28.0866" width="1" my="9.53729" version="2"> + <nodes> + <node type="NodePoint" idObject="232"/> + <node type="NodeSpline" reverse="0" idObject="233"/> + <node type="NodePoint" idObject="234"/> + <node type="NodePoint" idObject="235"/> + <node type="NodeSpline" reverse="0" idObject="236"/> + <node type="NodePoint" idObject="237"/> + </nodes> </detail> - <detail closed="1" id="255" name="CollarTopInterface" supplement="0" mx="27.8619" width="1" my="-1.37137"> - <node type="NodePoint" nodeType="Contour" idObject="249" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="250" mx="0" my="0"/> - <node type="NodeSpline" reverse="0" nodeType="Contour" idObject="251" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="252" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="253" mx="0" my="0"/> - <node type="NodeSpline" reverse="0" nodeType="Contour" idObject="254" mx="0" my="0"/> + <detail closed="1" id="255" name="CollarTopInterface" seamAllowance="0" mx="27.8619" width="1" my="-1.37137" version="2"> + <nodes> + <node type="NodePoint" idObject="249"/> + <node type="NodePoint" idObject="250"/> + <node type="NodeSpline" reverse="0" idObject="251"/> + <node type="NodePoint" idObject="252"/> + <node type="NodePoint" idObject="253"/> + <node type="NodeSpline" reverse="0" idObject="254"/> + </nodes> </detail> </details> <groups/> @@ -609,20 +639,24 @@ Delete layouts which are not needed.</description> <point type="modeling" inUse="true" id="281" idObject="260" mx="0.132292" my="0.264583"/> </modeling> <details> - <detail closed="1" id="274" name="PlacketUnder" supplement="1" mx="27.725" width="1" my="-0.179464"> - <node type="NodePoint" nodeType="Contour" idObject="270" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="271" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="272" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="273" mx="0" my="0"/> + <detail closed="1" id="274" name="PlacketUnder" seamAllowance="1" mx="27.725" width="1" my="-0.179464" version="2"> + <nodes> + <node type="NodePoint" idObject="270"/> + <node type="NodePoint" idObject="271"/> + <node type="NodePoint" idObject="272"/> + <node type="NodePoint" idObject="273"/> + </nodes> </detail> - <detail closed="1" id="282" name="PlacketTop" supplement="1" mx="46.1968" width="1" my="-5.58778"> - <node type="NodePoint" nodeType="Contour" idObject="275" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="276" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="277" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="278" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="279" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="280" mx="0" my="0"/> - <node type="NodePoint" nodeType="Contour" idObject="281" mx="0" my="0"/> + <detail closed="1" id="282" name="PlacketTop" seamAllowance="1" mx="46.1968" width="1" my="-5.58778" version="2"> + <nodes> + <node type="NodePoint" idObject="275"/> + <node type="NodePoint" idObject="276"/> + <node type="NodePoint" idObject="277"/> + <node type="NodePoint" idObject="278"/> + <node type="NodePoint" idObject="279"/> + <node type="NodePoint" idObject="280"/> + <node type="NodePoint" idObject="281"/> + </nodes> </detail> </details> <groups/> diff --git a/src/app/share/collection/bugs/Issue_#604.val b/src/app/share/collection/bugs/Issue_#604.val index 084ddd57b..f43d59593 100644 --- a/src/app/share/collection/bugs/Issue_#604.val +++ b/src/app/share/collection/bugs/Issue_#604.val @@ -6,7 +6,7 @@ <author/> <description/> <notes/> - <measurements>3XL.vit</measurements> + <measurements>Issue_#604.vit</measurements> <increments/> <draw name="Élément de patron 1"> <calculation> diff --git a/src/app/share/collection/bugs/pointOnCurve.val b/src/app/share/collection/bugs/pointOnCurve.val new file mode 100644 index 000000000..58baf1e84 --- /dev/null +++ b/src/app/share/collection/bugs/pointOnCurve.val @@ -0,0 +1,282 @@ +<?xml version='1.0' encoding='UTF-8'?> +<pattern> + <!--Valentina pattern format.--> + <version>0.4.0</version> + <unit>mm</unit> + <author/> + <description/> + <notes/> + <gradation defSize="300" defHeight="1100" custom="true"> + <heights all="true"/> + <sizes all="true"/> + </gradation> + <measurements>../../../../../../../Valentina_0.5.x/build-Valentina-Qt_5_2_1_GCC_32bit-Debug/src/app/valentina/bin/tables/standard/GOST_man_ru.vst</measurements> + <increments> + <increment name="#Пс_впрз" description="Высота основания" formula="16.1"/> + <increment name="#Пк_впрз1" description="проймы сзади АГ" formula="14"/> + <increment name="#Пдтс1" description="Длина спинки" formula="13"/> + <increment name="#Пдтс2" description="до линии талии АТ" formula="20"/> + <increment name="#Пус_ди" description="Длина куртки АН" formula="-67"/> + <increment name="#Пс_шс" description="Ширина спинки ГГ2" formula="21"/> + <increment name="#Пк_шс1" description="Опис" formula="2"/> + <increment name="#Пк_шс2" description="Опис" formula="2"/> + <increment name="#Пшпр1" description="Ширина проймы Г2Г3" formula="46"/> + <increment name="#Пшпр2" description="Опис" formula="-24"/> + <increment name="#Пс_шг" description="Ширина полочки на" formula="42"/> + <increment name="#Пк_шг1" description="уровне линии груди" formula="4"/> + <increment name="#Пк_шг2" description="Г3Г4" formula="0"/> + <increment name="#Пс_шпт" description=" Ширина полочки на уровне линии талии Т3Т4" formula="19"/> + <increment name="#Пс_впрс" description="Высота проймы спинки" formula="42"/> + <increment name="#Пс_впр" description="Высота проймы полочки Г3П3" formula="28"/> + <increment name="#Пк_впр1" description="Опис" formula="8.5"/> + <increment name="#Пс_впрп" description="Высота горловины" formula="38"/> + <increment name="#Пк_впрп1" description="полочки Г5А4" formula="9"/> + <increment name="#Пшгс" description="Ширина горловины спинки А1А2" formula="30"/> + <increment name="#Пк_шп1" description="Длина плечевой линии" formula="3"/> + <increment name="#Пк_шп2" description="спинки А3П2" formula="-1"/> + <increment name="#Ппос_шп" description="Опис" formula="-2"/> + <increment name="#Пс_сб" description="Ширина куртки на линии бедер" formula="20"/> + <increment name="#Пдр1" description="Длина рукава АН" formula="82"/> + <increment name="#Пдр2" description="Опис" formula="20"/> + <increment name="#Пдр_лок1" description="Длина рукава до" formula="38"/> + <increment name="#Пдр_лок2" description="локтя АЛ" formula="-10"/> + <increment name="#Пшр" description="Ширина рукава с курточным окатом АА1 и ББ2" formula="42"/> + <increment name="#Ппос_ор" description="Прибавка на посадку по окату рукава" formula="34"/> + <increment name="#Пшр1" description="Description" formula="50"/> + <increment name="#Пшр2" description="Description" formula="62"/> + <increment name="#Швс" description="Description" formula="70"/> + <increment name="#Пвк" description="Висота капишона" formula="20"/> + <increment name="#Пшк" description="ширина капишона" formula="20"/> + </increments> + <draw name="Куртка"> + <calculation> + <point type="single" x="16.3689" y="57.7733" id="33" name="А" mx="1.32292" my="2.64583"/> + <point type="endLine" typeLine="none" id="34" name="Г" basePoint="33" lineColor="black" mx="1.32292" angle="270" my="2.64583" length="0.2 * bust_arc_f + 0.07 * height + #Пс_впрз+10"/> + <point type="alongLine" typeLine="none" id="35" name="У" firstPoint="33" secondPoint="34" lineColor="black" mx="1.32292" my="2.64583" length="0.5*Line_А_Г"/> + <point type="endLine" typeLine="none" id="36" name="Т" basePoint="33" lineColor="black" mx="1.32292" angle="270" my="2.64583" length="0.25 * height + #Пдтс2"/> + <point type="endLine" typeLine="hair" id="37" name="Н" basePoint="33" lineColor="black" mx="1.32292" angle="270" my="2.64583" length="0.33 * height + 0.33 * indent_neck_back"/> + <point type="endLine" typeLine="hair" id="38" name="Г2" basePoint="34" lineColor="black" mx="1.32292" angle="0" my="2.64583" length="0.35 * bust_arc_f + 0.017 * height + #Пс_шс + #Пк_шс2"/> + <point type="endLine" typeLine="hair" id="39" name="Г3" basePoint="38" lineColor="black" mx="1.32292" angle="0" my="2.64583" length="0.3 * bust_arc_f + #Пшпр2"/> + <point type="endLine" typeLine="hair" id="40" name="Г4" basePoint="39" lineColor="black" mx="1.32292" angle="0" my="2.64583" length="0.35 * bust_arc_f + 0.01 * height + #Пс_шг + #Пк_шг2"/> + <point type="endLine" typeLine="hair" id="41" name="А2" basePoint="33" lineColor="black" mx="1.32292" angle="0" my="2.64583" length="0.35*neck_mid_circ + #Пшгс"/> + <point type="endLine" typeLine="none" id="42" name="Г5" basePoint="40" lineColor="black" mx="1.32292" angle="180" my="2.64583" length="Line_А_А2"/> + <point type="endLine" typeLine="hair" id="43" name="А3" basePoint="41" lineColor="black" mx="1.32292" angle="90" my="2.64583" length="0.35*Line_А_А2"/> + <point type="endLine" typeLine="hair" id="44" name="А20" basePoint="41" lineColor="black" mx="-2.08003" angle="135" my="6.61594" length="0.75*Line_А2_А3"/> + <point type="endLine" typeLine="hair" id="45" name="П" basePoint="38" lineColor="black" mx="1.32292" angle="90" my="2.64583" length="0.2 * bust_arc_f + 0.05 * height + #Пс_впрс+10"/> + <point type="endLine" typeLine="hair" id="46" name="П1" basePoint="35" lineColor="black" mx="28.6501" angle="0" my="-31.8727" length="Line_Г_Г2"/> + <point type="alongLine" typeLine="hair" id="47" name="П2" firstPoint="43" secondPoint="45" lineColor="black" mx="1.32292" my="2.64583" length="0.2 * bust_arc_f + 0.03 * height + #Пк_шп2 + #Ппос_шп"/> + <point type="alongLine" typeLine="none" id="48" name="П20" firstPoint="43" secondPoint="45" lineColor="black" mx="1.32292" my="2.64583" length="50"/> + <point type="endLine" typeLine="hair" id="49" name="П3" basePoint="39" lineColor="black" mx="1.32292" angle="90" my="2.64583" length="Line_Г2_П"/> + <point type="endLine" typeLine="hair" id="50" name="А4" basePoint="42" lineColor="black" mx="1.32292" angle="90" my="2.64583" length="Line_А_Г+Line_А2_А3"/> + <point type="alongLine" typeLine="hair" id="51" name="П4" firstPoint="50" secondPoint="49" lineColor="black" mx="-1.00541" my="-11.3242" length="Line_А3_П2"/> + <point type="endLine" typeLine="none" id="52" name="П5" basePoint="39" lineColor="black" mx="8.59896" angle="90" my="-2.01084" length="Line_Г3_П3*0.4444"/> + <line typeLine="hair" id="53" firstPoint="51" secondPoint="52" lineColor="black"/> + <point type="alongLine" typeLine="none" id="54" name="П7" firstPoint="52" secondPoint="51" lineColor="black" mx="-9.23943" my="2.64583" length="0.5*Line_П4_П5"/> + <point type="normal" typeLine="hair" id="55" name="П8" firstPoint="54" secondPoint="52" lineColor="black" mx="2.61006" angle="0" my="-10.595" length="1"/> + <point type="endLine" typeLine="none" id="56" name="Г6" basePoint="34" lineColor="black" mx="5.48569" angle="0" my="4.79765" length="0.5*(Line_Г_Г2+Line_Г2_Г3+Line_Г3_Г4)"/> + <point type="endLine" typeLine="hair" id="57" name="З" basePoint="38" lineColor="black" mx="-3.0442" angle="45" my="8.2607" length="0.24*Line_Г2_Г3"/> + <point type="endLine" typeLine="hair" id="58" name="З3" basePoint="39" lineColor="black" mx="0.0751693" angle="135" my="8.88457" length="0.24*Line_Г2_Г3"/> + <point type="endLine" typeLine="hair" id="59" name="А5" basePoint="50" lineColor="black" mx="1.32292" angle="0" my="2.64583" length="Line_А_А2"/> + <line typeLine="hair" id="60" firstPoint="59" secondPoint="40" lineColor="black"/> + <point type="alongLine" typeLine="none" id="61" name="А6" firstPoint="59" secondPoint="40" lineColor="black" mx="22.4896" my="-8.99584" length="0.82*Line_А4_А5"/> + <point type="alongLine" typeLine="none" id="62" name="А7" firstPoint="50" secondPoint="42" lineColor="black" mx="1.32292" my="2.64583" length="0.8*Line_А4_А5"/> + <line typeLine="hair" id="63" firstPoint="62" secondPoint="61" lineColor="black"/> + <point type="bisector" typeLine="hair" id="64" name="А51" thirdPoint="61" firstPoint="50" secondPoint="62" lineColor="black" mx="1.32292" my="2.64583" length="150"/> + <point type="lineIntersect" id="65" name="А50" p2Line1="59" p2Line2="64" p1Line1="50" p1Line2="62" mx="1.32292" my="2.64583"/> + <point type="pointOfContact" id="66" name="Ак" radius="Line_А4_А50" firstPoint="62" center="65" secondPoint="61" mx="1.32292" my="2.64583"/> + <point type="endLine" typeLine="hair" id="67" name="Т3" basePoint="36" lineColor="black" mx="1.32292" angle="0" my="2.64583" length="Line_Г_Г2+Line_Г2_Г3"/> + <line typeLine="hair" id="68" firstPoint="39" secondPoint="67" lineColor="black"/> + <point type="endLine" typeLine="hair" id="69" name="Т4" basePoint="67" lineColor="black" mx="1.32292" angle="0" my="2.64583" length="Line_Г3_Г4"/> + <line typeLine="hair" id="70" firstPoint="40" secondPoint="69" lineColor="black"/> + <point type="endLine" typeLine="hair" id="71" name="Н3" basePoint="37" lineColor="black" mx="1.32292" angle="0" my="2.64583" length="Line_Т3_Т4+Line_Т_Т3"/> + <line typeLine="hair" id="72" firstPoint="69" secondPoint="71" lineColor="black"/> + <point type="endLine" typeLine="none" id="73" name="Н5" basePoint="37" lineColor="black" mx="1.32292" angle="0" my="2.64583" length="Line_Г_Г6"/> + <line typeLine="hair" id="74" firstPoint="56" secondPoint="73" lineColor="black"/> + <line typeLine="hair" id="75" firstPoint="65" secondPoint="66" lineColor="black"/> + <arc type="simple" angle1="180" angle2="AngleLine_А50_Ак" id="76" radius="Line_А4_А50" center="65" color="black"/> + <spline type="pathInteractive" id="77" color="black"> + <pathPoint angle1="184.205" pSpline="33" angle2="4.20522" length1="0" length2="27.556"/> + <pathPoint angle1="215.751" pSpline="44" angle2="35.7515" length1="12.4503" length2="8.15772"/> + <pathPoint angle1="234.166" pSpline="43" angle2="54.166" length1="5.84299" length2="0"/> + </spline> + <spline type="pathInteractive" id="78" color="black"> + <pathPoint angle1="80.258" pSpline="47" angle2="260.258" length1="0" length2="20.8645"/> + <pathPoint angle1="87.674" pSpline="46" angle2="267.674" length1="30.751" length2="50.1703"/> + <pathPoint angle1="120.24" pSpline="57" angle2="300.24" length1="11.5169" length2="12.8071"/> + <pathPoint angle1="184.589" pSpline="56" angle2="4.58891" length1="12.5947" length2="0"/> + </spline> + <point type="endLine" typeLine="hair" id="79" name="П5н" basePoint="52" lineColor="black" mx="-13.6151" angle="180" my="5.24991" length="1"/> + <spline type="pathInteractive" id="80" color="black"> + <pathPoint angle1="101.835" pSpline="51" angle2="281.835" length1="0" length2="27.3441"/> + <pathPoint angle1="100.326" pSpline="55" angle2="280.326" length1="3.61809" length2="21.5186"/> + <pathPoint angle1="93.053" pSpline="79" angle2="273.053" length1="12.096" length2="38.3854"/> + <pathPoint angle1="56.906" pSpline="58" angle2="236.906" length1="13.1026" length2="8.79047"/> + <pathPoint angle1="355.114" pSpline="56" angle2="175.114" length1="9.58048" length2="0"/> + </spline> + <line typeLine="hair" id="81" firstPoint="43" secondPoint="50" lineColor="black"/> + <line typeLine="hair" id="82" firstPoint="47" secondPoint="51" lineColor="black"/> + <point type="alongLine" typeLine="none" id="83" name="П11" firstPoint="47" secondPoint="51" lineColor="black" mx="1.32292" my="2.64583" length="Line_П2_П4*0.5"/> + <point type="endLine" typeLine="none" id="86" name="Г81" basePoint="83" lineColor="black" mx="-23.9299" angle="270" my="11.8341" length="Line_А_Г"/> + <point type="lineIntersect" id="87" name="Г8" p2Line1="86" p2Line2="39" p1Line1="83" p1Line2="34" mx="-26.0772" my="7.75128"/> + <line typeLine="hair" id="88" firstPoint="87" secondPoint="83" lineColor="black"/> + <point type="endLine" typeLine="hair" id="89" name="К2" basePoint="67" lineColor="black" mx="1.32292" angle="0" my="2.64583" length="0.1*bust_arc_f"/> + <point type="endLine" typeLine="hair" id="90" name="К3" basePoint="89" lineColor="black" mx="1.32292" angle="80" my="2.64583" length="50"/> + <point type="endLine" typeLine="hair" id="91" name="К4" basePoint="89" lineColor="black" mx="1.32292" angle="260" my="2.64583" length="50"/> + <point type="endLine" typeLine="hair" id="92" name="К5" basePoint="90" lineColor="black" mx="1.32292" angle="170" my="2.64583" length="15"/> + <point type="endLine" typeLine="hair" id="93" name="К6" basePoint="91" lineColor="black" mx="1.32292" angle="170" my="2.64583" length="15"/> + <line typeLine="hair" id="94" firstPoint="92" secondPoint="93" lineColor="black"/> + <point type="alongLine" typeLine="hair" id="95" name="А41" firstPoint="50" secondPoint="49" lineColor="black" mx="1.32292" my="2.64583" length="20"/> + <line typeLine="hair" id="96" firstPoint="73" secondPoint="71" lineColor="black"/> + <point type="alongLine" typeLine="hair" id="97" name="Н31" firstPoint="73" secondPoint="71" lineColor="black" mx="1.32292" my="2.64583" length="Line_Н5_Н3-50"/> + <spline type="simpleInteractive" point4="97" angle1="286.103" angle2="92.0822" id="98" color="black" length1="160.559" length2="101.493" point1="95"/> + <point type="cutSplinePath" id="203" name="С1" splinePath="78" mx="23.5479" my="13.2292" length="SplPath_П2_Г6*0.5"/> + <point type="cutSplinePath" id="209" name="С3" splinePath="80" mx="18.0755" my="25.1094" length="SplPath_П4_Г6*0.5"/> + <point type="alongLine" typeLine="none" id="286" name="Ф1" firstPoint="33" secondPoint="36" lineColor="black" mx="1.32292" my="2.64583" length="Line_А_Т*0.205"/> + <point type="cutSplinePath" id="287" name="Ф2" splinePath="78" mx="1.32292" my="2.64583" length="SplPath_П2_С1*0.67"/> + <line typeLine="hair" id="290" firstPoint="286" secondPoint="287" lineColor="black"/> + <point type="alongLine" typeLine="none" id="291" name="Ф3" firstPoint="69" secondPoint="59" lineColor="black" mx="1.32292" my="2.64583" length="Line_Ф1_Т"/> + <point type="cutSplinePath" id="292" name="Ф4" splinePath="80" mx="1.32292" my="2.64583" length="SplPath_П4_С3*0.67"/> + <line typeLine="hair" id="295" firstPoint="292" secondPoint="291" lineColor="black"/> + </calculation> + <modeling> + <point type="modeling" inUse="true" id="296" idObject="33" mx="1.32292" my="2.64583"/> + <spline type="modelingPath" inUse="true" id="297" idObject="77"/> + <point type="modeling" inUse="true" id="298" idObject="43" mx="1.32292" my="2.64583"/> + <point type="modeling" inUse="true" id="299" idObject="47" mx="1.32292" my="2.64583"/> + <spline type="modelingPath" inUse="true" id="300" idObject="78"/> + <point type="modeling" inUse="true" id="301" idObject="287" mx="1.32292" my="2.64583"/> + <point type="modeling" inUse="true" id="302" idObject="286" mx="1.32292" my="2.64583"/> + </modeling> + <details> + <detail closed="0" id="303" name="Деталь" forbidFlipping="true" united="false" seamAllowance="true" width="7" mx="10.0402" inLayout="true" my="-26.0133" version="2"> + <data rotation="0" letter="" fontSize="0" visible="true" mx="0" width="0" my="0" height="0"/> + <patternInfo rotation="0" fontSize="0" visible="true" mx="0" width="0" my="0" height="0"/> + <grainline arrows="0" rotation="90" visible="false" mx="0" my="0" length="0"/> + <nodes> + <node type="NodePoint" idObject="299"/> + <node type="NodeSplinePath" reverse="0" idObject="300"/> + <node type="NodePoint" idObject="301"/> + <node type="NodePoint" after="0" idObject="302"/> + <node before="0" type="NodePoint" idObject="296"/> + <node type="NodeSplinePath" reverse="0" idObject="297"/> + <node type="NodePoint" idObject="298"/> + </nodes> + </detail> + </details> + <groups/> + </draw> + <draw name="Рукав"> + <calculation> + <point type="single" x="662.911" y="-31.3691" id="125" name="А" mx="1.32292" my="2.64583"/> + <point type="endLine" typeLine="hair" id="126" name="Н" basePoint="125" lineColor="black" mx="1.32292" angle="270" my="2.64583" length="0.33*height+0.15*bust_arc_f-50"/> + <point type="alongLine" typeLine="none" id="127" name="Б" firstPoint="125" secondPoint="126" lineColor="black" mx="1.32292" my="2.64583" length="0.3792*Line_Г8_П11"/> + <point type="endLine" typeLine="none" id="128" name="Б1" basePoint="127" lineColor="black" mx="1.32292" angle="0" my="2.64583" length="Line_Г2_Г3+#Пшр1"/> + <point type="endLine" typeLine="none" id="129" name="Б4" basePoint="127" lineColor="black" mx="1.32292" angle="180" my="2.64583" length="Line_Г2_Г3+#Пшр1"/> + <point type="endLine" typeLine="hair" id="130" name="Н1" basePoint="126" lineColor="black" mx="1.32292" angle="0" my="2.64583" length="0.6*Line_Б_Б1+38"/> + <line typeLine="hair" id="131" firstPoint="128" secondPoint="130" lineColor="black"/> + <point type="endLine" typeLine="hair" id="132" name="Н2" basePoint="126" lineColor="black" mx="1.32292" angle="180" my="2.64583" length="0.6*Line_Б_Б1+38"/> + <line typeLine="hair" id="133" firstPoint="129" secondPoint="132" lineColor="black"/> + <point type="alongLine" typeLine="hair" id="138" name="Б2" firstPoint="127" secondPoint="128" lineColor="black" mx="1.32292" my="2.64583" length="((0.5 * (SplPath_П2_Г6+SplPath_П4_Г6) +3)^2 - Line_А_Б^2)^0.5"/> + <point type="alongLine" typeLine="hair" id="139" name="Б3" firstPoint="127" secondPoint="129" lineColor="black" mx="1.32292" my="2.64583" length="((0.5 * (SplPath_П2_Г6+SplPath_П4_Г6) -8)^2 - Line_А_Б^2)^0.5"/> + <line typeLine="hair" id="140" firstPoint="125" secondPoint="138" lineColor="black"/> + <line typeLine="hair" id="141" firstPoint="125" secondPoint="139" lineColor="black"/> + <point type="alongLine" typeLine="none" id="142" name="А1" firstPoint="125" secondPoint="138" lineColor="black" mx="19.0616" my="-50.5702" length="Line_А_Б2*0.5"/> + <point type="alongLine" typeLine="none" id="143" name="А2" firstPoint="125" secondPoint="142" lineColor="black" mx="0.130208" my="6.82032" length="Line_А_А1*0.5"/> + <point type="alongLine" typeLine="none" id="144" name="А3" firstPoint="142" secondPoint="138" lineColor="black" mx="5.9633" my="-10.2441" length="Line_А1_Б2*0.5"/> + <point type="alongLine" typeLine="none" id="145" name="А1з" firstPoint="125" secondPoint="139" lineColor="black" mx="-4.43017" my="-60.6381" length="Line_А_Б3*0.5"/> + <point type="alongLine" typeLine="none" id="146" name="А2з" firstPoint="125" secondPoint="145" lineColor="black" mx="4.33266" my="4.97457" length="Line_А_А1з*0.5"/> + <point type="alongLine" typeLine="none" id="147" name="А3з" firstPoint="145" secondPoint="139" lineColor="black" mx="-2.80186" my="-13.3377" length="Line_А1з_Б3*0.5"/> + <point type="normal" typeLine="hair" id="148" name="А4" firstPoint="143" secondPoint="138" lineColor="black" mx="1.89007" angle="0" my="-12.1003" length="0.10*Line_А_Б"/> + <point type="normal" typeLine="hair" id="149" name="А4з" firstPoint="146" secondPoint="125" lineColor="black" mx="-15.3305" angle="0" my="-20.8475" length="0.10*Line_А_Б"/> + <point type="normal" typeLine="hair" id="150" name="А5" firstPoint="144" secondPoint="125" lineColor="black" mx="-5.89299" angle="0" my="6.80045" length="Line_А2_А4"/> + <point type="normal" typeLine="hair" id="151" name="А5з" firstPoint="147" secondPoint="139" lineColor="black" mx="2.85356" angle="0" my="5.92579" length="Line_А2з_А4з"/> + <line typeLine="hair" id="152" firstPoint="148" secondPoint="150" lineColor="black"/> + <line typeLine="hair" id="153" firstPoint="149" secondPoint="151" lineColor="black"/> + <point type="alongLine" typeLine="hair" id="154" name="О" firstPoint="148" secondPoint="143" lineColor="black" mx="-9.59601" my="-2.49453" length="Line_А2_А4*0.25"/> + <point type="alongLine" typeLine="hair" id="155" name="Оз" firstPoint="149" secondPoint="146" lineColor="black" mx="5.23899" my="-5.3851" length="Line_А2з_А4з*0.25"/> + <point type="alongLine" typeLine="hair" id="156" name="О1" firstPoint="150" secondPoint="144" lineColor="black" mx="8.1015" my="5.05114" length="Line_А4_О"/> + <point type="alongLine" typeLine="hair" id="157" name="О1з" firstPoint="151" secondPoint="147" lineColor="black" mx="-14.4209" my="2.20851" length="Line_А4з_Оз"/> + <point type="alongLine" typeLine="hair" id="158" name="О2" firstPoint="142" secondPoint="148" lineColor="black" mx="6.04115" my="-33.125" length="Line_А4_А5*0.25"/> + <point type="alongLine" typeLine="hair" id="159" name="О2з" firstPoint="145" secondPoint="149" lineColor="black" mx="8.66898" my="14.5691" length="Line_А4з_А5з*0.25"/> + <point type="alongLine" typeLine="hair" id="160" name="А6" firstPoint="144" secondPoint="150" lineColor="black" mx="9.12091" my="2.93381" length="Line_А3_А5*0.5"/> + <point type="alongLine" typeLine="hair" id="161" name="А6з" firstPoint="147" secondPoint="151" lineColor="black" mx="-12.8902" my="-0.415461" length="Line_А3з_А5з*0.5"/> + <point type="lineIntersect" id="162" name="О3" p2Line1="158" p2Line2="138" p1Line1="160" p1Line2="125" mx="5.68854" my="-6.37646"/> + <point type="lineIntersect" id="163" name="О3з" p2Line1="159" p2Line2="139" p1Line1="161" p1Line2="125" mx="-22.6642" my="-26.58"/> + <point type="alongLine" typeLine="hair" id="164" name="О4" firstPoint="160" secondPoint="144" lineColor="black" mx="13.8377" my="-4.63021" length="Line_А3_А6*0.25"/> + <point type="alongLine" typeLine="hair" id="165" name="О4з" firstPoint="161" secondPoint="147" lineColor="black" mx="7.08554" my="-5.9981" length="Line_А3з_А6з*0.25"/> + <spline type="pathInteractive" id="166" color="black"> + <pathPoint angle1="179.998" pSpline="125" angle2="359.998" length1="0" length2="12.3634"/> + <pathPoint angle1="153.959" pSpline="154" angle2="333.959" length1="14.6138" length2="5.85177"/> + <pathPoint angle1="153.373" pSpline="158" angle2="333.373" length1="5.10362" length2="9.46745"/> + <pathPoint angle1="152.532" pSpline="142" angle2="332.532" length1="5.90789" length2="19.9914"/> + <pathPoint angle1="158.016" pSpline="156" angle2="338.016" length1="13.1046" length2="12.3332"/> + <pathPoint angle1="173.032" pSpline="138" angle2="353.032" length1="17.7872" length2="0"/> + </spline> + <spline type="pathInteractive" id="167" color="black"> + <pathPoint angle1="1.148" pSpline="125" angle2="181.148" length1="0" length2="9.88634"/> + <pathPoint angle1="24.198" pSpline="155" angle2="204.198" length1="17.7795" length2="4.99338"/> + <pathPoint angle1="27.376" pSpline="159" angle2="207.376" length1="8.73578" length2="7.35637"/> + <pathPoint angle1="26.864" pSpline="163" angle2="206.864" length1="13.129" length2="8.98105"/> + <pathPoint angle1="25.87" pSpline="165" angle2="205.87" length1="13.1037" length2="6.12142"/> + <pathPoint angle1="9.899" pSpline="139" angle2="189.899" length1="17.6503" length2="0"/> + </spline> + <spline type="simpleInteractive" point4="138" angle1="84.068" angle2="255.161" id="168" color="black" length1="135.76" length2="82.0371" point1="130"/> + <spline type="simpleInteractive" point4="139" angle1="98.0171" angle2="286.671" id="169" color="black" length1="175.212" length2="76.4262" point1="132"/> + </calculation> + <modeling/> + <details/> + </draw> + <draw name="Комір"> + <calculation> + <point type="single" x="711.333" y="736.791" id="190" name="В" mx="1.32292" my="2.64583"/> + <point type="endLine" typeLine="hair" id="192" name="В1" basePoint="190" lineColor="black" mx="1.32292" angle="0" my="2.64583" length="SplPath_А_А3*2+(Arc_А50_76+Line_А6_Ак)*2"/> + <point type="endLine" typeLine="hair" id="193" name="В2" basePoint="190" lineColor="black" mx="1.32292" angle="90" my="2.64583" length="#Швс"/> + <point type="endLine" typeLine="hair" id="194" name="В3" basePoint="193" lineColor="black" mx="1.32292" angle="0" my="2.64583" length="SplPath_А_А3*2+(Arc_А50_76+Line_А6_Ак)*2"/> + <line typeLine="hair" id="195" firstPoint="194" secondPoint="192" lineColor="black"/> + </calculation> + <modeling/> + <details/> + </draw> + <draw name="капишон"> + <calculation> + <point type="single" x="-264.749" y="32.1467" id="224" name="А" mx="-8.83849" my="-20.0204"/> + <point type="endLine" typeLine="hair" id="225" name="Б" basePoint="224" lineColor="black" mx="1.32292" angle="270" my="2.64583" length="1.33*(height-height_neck_back)+#Пвк"/> + <point type="alongLine" typeLine="none" id="226" name="В" firstPoint="224" secondPoint="225" lineColor="black" mx="1.32292" my="2.64583" length="0.33*Line_А_Б"/> + <point type="alongLine" typeLine="none" id="227" name="Д" firstPoint="225" secondPoint="226" lineColor="black" mx="1.32292" my="2.64583" length="0.25*(height-height_neck_back)"/> + <point type="endLine" typeLine="hair" id="228" name="Г" basePoint="225" lineColor="black" mx="0.709236" angle="270" my="2.03215" length="0.33*Line_А5_А6"/> + <point type="endLine" typeLine="hair" id="229" name="А1" basePoint="224" lineColor="black" mx="1.32292" angle="0" my="2.64583" length="0.4*head_circ+#Пшк"/> + <point type="alongLine" typeLine="none" id="230" name="А2" firstPoint="229" secondPoint="224" lineColor="black" mx="1.32292" my="2.64583" length="Line_А_В"/> + <point type="endLine" typeLine="hair" id="231" name="В1" basePoint="226" lineColor="black" mx="1.32292" angle="0" my="2.64583" length="Line_А_А1"/> + <point type="alongLine" typeLine="none" id="232" name="В2" firstPoint="231" secondPoint="226" lineColor="black" mx="1.32292" my="2.64583" length="Line_А_В"/> + <line typeLine="hair" id="233" firstPoint="230" secondPoint="232" lineColor="black"/> + <point type="endLine" typeLine="hair" id="235" name="Г1" basePoint="228" lineColor="black" mx="8.68713" angle="180" my="2.03215" length="0.6*Line_А4_А5"/> + <point type="alongLine" typeLine="hair" id="236" name="Г2" firstPoint="235" secondPoint="228" lineColor="black" mx="1.32292" my="2.64583" length="SplPath_А_А3+Arc_А50_76+Line_А6_Ак"/> + <point type="endLine" typeLine="hair" id="237" name="Б1" basePoint="236" lineColor="black" mx="1.32292" angle="90" my="2.64583" length="Line_Б_Г"/> + <line typeLine="hair" id="238" firstPoint="225" secondPoint="237" lineColor="black"/> + <point type="endLine" typeLine="hair" id="239" name="Д1" basePoint="227" lineColor="black" mx="1.32292" angle="0" my="2.64583" length="Line_Б_Б1+2"/> + <line typeLine="hair" id="240" firstPoint="239" secondPoint="237" lineColor="black"/> + <point type="alongLine" typeLine="none" id="243" name="А4" firstPoint="224" secondPoint="226" lineColor="black" mx="1.32292" my="2.64583" length="8"/> + <point type="alongLine" typeLine="none" id="244" name="А3" firstPoint="224" secondPoint="230" lineColor="black" mx="1.32292" my="2.64583" length="0.65*Line_А2_А"/> + <line typeLine="hair" id="249" firstPoint="244" secondPoint="243" lineColor="black"/> + <point type="alongLine" typeLine="none" id="250" name="А5" firstPoint="244" secondPoint="243" lineColor="black" mx="1.32292" my="2.64583" length="Line_А3_А4+10"/> + <point type="endLine" typeLine="hair" id="254" name="Л" basePoint="235" lineColor="black" mx="1.32292" angle="90" my="2.64583" length="50"/> + <point type="alongLine" typeLine="none" id="255" name="Л1" firstPoint="228" secondPoint="227" lineColor="black" mx="6.63051" my="0.750261" length="Line_Г1_Л"/> + <line typeLine="hair" id="256" firstPoint="254" secondPoint="255" lineColor="black"/> + <spline type="simpleInteractive" point4="237" angle1="358.736" angle2="178.86" id="258" color="black" length1="122.19" length2="106.948" point1="235"/> + <spline type="pathInteractive" id="261" color="black"> + <pathPoint angle1="175.568" pSpline="230" angle2="355.568" length1="0" length2="79.6733"/> + <pathPoint angle1="81.86" pSpline="231" angle2="261.86" length1="54.8681" length2="104.96"/> + <pathPoint angle1="73.099" pSpline="237" angle2="253.099" length1="60.9341" length2="0"/> + </spline> + <spline type="pathInteractive" id="263" color="black"> + <pathPoint angle1="96.992" pSpline="250" angle2="276.992" length1="0" length2="39.4593"/> + <pathPoint angle1="94.44" pSpline="226" angle2="274.44" length1="31.3315" length2="57.3187"/> + <pathPoint angle1="2.828" pSpline="254" angle2="182.828" length1="65.4653" length2="0"/> + </spline> + <spline type="simpleInteractive" point4="230" angle1="11.0159" angle2="176.295" id="275" color="black" length1="53.2682" length2="26.8703" point1="250"/> + </calculation> + <modeling/> + <details/> + <groups/> + </draw> +</pattern> diff --git a/src/app/share/collection/test/merki27.vit b/src/app/share/collection/test/merki27.vit new file mode 100644 index 000000000..4b7527a98 --- /dev/null +++ b/src/app/share/collection/test/merki27.vit @@ -0,0 +1,24 @@ +<?xml version='1.0' encoding='UTF-8'?> +<vit> + <!--Measurements created with Valentina (http://www.valentina-project.org/).--> + <version>0.3.3</version> + <read-only>false</read-only> + <notes/> + <unit>cm</unit> + <pm_system>998</pm_system> + <personal> + <family-name/> + <given-name/> + <birth-date>1800-01-01</birth-date> + <gender>unknown</gender> + <email/> + </personal> + <body-measurements> + <m name="lowbust_circ" value="107"/> + <m name="hip_circ_with_abdomen" value="88"/> + <m name="waist_circ" value="60"/> + <m name="neck_back_to_waist_b" value="39"/> + <m name="waist_to_highhip_b" value="19"/> + <m name="arm_shoulder_tip_to_wrist" value="57"/> + </body-measurements> +</vit> diff --git a/src/app/share/collection/test/seamtest1.val b/src/app/share/collection/test/seamtest1.val new file mode 100644 index 000000000..d36f80aba --- /dev/null +++ b/src/app/share/collection/test/seamtest1.val @@ -0,0 +1,162 @@ +<?xml version='1.0' encoding='UTF-8'?> +<pattern> + <!--Pattern created with Valentina (http://www.valentina-project.org/).--> + <version>0.4.0</version> + <unit>cm</unit> + <author/> + <description/> + <notes/> + <measurements>merki27.vit</measurements> + <increments/> + <draw name="Чертеж 1"> + <calculation> + <point type="single" x="0.79375" y="1.05833" id="1" name="А" mx="0.132292" my="0.264583"/> + <point type="endLine" typeLine="hair" id="2" name="А1" basePoint="1" mx="0.132292" lineColor="black" angle="270" my="0.264583" length="neck_back_to_waist_b"/> + <point type="endLine" typeLine="hair" id="3" name="А2" basePoint="2" mx="0.132292" lineColor="black" angle="0" my="0.264583" length="lowbust_circ/2+6"/> + <point type="alongLine" typeLine="none" id="4" name="А3" firstPoint="1" secondPoint="2" mx="0.0821985" lineColor="black" my="0.21449" length="lowbust_circ/12+13.7"/> + <point type="pointOfIntersection" id="5" name="А4" firstPoint="3" secondPoint="4" mx="0.132292" my="0.264583"/> + <line typeLine="hair" id="6" firstPoint="5" secondPoint="3" lineColor="black"/> + <point type="endLine" typeLine="hair" id="7" name="А5" basePoint="4" mx="0.132292" lineColor="black" angle="0" my="0.264583" length="lowbust_circ/8+7.4"/> + <point type="pointOfIntersection" id="8" name="А6" firstPoint="7" secondPoint="1" mx="0.132292" my="0.264583"/> + <line typeLine="hair" id="9" firstPoint="1" secondPoint="8" lineColor="black"/> + <point type="alongLine" typeLine="none" id="10" name="А7" firstPoint="1" secondPoint="4" mx="0.132292" lineColor="black" my="0.264583" length="8"/> + <point type="pointOfIntersection" id="11" name="А8" firstPoint="8" secondPoint="10" mx="0.132292" my="0.264583"/> + <line typeLine="hair" id="12" firstPoint="10" secondPoint="11" lineColor="black"/> + <line typeLine="hair" id="14" firstPoint="11" secondPoint="7" lineColor="black"/> + <point type="alongLine" typeLine="none" id="15" name="А9" firstPoint="11" secondPoint="7" mx="0.132292" lineColor="black" my="0.264583" length="(Line_А8_А5/2)+0.5"/> + <point type="endLine" typeLine="hair" id="16" name="А10" basePoint="5" mx="0.132292" lineColor="black" angle="90" my="0.264583" length="lowbust_circ/5+8.3+1"/> + <point type="endLine" typeLine="hair" id="17" name="А11" basePoint="5" mx="0.132292" lineColor="black" angle="180" my="0.264583" length="lowbust_circ/8+6.2"/> + <point type="pointOfIntersection" id="18" name="А12" firstPoint="17" secondPoint="16" mx="0.132292" my="0.264583"/> + <line typeLine="hair" id="19" firstPoint="18" secondPoint="17" lineColor="black"/> + <line typeLine="hair" id="20" firstPoint="18" secondPoint="16" lineColor="black"/> + <point type="alongLine" typeLine="none" id="21" name="А13" firstPoint="17" secondPoint="7" mx="0.132292" lineColor="black" my="0.264583" length="lowbust_circ/32"/> + <point type="pointOfIntersection" id="22" name="А14" firstPoint="21" secondPoint="15" mx="0.132292" my="0.264583"/> + <point type="alongLine" typeLine="none" id="23" name="А15" firstPoint="5" secondPoint="17" mx="0.182385" lineColor="black" my="0.264583" length="(Line_А4_А11/2)+0.7"/> + <line typeLine="hair" id="24" firstPoint="22" secondPoint="23" lineColor="black"/> + <line typeLine="hair" id="25" firstPoint="21" secondPoint="17" lineColor="black"/> + <line typeLine="hair" id="26" firstPoint="21" secondPoint="22" lineColor="black"/> + <line typeLine="hair" id="27" firstPoint="11" secondPoint="8" lineColor="black"/> + <line typeLine="hair" id="28" firstPoint="7" secondPoint="21" lineColor="black"/> + <point type="alongLine" typeLine="none" id="29" name="А16" firstPoint="7" secondPoint="21" mx="0.132292" lineColor="black" my="0.264583" length="Line_А5_А13/2"/> + <point type="pointOfIntersection" id="30" name="А17" firstPoint="29" secondPoint="2" mx="0.132292" my="0.264583"/> + <line typeLine="hair" id="31" firstPoint="29" secondPoint="30" lineColor="black"/> + <point type="alongLine" typeLine="none" id="32" name="А18" firstPoint="10" secondPoint="11" mx="0.132292" lineColor="black" my="0.264583" length="(Line_А7_А8/2)+1"/> + <point type="alongLine" typeLine="none" id="33" name="А19" firstPoint="16" secondPoint="18" mx="0.172819" lineColor="black" my="0.264583" length="lowbust_circ/24+3.4"/> + <point type="alongLine" typeLine="none" id="34" name="А20" firstPoint="16" secondPoint="5" mx="0.132292" lineColor="black" my="0.264583" length="Line_А10_А19+0.5"/> + <point type="pointOfIntersection" id="35" name="А21" firstPoint="33" secondPoint="34" mx="0.132292" my="0.264583"/> + <line typeLine="hair" id="38" firstPoint="35" secondPoint="16" lineColor="black"/> + <point type="alongLine" typeLine="none" id="39" name="А22" firstPoint="35" secondPoint="16" mx="0.132292" lineColor="black" my="0.264583" length="(Line_А21_А10/3)-0.5"/> + <spline point4="34" type="simpleInteractive" angle1="cos=270" angle2="sin=180" id="40" length1="4.89524" color="black" length2="4.34579" point1="33"/> + <line typeLine="hair" id="41" firstPoint="34" secondPoint="35" lineColor="black"/> + <line typeLine="hair" id="42" firstPoint="33" secondPoint="35" lineColor="black"/> + <point type="alongLine" typeLine="none" id="43" name="А23" firstPoint="33" secondPoint="18" mx="0.132292" lineColor="black" my="0.264583" length="8"/> + <point type="endLine" typeLine="none" id="44" name="А24" basePoint="43" mx="0.132292" lineColor="black" angle="270" my="0.264583" length="3.2"/> + <point type="lineIntersect" id="45" name="А25" p2Line1="44" p2Line2="17" p1Line1="33" p1Line2="18" mx="0.132292" my="0.264583"/> + <point type="alongLine" typeLine="none" id="46" name="А26" firstPoint="33" secondPoint="45" mx="0.132292" lineColor="black" my="0.264583" length="Line_А19_А25+1.8"/> + <point type="alongLine" typeLine="none" id="47" name="А27" firstPoint="1" secondPoint="8" mx="-0.514964" lineColor="black" my="0.552252" length="Line_А10_А19+0.2"/> + <point type="endLine" typeLine="hair" id="48" name="А28" basePoint="47" mx="-1.00881" lineColor="black" angle="90" my="-1.66652" length="Line_А_А27/3"/> + <spline point4="48" type="simpleInteractive" angle1="max=0" angle2="235.888" id="49" length1="2.42673" color="black" length2="3.03166" point1="1"/> + <point type="endLine" typeLine="none" id="50" name="А29" basePoint="48" mx="-0.745481" lineColor="black" angle="0" my="-1.52022" length="8"/> + <point type="endLine" typeLine="none" id="51" name="А30" basePoint="50" mx="0.132292" lineColor="black" angle="270" my="0.264583" length="2.6"/> + <point type="pointOfIntersection" id="52" name="А31" firstPoint="32" secondPoint="48" mx="-0.921036" my="-1.57874"/> + <point type="lineIntersect" id="53" name="А32" p2Line1="51" p2Line2="32" p1Line1="48" p1Line2="52" mx="-2.0914" my="-1.31541"/> + <point type="alongLine" typeLine="none" id="54" name="А33" firstPoint="53" secondPoint="51" mx="-1.82807" lineColor="black" my="0.0305105" length="1.5"/> + <point type="alongLine" typeLine="none" id="55" name="А34" firstPoint="54" secondPoint="51" mx="0.34558" lineColor="black" my="4.05045" length="lowbust_circ/32-0.8"/> + <point type="alongLine" typeLine="none" id="56" name="А35" firstPoint="48" secondPoint="51" mx="0.132292" lineColor="black" my="0.264583" length="Line_А19_А26+Line_А33_А34"/> + <point dartP3="55" type="trueDarts" my1="-1.63726" my2="-2.89101" id="57" mx1="-0.423631" mx2="2.30483" name1="А36" point1="58" baseLineP1="48" point2="59" name2="А37" dartP1="54" baseLineP2="56" dartP2="32"/> + <line typeLine="hair" id="60" firstPoint="48" secondPoint="58" lineColor="black"/> + <line typeLine="hair" id="61" firstPoint="32" secondPoint="58" lineColor="black"/> + <line typeLine="hair" id="62" firstPoint="32" secondPoint="59" lineColor="black"/> + <line typeLine="hair" id="63" firstPoint="59" secondPoint="56" lineColor="black"/> + <point type="alongLine" typeLine="none" id="64" name="А38" firstPoint="33" secondPoint="44" mx="0.132292" lineColor="black" my="0.264583" length="Line_А28_А36"/> + <line typeLine="hair" id="65" firstPoint="33" secondPoint="64" lineColor="black"/> + <line typeLine="hair" id="66" firstPoint="23" secondPoint="64" lineColor="black"/> + <arc type="simple" angle1="AngleLine_А15_А38" angle2="180" id="67" radius="Line_А14_А15" center="23" color="black"/> + <point type="cutArc" arc="67" id="68" name="А39" mx="0.132292" my="0.264583" length="lowbust_circ/12-3.2"/> + <point type="alongLine" typeLine="none" id="69" name="А40" firstPoint="23" secondPoint="68" mx="-1.12242" lineColor="black" my="-1.69277" length="Line_А15_А38"/> + <line typeLine="hair" id="70" firstPoint="23" secondPoint="69" lineColor="black"/> + <operation type="rotation" suffix="а1" id="71" center="23" angle="AngleLine_А15_А40-AngleLine_А15_А38"> + <source> + <item idObject="46"/> + </source> + <destination> + <item idObject="72" mx="0.132292" my="0.264583"/> + </destination> + </operation> + <line typeLine="hair" id="73" firstPoint="69" secondPoint="72" lineColor="black"/> + <point type="normal" typeLine="hair" id="74" name="А41" firstPoint="56" secondPoint="59" mx="0.132292" lineColor="black" angle="0" my="0.264583" length="7"/> + <point type="normal" typeLine="hair" id="75" name="А42" firstPoint="72" secondPoint="69" mx="0.132292" lineColor="black" angle="180" my="0.264583" length="7"/> + <point type="bisector" typeLine="hair" id="77" thirdPoint="22" name="А43" firstPoint="29" secondPoint="21" mx="0.132292" lineColor="black" my="0.264583" length="Line_А5_А16/3+0.5"/> + <point type="bisector" typeLine="hair" id="78" thirdPoint="29" name="А44" firstPoint="15" secondPoint="7" mx="0.132292" lineColor="black" my="0.264583" length="Line_А5_А16/3+0.8"/> + <spline type="pathInteractive" id="100" color="black"> + <pathPoint angle1="180.19" pSpline="29" angle2="0.189514" length1="0" length2="5.5002"/> + <pathPoint angle1="261.299" pSpline="22" angle2="81.2993" length1="2.57033" length2="5.3812"/> + <pathPoint angle1="327.914" pSpline="72" angle2="147.914" length1="8.44184" length2="13.3029"/> + </spline> + <point type="alongLine" typeLine="none" id="116" name="А45" firstPoint="11" secondPoint="15" mx="0.132292" lineColor="black" my="0.264583" length="(Line_А8_А5/2)"/> + <spline type="pathInteractive" id="117" color="black"> + <pathPoint angle1="63.8459" pSpline="56" angle2="243.846" length1="0" length2="8.76616"/> + <pathPoint angle1="95.8866" pSpline="116" angle2="275.887" length1="1.32614" length2="2.74113"/> + <pathPoint angle1="180" pSpline="29" angle2="0" length1="5.03118" length2="1.36011"/> + </spline> + <operation type="moving" suffix="a1" id="149" angle="90.6703" length="40.35"> + <source> + <item idObject="117"/> + <item idObject="100"/> + </source> + <destination> + <item idObject="150" mx="2.14748e+09" my="2.14748e+09"/> + <item idObject="151" mx="2.14748e+09" my="2.14748e+09"/> + </destination> + </operation> + </calculation> + <modeling> + <point type="modeling" inUse="true" id="155" idObject="4" mx="0.0821985" my="0.21449"/> + <point type="modeling" inUse="true" id="156" idObject="1" mx="0.132292" my="0.264583"/> + <spline type="modelingSpline" inUse="true" id="157" idObject="49"/> + <point type="modeling" inUse="true" id="158" idObject="48" mx="-1.00881" my="-1.66652"/> + <point type="modeling" inUse="true" id="159" idObject="58" mx="-0.423631" my="-1.63726"/> + <point type="modeling" inUse="true" id="160" idObject="32" mx="0.132292" my="0.264583"/> + <point type="modeling" inUse="true" id="161" idObject="59" mx="2.30483" my="-2.89101"/> + <point type="modeling" inUse="true" id="162" idObject="56" mx="0.132292" my="0.264583"/> + <spline type="modelingPath" inUse="true" id="163" idObject="117"/> + <point type="modeling" inUse="true" id="164" idObject="29" mx="0.132292" my="0.264583"/> + </modeling> + <details> + <detail id="165" name="" forbidFlipping="true" seamAllowance="true" mx="1.41527" inLayout="true" width="1" my="3.02812" version="2"> + <nodes> + <node before="2" type="NodePoint" after="0" idObject="155"/> + <node before="0" type="NodePoint" idObject="156"/> + <node type="NodeSpline" reverse="0" idObject="157"/> + <node type="NodePoint" after="0" idObject="158"/> + <node before="0" type="NodePoint" idObject="159"/> + <node type="NodePoint" idObject="160"/> + <node type="NodePoint" after="0" idObject="161"/> + <node before="0" type="NodePoint" after="5" idObject="162"/> + <node type="NodeSplinePath" reverse="0" idObject="163"/> + <node before="5" type="NodePoint" after="0" idObject="164"/> + </nodes> + </detail> + </details> + <groups/> + </draw> + <draw name="Чертеж 2"> + <calculation> + <point type="single" x="36.3125" y="34.6144" id="141" name="Б" mx="0.132292" my="0.264583"/> + <point type="endLine" typeLine="hair" id="142" name="Б1" basePoint="141" mx="0.132292" lineColor="black" angle="0" my="0.264583" length="Line_А5_А16"/> + <point type="endLine" typeLine="hair" id="143" name="Б2" basePoint="141" mx="0.132292" lineColor="black" angle="90" my="0.264583" length="Line_А8_А5/2"/> + <point type="endLine" typeLine="hair" id="144" name="Б3" basePoint="143" mx="0.132292" lineColor="black" angle="90" my="0.264583" length="Line_Б_Б2"/> + <point type="endLine" typeLine="hair" id="145" name="Б4" basePoint="144" mx="0.132292" lineColor="black" angle="180" my="0.264583" length="Line_А18_А8"/> + <point type="endLine" typeLine="hair" id="146" name="Б5" basePoint="145" mx="0.132292" lineColor="black" angle="AngleLine_А18_А37" my="0.264583" length="Line_А18_А37"/> + <point type="endLine" typeLine="hair" id="147" name="Б6" basePoint="146" mx="0.132292" lineColor="black" angle="AngleLine_А37_А35" my="0.264583" length="Line_А37_А35"/> + <spline type="pathInteractive" id="148" color="black"> + <pathPoint angle1="64.6053" pSpline="147" angle2="243.846" length1="0" length2="8.76616"/> + <pathPoint angle1="Angle2SplPath_А35_А16_Seg_1" pSpline="143" angle2="275.887" length1="C2LengthSplPath_А35_А16_Seg_1" length2="2.74113"/> + <pathPoint angle1="Angle2SplPath_А35_А16" pSpline="142" angle2="0.12" length1="4.97078" length2="1.36701"/> + </spline> + </calculation> + <modeling/> + <details/> + <groups/> + </draw> +</pattern> diff --git a/src/app/share/collection/test/seamtest2.val b/src/app/share/collection/test/seamtest2.val new file mode 100644 index 000000000..751483d4e --- /dev/null +++ b/src/app/share/collection/test/seamtest2.val @@ -0,0 +1,42 @@ +<?xml version='1.0' encoding='UTF-8'?> +<pattern> + <!--Pattern created with Valentina (http://www.valentina-project.org/).--> + <version>0.4.0</version> + <unit>cm</unit> + <author/> + <description/> + <notes/> + <measurements/> + <increments/> + <draw name="Pattern piece 1"> + <calculation> + <point type="single" x="0.79375" y="1.05833" id="1" name="A" mx="0.132292" my="0.264583"/> + <point type="endLine" typeLine="hair" id="2" name="A1" basePoint="1" mx="0.132292" lineColor="black" my="0.264583" angle="0" length="10"/> + <point type="normal" typeLine="hair" id="3" name="A2" firstPoint="2" secondPoint="1" mx="0.132292" lineColor="black" my="0.264583" angle="0" length="5"/> + <point type="alongLine" typeLine="none" id="4" name="A3" firstPoint="1" secondPoint="3" mx="0.132292" lineColor="black" my="0.264583" length="CurrentLength/2"/> + <spline type="simpleInteractive" point4="3" angle1="236.89" angle2="209.202" id="5" color="black" length1="1.06381" length2="2.9538" point1="4"/> + <spline type="simpleInteractive" point4="4" angle1="241.792" angle2="241.791" id="6" color="black" length1="2.22517" length2="2.12741" point1="1"/> + </calculation> + <modeling> + <point type="modeling" inUse="true" id="12" idObject="1" mx="0.132292" my="0.264583"/> + <point type="modeling" inUse="true" id="13" idObject="2" mx="0.132292" my="0.264583"/> + <point type="modeling" inUse="true" id="14" idObject="3" mx="0.132292" my="0.264583"/> + <spline type="modelingSpline" inUse="true" id="15" idObject="5"/> + <point type="modeling" inUse="true" id="16" idObject="4" mx="0.132292" my="0.264583"/> + <spline type="modelingSpline" inUse="true" id="17" idObject="6"/> + </modeling> + <details> + <detail id="18" name="" forbidFlipping="true" seamAllowance="true" mx="0" inLayout="true" width="1" my="0" version="2"> + <nodes> + <node type="NodePoint" idObject="12"/> + <node type="NodePoint" idObject="13"/> + <node type="NodePoint" idObject="14"/> + <node type="NodeSpline" reverse="1" idObject="15"/> + <node before="1.01" type="NodePoint" after="1.01" idObject="16"/> + <node type="NodeSpline" reverse="1" idObject="17"/> + </nodes> + </detail> + </details> + <groups/> + </draw> +</pattern> diff --git a/src/app/share/collection/test/seamtest3.val b/src/app/share/collection/test/seamtest3.val new file mode 100644 index 000000000..2141cf046 --- /dev/null +++ b/src/app/share/collection/test/seamtest3.val @@ -0,0 +1,57 @@ +<?xml version='1.0' encoding='UTF-8'?> +<pattern> + <!--Pattern created with Valentina (http://www.valentina-project.org/).--> + <version>0.4.0</version> + <unit>cm</unit> + <author/> + <description/> + <notes/> + <measurements/> + <increments/> + <draw name="Pattern piece 1"> + <calculation> + <point type="single" x="0.79375" y="1.05833" id="1" name="A" mx="0.132292" my="0.264583"/> + <point type="endLine" typeLine="hair" id="2" name="A1" basePoint="1" mx="0.132292" lineColor="black" my="0.264583" angle="0" length="10"/> + <point type="normal" typeLine="hair" id="3" name="A2" firstPoint="2" secondPoint="1" mx="0.132292" lineColor="black" my="0.264583" angle="0" length="5"/> + <point type="alongLine" typeLine="none" id="4" name="A3" firstPoint="1" secondPoint="3" mx="0.132292" lineColor="black" my="0.264583" length="CurrentLength/2"/> + <point type="alongLine" typeLine="none" id="5" name="A4" firstPoint="4" secondPoint="3" mx="0.132292" lineColor="black" my="0.264583" length="CurrentLength/2"/> + <point type="alongLine" typeLine="none" id="6" name="A5" firstPoint="1" secondPoint="4" mx="0.132292" lineColor="black" my="0.264583" length="CurrentLength/2"/> + <spline type="pathInteractive" id="7" color="black"> + <pathPoint angle1="65.3764" pSpline="3" angle2="245.376" length1="0" length2="2.1538"/> + <pathPoint angle1="248.531" pSpline="5" angle2="68.531" length1="1.80107" length2="2.63289"/> + <pathPoint angle1="42.0794" pSpline="4" angle2="222.079" length1="0.714555" length2="3.76242"/> + <pathPoint angle1="50.1229" pSpline="6" angle2="230.123" length1="2.19303" length2="2.72501"/> + <pathPoint angle1="228.872" pSpline="1" angle2="48.872" length1="0.486869" length2="0"/> + </spline> + </calculation> + <modeling> + <point type="modeling" inUse="true" id="8" idObject="1" mx="0.132292" my="0.264583"/> + <point type="modeling" inUse="true" id="9" idObject="2" mx="0.132292" my="0.264583"/> + <point type="modeling" inUse="true" id="10" idObject="3" mx="0.132292" my="0.264583"/> + <spline type="modelingPath" inUse="true" id="11" idObject="7"/> + <point type="modeling" inUse="true" id="12" idObject="5" mx="0.132292" my="0.264583"/> + <spline type="modelingPath" inUse="true" id="13" idObject="7"/> + <point type="modeling" inUse="true" id="14" idObject="4" mx="0.132292" my="0.264583"/> + <spline type="modelingPath" inUse="true" id="15" idObject="7"/> + <point type="modeling" inUse="true" id="16" idObject="6" mx="0.132292" my="0.264583"/> + <spline type="modelingPath" inUse="true" id="17" idObject="7"/> + </modeling> + <details> + <detail id="18" name="" forbidFlipping="true" seamAllowance="true" mx="0" inLayout="true" width="1" my="0" version="2"> + <nodes> + <node type="NodePoint" idObject="8"/> + <node type="NodePoint" idObject="9"/> + <node type="NodePoint" idObject="10"/> + <node type="NodeSplinePath" reverse="0" idObject="11"/> + <node before="0.5" type="NodePoint" after="0.5" idObject="12"/> + <node type="NodeSplinePath" reverse="0" idObject="13"/> + <node type="NodePoint" idObject="14"/> + <node type="NodeSplinePath" reverse="0" idObject="15"/> + <node before="0.2" type="NodePoint" idObject="16"/> + <node type="NodeSplinePath" reverse="0" idObject="17"/> + </nodes> + </detail> + </details> + <groups/> + </draw> +</pattern> diff --git a/src/app/tape/tmainwindow.cpp b/src/app/tape/tmainwindow.cpp index e0be0b916..d6e4f6e63 100644 --- a/src/app/tape/tmainwindow.cpp +++ b/src/app/tape/tmainwindow.cpp @@ -1258,10 +1258,9 @@ void TMainWindow::ImportFromPattern() converter.Convert(); VDomDocument::ValidateXML(VPatternConverter::CurrentSchema, mPath); - VLitePattern *doc = new VLitePattern(); + QScopedPointer<VLitePattern> doc(new VLitePattern()); doc->setXMLContent(mPath); measurements = doc->ListMeasurements(); - delete doc; // close a pattern } catch (VException &e) { diff --git a/src/app/valentina/core/vtooloptionspropertybrowser.cpp b/src/app/valentina/core/vtooloptionspropertybrowser.cpp index b4426a712..09e22849e 100644 --- a/src/app/valentina/core/vtooloptionspropertybrowser.cpp +++ b/src/app/valentina/core/vtooloptionspropertybrowser.cpp @@ -76,7 +76,7 @@ void VToolOptionsPropertyBrowser::ClearPropertyBrowser() void VToolOptionsPropertyBrowser::ShowItemOptions(QGraphicsItem *item) { // This check helps to find missed tools in the switch - Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 50, "Not all tools were used in switch."); + Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 51, "Not all tools were used in switch."); switch (item->type()) { @@ -203,7 +203,7 @@ void VToolOptionsPropertyBrowser::UpdateOptions() } // This check helps to find missed tools in the switch - Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 50, "Not all tools were used in switch."); + Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 51, "Not all tools were used in switch."); switch (currentItem->type()) { @@ -348,7 +348,7 @@ void VToolOptionsPropertyBrowser::userChangedData(VPE::VProperty *property) } // This check helps to find missed tools in the switch - Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 50, "Not all tools were used in switch."); + Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 51, "Not all tools were used in switch."); switch (currentItem->type()) { diff --git a/src/app/valentina/dialogs/dialoghistory.cpp b/src/app/valentina/dialogs/dialoghistory.cpp index 7cd426595..a168827b8 100644 --- a/src/app/valentina/dialogs/dialoghistory.cpp +++ b/src/app/valentina/dialogs/dialoghistory.cpp @@ -212,7 +212,7 @@ QT_WARNING_DISABLE_GCC("-Wswitch-default") QString DialogHistory::Record(const VToolRecord &tool) { // This check helps to find missed tools in the switch - Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 50, "Not all tools were used in history."); + Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 51, "Not all tools were used in history."); const QDomElement domElem = doc->elementById(tool.getId()); if (domElem.isElement() == false) @@ -392,7 +392,7 @@ QString DialogHistory::Record(const VToolRecord &tool) } //Because "history" not only show history of pattern, but help restore current data for each pattern's //piece, we need add record about details and nodes, but don't show them. - case Tool::Detail: + case Tool::Piece: case Tool::UnionDetails: case Tool::NodeArc: case Tool::NodeElArc: @@ -404,6 +404,7 @@ QString DialogHistory::Record(const VToolRecord &tool) case Tool::FlippingByLine: case Tool::FlippingByAxis: case Tool::Move: + case Tool::PiecePath: return QString(); } } diff --git a/src/app/valentina/dialogs/vwidgetdetails.cpp b/src/app/valentina/dialogs/vwidgetdetails.cpp index 1942ca3fc..7fe50975a 100644 --- a/src/app/valentina/dialogs/vwidgetdetails.cpp +++ b/src/app/valentina/dialogs/vwidgetdetails.cpp @@ -31,7 +31,7 @@ #include "../ifc/xml/vabstractpattern.h" #include "../vpatterndb/vcontainer.h" #include "../vmisc/vabstractapplication.h" -#include "../vtools/undocommands/toggledetailinlayout.h" +#include "../vtools/undocommands/togglepieceinlayout.h" #include <QMenu> #include <QUndoStack> @@ -45,7 +45,7 @@ VWidgetDetails::VWidgetDetails(VContainer *data, VAbstractPattern *doc, QWidget { ui->setupUi(this); - FillTable(m_data->DataDetails()); + FillTable(m_data->DataPieces()); ui->tableWidget->setContextMenuPolicy(Qt::CustomContextMenu); @@ -62,7 +62,7 @@ VWidgetDetails::~VWidgetDetails() //--------------------------------------------------------------------------------------------------------------------- void VWidgetDetails::UpdateList() { - FillTable(m_data->DataDetails()); + FillTable(m_data->DataPieces()); } //--------------------------------------------------------------------------------------------------------------------- @@ -93,16 +93,16 @@ void VWidgetDetails::InLayoutStateChanged(int row, int column) return; } - const QHash<quint32, VDetail> *allDetails = m_data->DataDetails(); + const QHash<quint32, VPiece> *allDetails = m_data->DataPieces(); const bool inLayout = not allDetails->value(id).IsInLayout(); - ToggleDetailInLayout *togglePrint = new ToggleDetailInLayout(id, inLayout, m_data, m_doc); - connect(togglePrint, &ToggleDetailInLayout::UpdateList, this, &VWidgetDetails::UpdateList); + TogglePieceInLayout *togglePrint = new TogglePieceInLayout(id, inLayout, m_data, m_doc); + connect(togglePrint, &TogglePieceInLayout::UpdateList, this, &VWidgetDetails::UpdateList); qApp->getUndoStack()->push(togglePrint); } //--------------------------------------------------------------------------------------------------------------------- -void VWidgetDetails::FillTable(const QHash<quint32, VDetail> *details) +void VWidgetDetails::FillTable(const QHash<quint32, VPiece> *details) { const int selectedRow = ui->tableWidget->currentRow(); ui->tableWidget->clear(); @@ -114,7 +114,7 @@ void VWidgetDetails::FillTable(const QHash<quint32, VDetail> *details) while (i != details->constEnd()) { ++currentRow; - const VDetail det = i.value(); + const VPiece det = i.value(); QTableWidgetItem *item = new QTableWidgetItem(); item->setTextAlignment(Qt::AlignHCenter); @@ -134,7 +134,7 @@ void VWidgetDetails::FillTable(const QHash<quint32, VDetail> *details) ui->tableWidget->setItem(currentRow, 0, item); - QString name = det.getName(); + QString name = det.GetName(); if (name.isEmpty()) { name = tr("Unnamed"); @@ -158,7 +158,7 @@ void VWidgetDetails::FillTable(const QHash<quint32, VDetail> *details) //--------------------------------------------------------------------------------------------------------------------- void VWidgetDetails::ToggleSectionDetails(bool select) { - const QHash<quint32, VDetail> *allDetails = m_data->DataDetails(); + const QHash<quint32, VPiece> *allDetails = m_data->DataPieces(); if (allDetails->count() == 0) { return; @@ -172,8 +172,8 @@ void VWidgetDetails::ToggleSectionDetails(bool select) { if (not select == allDetails->value(id).IsInLayout()) { - ToggleDetailInLayout *togglePrint = new ToggleDetailInLayout(id, select, m_data, m_doc); - connect(togglePrint, &ToggleDetailInLayout::UpdateList, this, &VWidgetDetails::UpdateList); + TogglePieceInLayout *togglePrint = new TogglePieceInLayout(id, select, m_data, m_doc); + connect(togglePrint, &TogglePieceInLayout::UpdateList, this, &VWidgetDetails::UpdateList); qApp->getUndoStack()->push(togglePrint); } } @@ -193,7 +193,7 @@ void VWidgetDetails::ShowContextMenu(const QPoint &pos) QAction *actionInvertSelection = menu->addAction(tr("Invert selection")); - const QHash<quint32, VDetail> *allDetails = m_data->DataDetails(); + const QHash<quint32, VPiece> *allDetails = m_data->DataPieces(); if (allDetails->count() == 0) { return; @@ -201,7 +201,7 @@ void VWidgetDetails::ShowContextMenu(const QPoint &pos) int selectedDetails = 0; - QHash<quint32, VDetail>::const_iterator iter = allDetails->constBegin(); + auto iter = allDetails->constBegin(); while (iter != allDetails->constEnd()) { if(iter.value().IsInLayout()) @@ -220,7 +220,6 @@ void VWidgetDetails::ShowContextMenu(const QPoint &pos) actionSelectAll->setDisabled(true); } - QAction *selectedAction = menu->exec(ui->tableWidget->viewport()->mapToGlobal(pos)); bool select; @@ -250,8 +249,8 @@ void VWidgetDetails::ShowContextMenu(const QPoint &pos) { select = not allDetails->value(id).IsInLayout(); - ToggleDetailInLayout *togglePrint = new ToggleDetailInLayout(id, select, m_data, m_doc); - connect(togglePrint, &ToggleDetailInLayout::UpdateList, this, &VWidgetDetails::UpdateList); + TogglePieceInLayout *togglePrint = new TogglePieceInLayout(id, select, m_data, m_doc); + connect(togglePrint, &TogglePieceInLayout::UpdateList, this, &VWidgetDetails::UpdateList); qApp->getUndoStack()->push(togglePrint); } } diff --git a/src/app/valentina/dialogs/vwidgetdetails.h b/src/app/valentina/dialogs/vwidgetdetails.h index 987bb74d1..f33ce9efc 100644 --- a/src/app/valentina/dialogs/vwidgetdetails.h +++ b/src/app/valentina/dialogs/vwidgetdetails.h @@ -33,7 +33,7 @@ class VAbstractPattern; class VContainer; -class VDetail; +class VPiece; namespace Ui { @@ -65,7 +65,7 @@ private: VAbstractPattern *m_doc; VContainer *m_data; - void FillTable(const QHash<quint32, VDetail> *details); + void FillTable(const QHash<quint32, VPiece> *details); void ToggleSectionDetails(bool select); }; diff --git a/src/app/valentina/main.cpp b/src/app/valentina/main.cpp index 275dae711..530f40ac8 100644 --- a/src/app/valentina/main.cpp +++ b/src/app/valentina/main.cpp @@ -29,6 +29,7 @@ #include "mainwindow.h" #include "core/vapplication.h" #include "../fervor/fvupdater.h" +#include "../vpatterndb/vpiecenode.h" #include <QMessageBox> // For QT_REQUIRE_VERSION #include <QTimer> @@ -53,6 +54,8 @@ int main(int argc, char *argv[]) qt_qhash_seed.store(0); // Lock producing random attribute order in XML + qRegisterMetaTypeStreamOperators<VPieceNode>("VPieceNode"); + #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); // DPI support #endif diff --git a/src/app/valentina/mainwindow.cpp b/src/app/valentina/mainwindow.cpp index 8598c04ac..801df66a2 100644 --- a/src/app/valentina/mainwindow.cpp +++ b/src/app/valentina/mainwindow.cpp @@ -51,12 +51,14 @@ #include "../vwidgets/vmaingraphicsscene.h" #include "tools/drawTools/drawtools.h" #include "../vtools/dialogs/tooldialogs.h" -#include "tools/vtooldetail.h" +#include "tools/vtoolseamallowance.h" +#include "tools/nodeDetails/vtoolpiecepath.h" #include "tools/vtooluniondetails.h" #include "dialogs/dialogs.h" #include "dialogs/vwidgetgroups.h" #include "../vtools/undocommands/addgroup.h" #include "dialogs/vwidgetdetails.h" +#include "../vpatterndb/vpiecepath.h" #include <QInputDialog> #include <QtDebug> @@ -134,7 +136,7 @@ MainWindow::MainWindow(QWidget *parent) connect(doc, &VPattern::SetEnabledGUI, this, &MainWindow::SetEnabledGUI); connect(doc, &VPattern::CheckLayout, RECEIVER(this)[this]() { - if (pattern->DataDetails()->count() == 0) + if (pattern->DataPieces()->count() == 0) { if(not ui->actionDraw->isChecked()) { @@ -306,9 +308,9 @@ QPointF MainWindow::StartPositionNewPP() const //--------------------------------------------------------------------------------------------------------------------- void MainWindow::InitScenes() { - sceneDraw = new VMainGraphicsScene(); + sceneDraw = new VMainGraphicsScene(this); currentScene = sceneDraw; - qApp->setCurrentScene(currentScene); + qApp->setCurrentScene(¤tScene); connect(this, &MainWindow::EnableItemMove, sceneDraw, &VMainGraphicsScene::EnableItemMove); connect(this, &MainWindow::ItemsSelection, sceneDraw, &VMainGraphicsScene::ItemsSelection); @@ -330,7 +332,7 @@ void MainWindow::InitScenes() connect(sceneDraw, &VMainGraphicsScene::mouseMove, this, &MainWindow::MouseMove); - sceneDetails = new VMainGraphicsScene(); + sceneDetails = new VMainGraphicsScene(this); connect(this, &MainWindow::EnableItemMove, sceneDetails, &VMainGraphicsScene::EnableItemMove); connect(this, &MainWindow::EnableNodeLabelSelection, sceneDetails, &VMainGraphicsScene::ToggleNodeLabelSelection); @@ -398,16 +400,7 @@ QSharedPointer<VMeasurements> MainWindow::OpenMeasurementFile(const QString &pat throw e; } - const QStringList mList = m->ListAll(); - const QStringList pList = doc->ListMeasurements(); - - const QSet<QString> match = pList.toSet().subtract(mList.toSet()); - if (not match.isEmpty()) - { - VException e(tr("Measurement file doesn't include all required measurements.")); - e.AddMoreInformation(tr("Please, additionaly provide: %1").arg(QStringList(match.toList()).join(", "))); - throw e; - } + CheckRequiredMeasurements(m.data()); if (m->Type() == MeasurementsType::Standard) { @@ -524,6 +517,24 @@ bool MainWindow::UpdateMeasurements(const QString &path, int size, int height) return true; } +//--------------------------------------------------------------------------------------------------------------------- +void MainWindow::CheckRequiredMeasurements(const VMeasurements *m) +{ + const QSet<QString> match = doc->ListMeasurements().toSet().subtract(m->ListAll().toSet()); + if (not match.isEmpty()) + { + QList<QString> list = match.toList(); + for (int i = 0; i < list.size(); ++i) + { + list[i] = qApp->TrVars()->MToUser(list.at(i)); + } + + VException e(tr("Measurement file doesn't include all required measurements.")); + e.AddMoreInformation(tr("Please, additionaly provide: %1").arg(QStringList(list).join(", "))); + throw e; + } +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief SetToolButton set tool and show dialog. @@ -542,13 +553,35 @@ void MainWindow::SetToolButton(bool checked, Tool t, const QString &cursor, cons CancelTool(); emit EnableItemMove(false); currentTool = lastUsedTool = t; - QPixmap pixmap(cursor); + auto cursorResource = cursor; + if (qApp->devicePixelRatio() >= 2) + { + // Try to load HiDPI versions of the cursors if availible + auto cursorHidpiResource = QString(cursor).replace(".png", "@2x.png"); + if (QFileInfo(cursorResource).exists()) + { + cursorResource = cursorHidpiResource; + } + } + QPixmap pixmap(cursorResource); QCursor cur(pixmap, 2, 3); ui->view->setCursor(cur); helpLabel->setText(toolTip); ui->view->setShowToolOptions(false); dialogTool = new Dialog(pattern, 0, this); + switch(t) + { + case Tool::Midpoint: + dialogTool->Build(t); + break; + case Tool::PiecePath: + dialogTool->SetPiecesList(doc->GetActivePPPieces()); + break; + default: + break; + } + VMainGraphicsScene *scene = qobject_cast<VMainGraphicsScene *>(currentScene); SCASSERT(scene != nullptr) @@ -556,6 +589,7 @@ void MainWindow::SetToolButton(bool checked, Tool t, const QString &cursor, cons connect(scene, &VMainGraphicsScene::SelectedObject, dialogTool.data(), &DialogTool::SelectedObject); connect(dialogTool.data(), &DialogTool::DialogClosed, this, closeDialogSlot); connect(dialogTool.data(), &DialogTool::ToolTip, this, &MainWindow::ShowToolTip); + connect(ui->view, &VMainGraphicsView::MouseRelease, [this](){EndVisualization(true);}); ui->view->itemClicked(nullptr); } else @@ -579,45 +613,13 @@ template <typename Dialog, typename Func, typename Func2> * @param applyDialogSlot function to handle apply in dialog. */ void MainWindow::SetToolButtonWithApply(bool checked, Tool t, const QString &cursor, const QString &toolTip, - Func closeDialogSlot, Func2 applyDialogSlot) + Func closeDialogSlot, Func2 applyDialogSlot) { if (checked) { - CancelTool(); - emit EnableItemMove(false); - currentTool = lastUsedTool = t; - auto cursorResource = cursor; - if (qApp->devicePixelRatio() >= 2) - { - // Try to load HiDPI versions of the cursors if availible - auto cursorHidpiResource = QString(cursor).replace(".png", "@2x.png"); - if (QFileInfo(cursorResource).exists()) - { - cursorResource = cursorHidpiResource; - } - } - QPixmap pixmap(cursorResource); - QCursor cur(pixmap, 2, 3); - ui->view->setCursor(cur); - ui->view->setShowToolOptions(false); - helpLabel->setText(toolTip); - dialogTool = new Dialog(pattern, NULL_ID, this); + SetToolButton<Dialog>(checked, t, cursor, toolTip, closeDialogSlot); - if (t == Tool::Midpoint) - { - dialogTool->Build(t); - } - - VMainGraphicsScene *scene = qobject_cast<VMainGraphicsScene *>(currentScene); - SCASSERT(scene != nullptr) - - connect(scene, &VMainGraphicsScene::ChoosedObject, dialogTool.data(), &DialogTool::ChosenObject); - connect(scene, &VMainGraphicsScene::SelectedObject, dialogTool.data(), &DialogTool::SelectedObject); - connect(dialogTool.data(), &DialogTool::DialogClosed, this, closeDialogSlot); connect(dialogTool.data(), &DialogTool::DialogApplied, this, applyDialogSlot); - connect(dialogTool.data(), &DialogTool::ToolTip, this, &MainWindow::ShowToolTip); - connect(ui->view, &VMainGraphicsView::MouseRelease, RECEIVER(this)[this](){EndVisualization(true);}); - ui->view->itemClicked(nullptr); } else { @@ -653,7 +655,7 @@ void MainWindow::ClosedDialog(int result) * @param result result working dialog. */ template <typename DrawTool> -void MainWindow::ClosedDialogWithApply(int result) +void MainWindow::ClosedDialogWithApply(int result, VMainGraphicsScene *scene) { SCASSERT(not dialogTool.isNull()) if (result == QDialog::Accepted) @@ -661,7 +663,6 @@ void MainWindow::ClosedDialogWithApply(int result) // Only create tool if not already created with apply if (dialogTool->GetAssociatedTool() == nullptr) { - VMainGraphicsScene *scene = qobject_cast<VMainGraphicsScene *>(currentScene); SCASSERT(scene != nullptr) dialogTool->SetAssociatedTool( @@ -699,14 +700,13 @@ void MainWindow::ClosedDialogWithApply(int result) * @brief ApplyDialog handle apply in dialog */ template <typename DrawTool> -void MainWindow::ApplyDialog() +void MainWindow::ApplyDialog(VMainGraphicsScene *scene) { SCASSERT(not dialogTool.isNull()) // Only create tool if not already created with apply if (dialogTool->GetAssociatedTool() == nullptr) { - VMainGraphicsScene *scene = qobject_cast<VMainGraphicsScene *>(currentScene); SCASSERT(scene != nullptr) dialogTool->SetAssociatedTool( @@ -720,6 +720,34 @@ void MainWindow::ApplyDialog() } } +//--------------------------------------------------------------------------------------------------------------------- +template <typename DrawTool> +void MainWindow::ClosedDrawDialogWithApply(int result) +{ + ClosedDialogWithApply<DrawTool>(result, sceneDraw); +} + +//--------------------------------------------------------------------------------------------------------------------- +template <typename DrawTool> +void MainWindow::ApplyDrawDialog() +{ + ApplyDialog<DrawTool>(sceneDraw); +} + +//--------------------------------------------------------------------------------------------------------------------- +template <typename DrawTool> +void MainWindow::ClosedDetailsDialogWithApply(int result) +{ + ClosedDialogWithApply<DrawTool>(result, sceneDetails); +} + +//--------------------------------------------------------------------------------------------------------------------- +template <typename DrawTool> +void MainWindow::ApplyDetailsDialog() +{ + ApplyDialog<DrawTool>(sceneDetails); +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief ToolEndLine handler tool endLine. @@ -729,8 +757,8 @@ void MainWindow::ToolEndLine(bool checked) { ToolSelectPointByRelease(); SetToolButtonWithApply<DialogEndLine>(checked, Tool::EndLine, ":/cursor/endline_cursor.png", tr("Select point"), - &MainWindow::ClosedDialogWithApply<VToolEndLine>, - &MainWindow::ApplyDialog<VToolEndLine>); + &MainWindow::ClosedDrawDialogWithApply<VToolEndLine>, + &MainWindow::ApplyDrawDialog<VToolEndLine>); } //--------------------------------------------------------------------------------------------------------------------- @@ -742,8 +770,8 @@ void MainWindow::ToolLine(bool checked) { ToolSelectPointByRelease(); SetToolButtonWithApply<DialogLine>(checked, Tool::Line, ":/cursor/line_cursor.png", tr("Select first point"), - &MainWindow::ClosedDialogWithApply<VToolLine>, - &MainWindow::ApplyDialog<VToolLine>); + &MainWindow::ClosedDrawDialogWithApply<VToolLine>, + &MainWindow::ApplyDrawDialog<VToolLine>); } //--------------------------------------------------------------------------------------------------------------------- @@ -755,8 +783,8 @@ void MainWindow::ToolAlongLine(bool checked) { ToolSelectPointByRelease(); SetToolButtonWithApply<DialogAlongLine>(checked, Tool::AlongLine, ":/cursor/alongline_cursor.png", - tr("Select point"), &MainWindow::ClosedDialogWithApply<VToolAlongLine>, - &MainWindow::ApplyDialog<VToolAlongLine>); + tr("Select point"), &MainWindow::ClosedDrawDialogWithApply<VToolAlongLine>, + &MainWindow::ApplyDrawDialog<VToolAlongLine>); } //--------------------------------------------------------------------------------------------------------------------- @@ -765,8 +793,8 @@ void MainWindow::ToolMidpoint(bool checked) ToolSelectPointByRelease(); // Reuse DialogAlongLine and VToolAlongLine but with different cursor SetToolButtonWithApply<DialogAlongLine>(checked, Tool::Midpoint, ":/cursor/midpoint_cursor.png", - tr("Select point"), &MainWindow::ClosedDialogWithApply<VToolAlongLine>, - &MainWindow::ApplyDialog<VToolAlongLine>); + tr("Select point"), &MainWindow::ClosedDrawDialogWithApply<VToolAlongLine>, + &MainWindow::ApplyDrawDialog<VToolAlongLine>); } //--------------------------------------------------------------------------------------------------------------------- @@ -779,8 +807,8 @@ void MainWindow::ToolShoulderPoint(bool checked) ToolSelectPointByRelease(); SetToolButtonWithApply<DialogShoulderPoint>(checked, Tool::ShoulderPoint, ":/cursor/shoulder_cursor.png", tr("Select point"), - &MainWindow::ClosedDialogWithApply<VToolShoulderPoint>, - &MainWindow::ApplyDialog<VToolShoulderPoint>); + &MainWindow::ClosedDrawDialogWithApply<VToolShoulderPoint>, + &MainWindow::ApplyDrawDialog<VToolShoulderPoint>); } //--------------------------------------------------------------------------------------------------------------------- @@ -793,8 +821,8 @@ void MainWindow::ToolNormal(bool checked) ToolSelectPointByRelease(); SetToolButtonWithApply<DialogNormal>(checked, Tool::Normal, ":/cursor/normal_cursor.png", tr("Select first point of line"), - &MainWindow::ClosedDialogWithApply<VToolNormal>, - &MainWindow::ApplyDialog<VToolNormal>); + &MainWindow::ClosedDrawDialogWithApply<VToolNormal>, + &MainWindow::ApplyDrawDialog<VToolNormal>); } //--------------------------------------------------------------------------------------------------------------------- @@ -807,8 +835,8 @@ void MainWindow::ToolBisector(bool checked) ToolSelectPointByRelease(); SetToolButtonWithApply<DialogBisector>(checked, Tool::Bisector, ":/cursor/bisector_cursor.png", tr("Select first point of angle"), - &MainWindow::ClosedDialogWithApply<VToolBisector>, - &MainWindow::ApplyDialog<VToolBisector>); + &MainWindow::ClosedDrawDialogWithApply<VToolBisector>, + &MainWindow::ApplyDrawDialog<VToolBisector>); } //--------------------------------------------------------------------------------------------------------------------- @@ -821,8 +849,8 @@ void MainWindow::ToolLineIntersect(bool checked) ToolSelectPointByRelease(); SetToolButtonWithApply<DialogLineIntersect>(checked, Tool::LineIntersect, ":/cursor/intersect_cursor.png", tr("Select first point of first line"), - &MainWindow::ClosedDialogWithApply<VToolLineIntersect>, - &MainWindow::ApplyDialog<VToolLineIntersect>); + &MainWindow::ClosedDrawDialogWithApply<VToolLineIntersect>, + &MainWindow::ApplyDrawDialog<VToolLineIntersect>); } //--------------------------------------------------------------------------------------------------------------------- @@ -835,8 +863,8 @@ void MainWindow::ToolSpline(bool checked) ToolSelectPointByPress(); SetToolButtonWithApply<DialogSpline>(checked, Tool::Spline, ":/cursor/spline_cursor.png", tr("Select first point curve"), - &MainWindow::ClosedDialogWithApply<VToolSpline>, - &MainWindow::ApplyDialog<VToolSpline>); + &MainWindow::ClosedDrawDialogWithApply<VToolSpline>, + &MainWindow::ApplyDrawDialog<VToolSpline>); } //--------------------------------------------------------------------------------------------------------------------- @@ -845,8 +873,8 @@ void MainWindow::ToolCubicBezier(bool checked) ToolSelectPointByRelease(); SetToolButtonWithApply<DialogCubicBezier>(checked, Tool::CubicBezier, ":/cursor/cubic_bezier_cursor.png", tr("Select first curve point"), - &MainWindow::ClosedDialogWithApply<VToolCubicBezier>, - &MainWindow::ApplyDialog<VToolCubicBezier>); + &MainWindow::ClosedDrawDialogWithApply<VToolCubicBezier>, + &MainWindow::ApplyDrawDialog<VToolCubicBezier>); } //--------------------------------------------------------------------------------------------------------------------- @@ -859,8 +887,8 @@ void MainWindow::ToolCutSpline(bool checked) ToolSelectSpline(); SetToolButtonWithApply<DialogCutSpline>(checked, Tool::CutSpline, ":/cursor/spline_cut_point_cursor.png", tr("Select simple curve"), - &MainWindow::ClosedDialogWithApply<VToolCutSpline>, - &MainWindow::ApplyDialog<VToolCutSpline>); + &MainWindow::ClosedDrawDialogWithApply<VToolCutSpline>, + &MainWindow::ApplyDrawDialog<VToolCutSpline>); } //--------------------------------------------------------------------------------------------------------------------- @@ -872,8 +900,9 @@ void MainWindow::ToolArc(bool checked) { ToolSelectPointByRelease(); SetToolButtonWithApply<DialogArc>(checked, Tool::Arc, ":/cursor/arc_cursor.png", - tr("Select point of center of arc"), &MainWindow::ClosedDialogWithApply<VToolArc>, - &MainWindow::ApplyDialog<VToolArc>); + tr("Select point of center of arc"), + &MainWindow::ClosedDrawDialogWithApply<VToolArc>, + &MainWindow::ApplyDrawDialog<VToolArc>); } //--------------------------------------------------------------------------------------------------------------------- @@ -885,9 +914,9 @@ void MainWindow::ToolEllipticalArc(bool checked) { ToolSelectPointByRelease(); SetToolButtonWithApply<DialogEllipticalArc>(checked, Tool::EllipticalArc, ":/cursor/el_arc_cursor.png", - tr("Select point of center of elliptical arc"), - &MainWindow::ClosedDialogWithApply<VToolEllipticalArc>, - &MainWindow::ApplyDialog<VToolEllipticalArc>); + tr("Select point of center of elliptical arc"), + &MainWindow::ClosedDrawDialogWithApply<VToolEllipticalArc>, + &MainWindow::ApplyDrawDialog<VToolEllipticalArc>); } //--------------------------------------------------------------------------------------------------------------------- @@ -900,8 +929,8 @@ void MainWindow::ToolSplinePath(bool checked) ToolSelectPointByPress(); SetToolButtonWithApply<DialogSplinePath>(checked, Tool::SplinePath, ":/cursor/splinepath_cursor.png", tr("Select point of curve path"), - &MainWindow::ClosedDialogWithApply<VToolSplinePath>, - &MainWindow::ApplyDialog<VToolSplinePath>); + &MainWindow::ClosedDrawDialogWithApply<VToolSplinePath>, + &MainWindow::ApplyDrawDialog<VToolSplinePath>); } //--------------------------------------------------------------------------------------------------------------------- @@ -911,8 +940,8 @@ void MainWindow::ToolCubicBezierPath(bool checked) SetToolButtonWithApply<DialogCubicBezierPath>(checked, Tool::CubicBezierPath, ":/cursor/cubic_bezier_path_cursor.png", tr("Select point of cubic bezier path"), - &MainWindow::ClosedDialogWithApply<VToolCubicBezierPath>, - &MainWindow::ApplyDialog<VToolCubicBezierPath>); + &MainWindow::ClosedDrawDialogWithApply<VToolCubicBezierPath>, + &MainWindow::ApplyDrawDialog<VToolCubicBezierPath>); } //--------------------------------------------------------------------------------------------------------------------- @@ -925,8 +954,8 @@ void MainWindow::ToolCutSplinePath(bool checked) ToolSelectSplinePath(); SetToolButtonWithApply<DialogCutSplinePath>(checked, Tool::CutSplinePath, ":/cursor/splinepath_cut_point_cursor.png", tr("Select curve path"), - &MainWindow::ClosedDialogWithApply<VToolCutSplinePath>, - &MainWindow::ApplyDialog<VToolCutSplinePath>); + &MainWindow::ClosedDrawDialogWithApply<VToolCutSplinePath>, + &MainWindow::ApplyDrawDialog<VToolCutSplinePath>); } //--------------------------------------------------------------------------------------------------------------------- @@ -939,8 +968,8 @@ void MainWindow::ToolPointOfContact(bool checked) ToolSelectPointByRelease(); SetToolButtonWithApply<DialogPointOfContact>(checked, Tool::PointOfContact, ":/cursor/pointcontact_cursor.png", tr("Select first point of line"), - &MainWindow::ClosedDialogWithApply<VToolPointOfContact>, - &MainWindow::ApplyDialog<VToolPointOfContact>); + &MainWindow::ClosedDrawDialogWithApply<VToolPointOfContact>, + &MainWindow::ApplyDrawDialog<VToolPointOfContact>); } //--------------------------------------------------------------------------------------------------------------------- @@ -951,23 +980,19 @@ void MainWindow::ToolPointOfContact(bool checked) void MainWindow::ToolDetail(bool checked) { ToolSelectAllDrawObjects(); - SetToolButton<DialogDetail>(checked, Tool::Detail, "://cursor/new_detail_cursor.png", - tr("Select points, arcs, curves clockwise."), &MainWindow::ClosedDialogDetail); + SetToolButtonWithApply<DialogSeamAllowance>(checked, Tool::Piece, "://cursor/new_detail_cursor.png", + tr("Select main path objects clockwise."), + &MainWindow::ClosedDetailsDialogWithApply<VToolSeamAllowance>, + &MainWindow::ApplyDetailsDialog<VToolSeamAllowance>); } //--------------------------------------------------------------------------------------------------------------------- -/** - * @brief ClosedDialogDetail actions after closing DialogDetail. - * @param result result of dialog working. - */ -void MainWindow::ClosedDialogDetail(int result) +void MainWindow::ToolPiecePath(bool checked) { - if (result == QDialog::Accepted) - { - VToolDetail::Create(dialogTool, sceneDetails, doc, pattern); - } - ArrowTool(); - doc->LiteParseTree(Document::LiteParse); + ToolSelectAllDrawObjects(); + SetToolButton<DialogPiecePath>(checked, Tool::PiecePath, "://cursor/path_cursor.png", + tr("Select path objects, <b>Shift</b> - reverse direction curve"), + &MainWindow::ClosedDialogPiecePath); } //--------------------------------------------------------------------------------------------------------------------- @@ -979,8 +1004,8 @@ void MainWindow::ToolHeight(bool checked) { ToolSelectPointByRelease(); SetToolButtonWithApply<DialogHeight>(checked, Tool::Height, ":/cursor/height_cursor.png", tr("Select base point"), - &MainWindow::ClosedDialogWithApply<VToolHeight>, - &MainWindow::ApplyDialog<VToolHeight>); + &MainWindow::ClosedDrawDialogWithApply<VToolHeight>, + &MainWindow::ApplyDrawDialog<VToolHeight>); } //--------------------------------------------------------------------------------------------------------------------- @@ -993,8 +1018,8 @@ void MainWindow::ToolTriangle(bool checked) ToolSelectPointByRelease(); SetToolButtonWithApply<DialogTriangle>(checked, Tool::Triangle, ":/cursor/triangle_cursor.png", tr("Select first point of axis"), - &MainWindow::ClosedDialogWithApply<VToolTriangle>, - &MainWindow::ApplyDialog<VToolTriangle>); + &MainWindow::ClosedDrawDialogWithApply<VToolTriangle>, + &MainWindow::ApplyDrawDialog<VToolTriangle>); } //--------------------------------------------------------------------------------------------------------------------- @@ -1008,8 +1033,8 @@ void MainWindow::ToolPointOfIntersection(bool checked) SetToolButtonWithApply<DialogPointOfIntersection>(checked, Tool::PointOfIntersection, ":/cursor/pointofintersect_cursor.png", tr("Select point for X value (vertical)"), - &MainWindow::ClosedDialogWithApply<VToolPointOfIntersection>, - &MainWindow::ApplyDialog<VToolPointOfIntersection>); + &MainWindow::ClosedDrawDialogWithApply<VToolPointOfIntersection>, + &MainWindow::ApplyDrawDialog<VToolPointOfIntersection>); } //--------------------------------------------------------------------------------------------------------------------- @@ -1051,8 +1076,8 @@ void MainWindow::ToolRotation(bool checked) SetToolButtonWithApply<DialogRotation>(checked, Tool::Rotation, ":/cursor/rotation_cursor.png", tr("Select one or more objects, <b>Enter</b> - confirm selection"), - &MainWindow::ClosedDialogWithApply<VToolRotation>, - &MainWindow::ApplyDialog<VToolRotation>); + &MainWindow::ClosedDrawDialogWithApply<VToolRotation>, + &MainWindow::ApplyDrawDialog<VToolRotation>); } //--------------------------------------------------------------------------------------------------------------------- @@ -1062,8 +1087,8 @@ void MainWindow::ToolFlippingByLine(bool checked) SetToolButtonWithApply<DialogFlippingByLine>(checked, Tool::FlippingByLine, ":/cursor/flipping_line_cursor.png", tr("Select one or more objects, <b>Enter</b> - confirm selection"), - &MainWindow::ClosedDialogWithApply<VToolFlippingByLine>, - &MainWindow::ApplyDialog<VToolFlippingByLine>); + &MainWindow::ClosedDrawDialogWithApply<VToolFlippingByLine>, + &MainWindow::ApplyDrawDialog<VToolFlippingByLine>); } //--------------------------------------------------------------------------------------------------------------------- @@ -1073,8 +1098,8 @@ void MainWindow::ToolFlippingByAxis(bool checked) SetToolButtonWithApply<DialogFlippingByAxis>(checked, Tool::FlippingByAxis, ":/cursor/flipping_axis_cursor.png", tr("Select one or more objects, <b>Enter</b> - confirm selection"), - &MainWindow::ClosedDialogWithApply<VToolFlippingByAxis>, - &MainWindow::ApplyDialog<VToolFlippingByAxis>); + &MainWindow::ClosedDrawDialogWithApply<VToolFlippingByAxis>, + &MainWindow::ApplyDrawDialog<VToolFlippingByAxis>); } //--------------------------------------------------------------------------------------------------------------------- @@ -1084,8 +1109,8 @@ void MainWindow::ToolMove(bool checked) SetToolButtonWithApply<DialogMove>(checked, Tool::Move, ":/cursor/move_cursor.png", tr("Select one or more objects, <b>Enter</b> - confirm selection"), - &MainWindow::ClosedDialogWithApply<VToolMove>, - &MainWindow::ApplyDialog<VToolMove>); + &MainWindow::ClosedDrawDialogWithApply<VToolMove>, + &MainWindow::ApplyDrawDialog<VToolMove>); } //--------------------------------------------------------------------------------------------------------------------- @@ -1107,6 +1132,20 @@ void MainWindow::ClosedDialogGroup(int result) ArrowTool(); } +//--------------------------------------------------------------------------------------------------------------------- +void MainWindow::ClosedDialogPiecePath(int result) +{ + SCASSERT(dialogTool != nullptr); + if (result == QDialog::Accepted) + { + DialogPiecePath *dialog = qobject_cast<DialogPiecePath*>(dialogTool); + SCASSERT(dialog != nullptr); + VToolPiecePath::Create(dialogTool, sceneDetails, doc, pattern); + } + ArrowTool(); + doc->LiteParseTree(Document::LiteParse); +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief ToolCutArc handler tool cutArc. @@ -1116,8 +1155,8 @@ void MainWindow::ToolCutArc(bool checked) { ToolSelectArc(); SetToolButtonWithApply<DialogCutArc>(checked, Tool::CutArc, ":/cursor/arc_cut_cursor.png", - tr("Select arc"), &MainWindow::ClosedDialogWithApply<VToolCutArc>, - &MainWindow::ApplyDialog<VToolCutArc>); + tr("Select arc"), &MainWindow::ClosedDrawDialogWithApply<VToolCutArc>, + &MainWindow::ApplyDrawDialog<VToolCutArc>); } //--------------------------------------------------------------------------------------------------------------------- @@ -1127,8 +1166,8 @@ void MainWindow::ToolLineIntersectAxis(bool checked) SetToolButtonWithApply<DialogLineIntersectAxis>(checked, Tool::LineIntersectAxis, ":/cursor/line_intersect_axis_cursor.png", tr("Select first point of line"), - &MainWindow::ClosedDialogWithApply<VToolLineIntersectAxis>, - &MainWindow::ApplyDialog<VToolLineIntersectAxis>); + &MainWindow::ClosedDrawDialogWithApply<VToolLineIntersectAxis>, + &MainWindow::ApplyDrawDialog<VToolLineIntersectAxis>); } //--------------------------------------------------------------------------------------------------------------------- @@ -1138,8 +1177,8 @@ void MainWindow::ToolCurveIntersectAxis(bool checked) SetToolButtonWithApply<DialogCurveIntersectAxis>(checked, Tool::CurveIntersectAxis, ":/cursor/curve_intersect_axis_cursor.png", tr("Select curve"), - &MainWindow::ClosedDialogWithApply<VToolCurveIntersectAxis>, - &MainWindow::ApplyDialog<VToolCurveIntersectAxis>); + &MainWindow::ClosedDrawDialogWithApply<VToolCurveIntersectAxis>, + &MainWindow::ApplyDrawDialog<VToolCurveIntersectAxis>); } //--------------------------------------------------------------------------------------------------------------------- @@ -1150,8 +1189,8 @@ void MainWindow::ToolArcIntersectAxis(bool checked) SetToolButtonWithApply<DialogCurveIntersectAxis>(checked, Tool::ArcIntersectAxis, ":/cursor/arc_intersect_axis_cursor.png", tr("Select arc"), - &MainWindow::ClosedDialogWithApply<VToolCurveIntersectAxis>, - &MainWindow::ApplyDialog<VToolCurveIntersectAxis>); + &MainWindow::ClosedDrawDialogWithApply<VToolCurveIntersectAxis>, + &MainWindow::ApplyDrawDialog<VToolCurveIntersectAxis>); } //--------------------------------------------------------------------------------------------------------------------- @@ -1161,8 +1200,8 @@ void MainWindow::ToolPointOfIntersectionArcs(bool checked) SetToolButtonWithApply<DialogPointOfIntersectionArcs>(checked, Tool::PointOfIntersectionArcs, "://cursor/point_of_intersection_arcs.png", tr("Select first an arc"), - &MainWindow::ClosedDialogWithApply<VToolPointOfIntersectionArcs>, - &MainWindow::ApplyDialog<VToolPointOfIntersectionArcs>); + &MainWindow::ClosedDrawDialogWithApply<VToolPointOfIntersectionArcs>, + &MainWindow::ApplyDrawDialog<VToolPointOfIntersectionArcs>); } //--------------------------------------------------------------------------------------------------------------------- @@ -1172,8 +1211,8 @@ void MainWindow::ToolPointOfIntersectionCircles(bool checked) SetToolButtonWithApply<DialogPointOfIntersectionCircles>(checked, Tool::PointOfIntersectionCircles, "://cursor/point_of_intersection_circles.png", tr("Select first circle center"), - &MainWindow::ClosedDialogWithApply<VToolPointOfIntersectionCircles>, - &MainWindow::ApplyDialog<VToolPointOfIntersectionCircles>); + &MainWindow::ClosedDrawDialogWithApply<VToolPointOfIntersectionCircles>, + &MainWindow::ApplyDrawDialog<VToolPointOfIntersectionCircles>); } //--------------------------------------------------------------------------------------------------------------------- @@ -1183,8 +1222,8 @@ void MainWindow::ToolPointOfIntersectionCurves(bool checked) SetToolButtonWithApply<DialogPointOfIntersectionCurves>(checked, Tool::PointOfIntersectionCurves, "://cursor/intersection_curves_cursor.png", tr("Select first curve"), - &MainWindow::ClosedDialogWithApply<VToolPointOfIntersectionCurves>, - &MainWindow::ApplyDialog<VToolPointOfIntersectionCurves>); + &MainWindow::ClosedDrawDialogWithApply<VToolPointOfIntersectionCurves>, + &MainWindow::ApplyDrawDialog<VToolPointOfIntersectionCurves>); } //--------------------------------------------------------------------------------------------------------------------- @@ -1194,8 +1233,8 @@ void MainWindow::ToolPointFromCircleAndTangent(bool checked) SetToolButtonWithApply<DialogPointFromCircleAndTangent>(checked, Tool::PointFromCircleAndTangent, "://cursor/point_from_circle_and_tangent_cursor.png", tr("Select point on tangent"), - &MainWindow::ClosedDialogWithApply<VToolPointFromCircleAndTangent>, - &MainWindow::ApplyDialog<VToolPointFromCircleAndTangent>); + &MainWindow::ClosedDrawDialogWithApply<VToolPointFromCircleAndTangent>, + &MainWindow::ApplyDrawDialog<VToolPointFromCircleAndTangent>); } //--------------------------------------------------------------------------------------------------------------------- @@ -1205,8 +1244,8 @@ void MainWindow::ToolPointFromArcAndTangent(bool checked) SetToolButtonWithApply<DialogPointFromArcAndTangent>(checked, Tool::PointFromArcAndTangent, "://cursor/point_from_arc_and_tangent_cursor.png", tr("Select point on tangent"), - &MainWindow::ClosedDialogWithApply<VToolPointFromArcAndTangent>, - &MainWindow::ApplyDialog<VToolPointFromArcAndTangent>); + &MainWindow::ClosedDrawDialogWithApply<VToolPointFromArcAndTangent>, + &MainWindow::ApplyDrawDialog<VToolPointFromArcAndTangent>); } //--------------------------------------------------------------------------------------------------------------------- @@ -1216,8 +1255,8 @@ void MainWindow::ToolArcWithLength(bool checked) SetToolButtonWithApply<DialogArcWithLength>(checked, Tool::ArcWithLength, "://cursor/arc_with_length_cursor.png", tr("Select point of the center of the arc"), - &MainWindow::ClosedDialogWithApply<VToolArcWithLength>, - &MainWindow::ApplyDialog<VToolArcWithLength>); + &MainWindow::ClosedDrawDialogWithApply<VToolArcWithLength>, + &MainWindow::ApplyDrawDialog<VToolArcWithLength>); } //--------------------------------------------------------------------------------------------------------------------- @@ -1227,8 +1266,8 @@ void MainWindow::ToolTrueDarts(bool checked) SetToolButtonWithApply<DialogTrueDarts>(checked, Tool::TrueDarts, "://cursor/true_darts_cursor.png", tr("Select the first base line point"), - &MainWindow::ClosedDialogWithApply<VToolTrueDarts>, - &MainWindow::ApplyDialog<VToolTrueDarts>); + &MainWindow::ClosedDrawDialogWithApply<VToolTrueDarts>, + &MainWindow::ApplyDrawDialog<VToolTrueDarts>); } //--------------------------------------------------------------------------------------------------------------------- @@ -1674,6 +1713,7 @@ void MainWindow::ToolBarDraws() }); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ToolBarTools() { /*First we will try use Standard Shortcuts from Qt, but because keypad "-" and "+" not the same keys like in main @@ -1721,6 +1761,9 @@ void MainWindow::InitToolButtons() connect(pointer, &QToolButton::clicked, this, &MainWindow::ArrowTool); } + // This check helps to find missed tools + Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 51, "Check if all tools were connected."); + connect(ui->toolButtonEndLine, &QToolButton::clicked, this, &MainWindow::ToolEndLine); connect(ui->toolButtonLine, &QToolButton::clicked, this, &MainWindow::ToolLine); connect(ui->toolButtonAlongLine, &QToolButton::clicked, this, &MainWindow::ToolAlongLine); @@ -1735,6 +1778,7 @@ void MainWindow::InitToolButtons() connect(ui->toolButtonCubicBezierPath, &QToolButton::clicked, this, &MainWindow::ToolCubicBezierPath); connect(ui->toolButtonPointOfContact, &QToolButton::clicked, this, &MainWindow::ToolPointOfContact); connect(ui->toolButtonNewDetail, &QToolButton::clicked, this, &MainWindow::ToolDetail); + connect(ui->toolButtonPiecePath, &QToolButton::clicked, this, &MainWindow::ToolPiecePath); connect(ui->toolButtonHeight, &QToolButton::clicked, this, &MainWindow::ToolHeight); connect(ui->toolButtonTriangle, &QToolButton::clicked, this, &MainWindow::ToolTriangle); connect(ui->toolButtonPointOfIntersection, &QToolButton::clicked, this, &MainWindow::ToolPointOfIntersection); @@ -1791,7 +1835,7 @@ QT_WARNING_DISABLE_GCC("-Wswitch-default") void MainWindow::CancelTool() { // This check helps to find missed tools in the switch - Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 50, "Not all tools were handled."); + Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 51, "Not all tools were handled."); qCDebug(vMainWindow, "Canceling tool."); delete dialogTool; @@ -1875,9 +1919,12 @@ void MainWindow::CancelTool() case Tool::PointOfContact: ui->toolButtonPointOfContact->setChecked(false); break; - case Tool::Detail: + case Tool::Piece: ui->toolButtonNewDetail->setChecked(false); break; + case Tool::PiecePath: + ui->toolButtonPiecePath->setChecked(false); + break; case Tool::Height: ui->toolButtonHeight->setChecked(false); break; @@ -2146,7 +2193,7 @@ void MainWindow::ActionDetails(bool checked) if(not qApp->getOpeningPattern()) { - if (pattern->DataDetails()->count() == 0) + if (pattern->DataPieces()->count() == 0) { QMessageBox::information(this, tr("Detail mode"), tr("You can't use now the Detail mode. " "Please, create at least one workpiece."), @@ -2221,10 +2268,10 @@ void MainWindow::ActionLayout(bool checked) ui->actionDetails->setChecked(false); ui->actionLayout->setChecked(true); - QHash<quint32, VDetail> details; + QHash<quint32, VPiece> details; if(not qApp->getOpeningPattern()) { - const QHash<quint32, VDetail> *allDetails = pattern->DataDetails(); + const QHash<quint32, VPiece> *allDetails = pattern->DataPieces(); if (allDetails->count() == 0) { QMessageBox::information(this, tr("Layout mode"), tr("You can't use now the Layout mode. " @@ -2235,7 +2282,7 @@ void MainWindow::ActionLayout(bool checked) } else { - QHash<quint32, VDetail>::const_iterator i = allDetails->constBegin(); + QHash<quint32, VPiece>::const_iterator i = allDetails->constBegin(); while (i != allDetails->constEnd()) { if (i.value().IsInLayout()) @@ -2656,6 +2703,9 @@ void MainWindow::FullParseFile() patternReadOnly = doc->IsReadOnly(); SetEnableWidgets(true); detailsWidget->UpdateList(); + + VMainGraphicsView::NewSceneRect(sceneDraw, qApp->getSceneView()); + VMainGraphicsView::NewSceneRect(sceneDetails, qApp->getSceneView()); } //--------------------------------------------------------------------------------------------------------------------- @@ -2992,7 +3042,7 @@ void MainWindow::SetEnableTool(bool enable) } // This check helps to find missed tools - Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 50, "Not all tools were handled."); + Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 51, "Not all tools were handled."); //Drawing Tools ui->toolButtonEndLine->setEnabled(drawTools); @@ -3009,6 +3059,7 @@ void MainWindow::SetEnableTool(bool enable) ui->toolButtonCubicBezierPath->setEnabled(drawTools); ui->toolButtonPointOfContact->setEnabled(drawTools); ui->toolButtonNewDetail->setEnabled(drawTools); + ui->toolButtonPiecePath->setEnabled(drawTools); ui->toolButtonHeight->setEnabled(drawTools); ui->toolButtonTriangle->setEnabled(drawTools); ui->toolButtonPointOfIntersection->setEnabled(drawTools); @@ -3313,7 +3364,7 @@ QT_WARNING_DISABLE_GCC("-Wswitch-default") void MainWindow::LastUsedTool() { // This check helps to find missed tools in the switch - Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 50, "Not all tools were handled."); + Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 51, "Not all tools were handled."); if (currentTool == lastUsedTool) { @@ -3400,10 +3451,14 @@ void MainWindow::LastUsedTool() ui->toolButtonPointOfContact->setChecked(true); ToolPointOfContact(true); break; - case Tool::Detail: + case Tool::Piece: ui->toolButtonNewDetail->setChecked(true); ToolDetail(true); break; + case Tool::PiecePath: + ui->toolButtonPiecePath->setChecked(true); + ToolPiecePath(true); + break; case Tool::Height: ui->toolButtonHeight->setChecked(true); ToolHeight(true); @@ -3785,8 +3840,6 @@ MainWindow::~MainWindow() CleanLayout(); delete doc; - delete sceneDetails; - delete sceneDraw; delete ui; } @@ -4232,7 +4285,7 @@ QString MainWindow::CheckPathToMeasurements(const QString &patternPath, const QS } else { - VMeasurements *m = new VMeasurements(pattern); + QScopedPointer<VMeasurements> m(new VMeasurements(pattern)); m->setXMLContent(mPath); patternType = m->Type(); @@ -4266,19 +4319,7 @@ QString MainWindow::CheckPathToMeasurements(const QString &patternPath, const QS throw e; } - const QStringList mList = m->ListAll(); - const QStringList pList = doc->ListMeasurements(); - - delete m; - - const QSet<QString> match = pList.toSet().subtract(mList.toSet()); - if (not match.isEmpty()) - { - VException e(tr("Measurement file doesn't include all required measurements.")); - e.AddMoreInformation(tr("Please, additionaly provide: %1") - .arg(QStringList(match.toList()).join(", "))); - throw e; - } + CheckRequiredMeasurements(m.data()); doc->SetPath(RelativeMPath(patternPath, mPath)); PatternChangesWereSaved(false); @@ -4332,7 +4373,7 @@ void MainWindow::ZoomFirstShow() * pattern will be moved. Looks very ugly. It is best solution that i have now. */ - if (pattern->DataDetails()->size() > 0) + if (pattern->DataPieces()->size() > 0) { ActionDetails(true); ui->view->ZoomFitBest(); @@ -4347,7 +4388,7 @@ void MainWindow::ZoomFirstShow() VMainGraphicsView::NewSceneRect(sceneDraw, ui->view); VMainGraphicsView::NewSceneRect(sceneDetails, ui->view); - if (pattern->DataDetails()->size() > 0) + if (pattern->DataPieces()->size() > 0) { ActionDetails(true); ui->view->ZoomFitBest(); @@ -4364,7 +4405,7 @@ void MainWindow::DoExport(const VCommandLinePtr &expParams) { auto settings = expParams->DefaultGenerator(); - const QHash<quint32, VDetail> *details = pattern->DataDetails(); + const QHash<quint32, VPiece> *details = pattern->DataPieces(); if(not qApp->getOpeningPattern()) { if (details->count() == 0) diff --git a/src/app/valentina/mainwindow.h b/src/app/valentina/mainwindow.h index d7c939a77..61e5999f1 100644 --- a/src/app/valentina/mainwindow.h +++ b/src/app/valentina/mainwindow.h @@ -137,6 +137,7 @@ private slots: void ToolCutSplinePath(bool checked); void ToolPointOfContact(bool checked); void ToolDetail(bool checked); + void ToolPiecePath(bool checked); void ToolHeight(bool checked); void ToolTriangle(bool checked); void ToolPointOfIntersection(bool checked); @@ -167,9 +168,9 @@ private slots: bool Save(); void Open(); - void ClosedDialogDetail(int result); void ClosedDialogUnionDetails(int result); void ClosedDialogGroup(int result); + void ClosedDialogPiecePath(int result); void LoadIndividual(); void LoadStandard(); @@ -285,10 +286,20 @@ private: Func closeDialogSlot, Func2 applyDialogSlot); template <typename DrawTool> void ClosedDialog(int result); + template <typename DrawTool> - void ClosedDialogWithApply(int result); + void ClosedDialogWithApply(int result, VMainGraphicsScene *scene); template <typename DrawTool> - void ApplyDialog(); + void ApplyDialog(VMainGraphicsScene *scene); + template <typename DrawTool> + void ClosedDrawDialogWithApply(int result); + template <typename DrawTool> + void ApplyDrawDialog(); + template <typename DrawTool> + void ClosedDetailsDialogWithApply(int result); + template <typename DrawTool> + void ApplyDetailsDialog(); + bool SavePattern(const QString &curFile, QString &error); void AutoSavePattern(); void setCurrentFile(const QString &fileName); @@ -328,6 +339,7 @@ private: QSharedPointer<VMeasurements> OpenMeasurementFile(const QString &path); bool LoadMeasurements(const QString &path); bool UpdateMeasurements(const QString &path, int size, int height); + void CheckRequiredMeasurements(const VMeasurements *m); void ReopenFilesAfterCrash(QStringList &args); void DoExport(const VCommandLinePtr& expParams); diff --git a/src/app/valentina/mainwindow.ui b/src/app/valentina/mainwindow.ui index fe04e4b67..34f5c066a 100644 --- a/src/app/valentina/mainwindow.ui +++ b/src/app/valentina/mainwindow.ui @@ -48,14 +48,14 @@ <string>Tools</string> </property> <property name="currentIndex"> - <number>7</number> + <number>5</number> </property> <widget class="QWidget" name="page"> <property name="geometry"> <rect> <x>0</x> <y>0</y> - <width>100</width> + <width>117</width> <height>358</height> </rect> </property> @@ -427,7 +427,7 @@ <rect> <x>0</x> <y>0</y> - <width>100</width> + <width>130</width> <height>110</height> </rect> </property> @@ -536,7 +536,7 @@ <rect> <x>0</x> <y>0</y> - <width>100</width> + <width>130</width> <height>248</height> </rect> </property> @@ -798,7 +798,7 @@ <rect> <x>0</x> <y>0</y> - <width>100</width> + <width>130</width> <height>248</height> </rect> </property> @@ -1063,7 +1063,7 @@ <rect> <x>0</x> <y>0</y> - <width>100</width> + <width>130</width> <height>58</height> </rect> </property> @@ -1143,8 +1143,8 @@ <rect> <x>0</x> <y>0</y> - <width>100</width> - <height>196</height> + <width>130</width> + <height>356</height> </rect> </property> <attribute name="icon"> @@ -1321,8 +1321,8 @@ <rect> <x>0</x> <y>0</y> - <width>100</width> - <height>104</height> + <width>130</width> + <height>150</height> </rect> </property> <property name="sizePolicy"> @@ -1423,6 +1423,32 @@ </property> </widget> </item> + <item row="2" column="0"> + <widget class="QToolButton" name="toolButtonPiecePath"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Piece path tool</string> + </property> + <property name="text"> + <string notr="true">...</string> + </property> + <property name="icon"> + <iconset resource="share/resources/toolicon.qrc"> + <normaloff>:/toolicon/32x32/path.png</normaloff>:/toolicon/32x32/path.png</iconset> + </property> + <property name="iconSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + </widget> + </item> </layout> </widget> <widget class="QWidget" name="layoutPage"> @@ -1431,7 +1457,7 @@ <x>0</x> <y>0</y> <width>130</width> - <height>326</height> + <height>356</height> </rect> </property> <attribute name="icon"> @@ -2548,8 +2574,8 @@ </customwidget> </customwidgets> <resources> - <include location="share/resources/toolicon.qrc"/> <include location="../../libs/vmisc/share/resources/icon.qrc"/> + <include location="share/resources/toolicon.qrc"/> </resources> <connections/> </ui> diff --git a/src/app/valentina/mainwindowsnogui.cpp b/src/app/valentina/mainwindowsnogui.cpp index b2c369fd4..9ba89c342 100644 --- a/src/app/valentina/mainwindowsnogui.cpp +++ b/src/app/valentina/mainwindowsnogui.cpp @@ -60,7 +60,7 @@ //--------------------------------------------------------------------------------------------------------------------- MainWindowsNoGUI::MainWindowsNoGUI(QWidget *parent) - : VAbstractMainWindow(parent), listDetails(QVector<VLayoutDetail>()), currentScene(nullptr), tempSceneLayout(nullptr), + : VAbstractMainWindow(parent), listDetails(QVector<VLayoutPiece>()), currentScene(nullptr), tempSceneLayout(nullptr), pattern(new VContainer(qApp->TrVars(), qApp->patternUnitP())), doc(nullptr), papers(QList<QGraphicsItem *>()), shadows(QList<QGraphicsItem *>()), scenes(QList<QGraphicsScene *>()), details(QList<QList<QGraphicsItem *> >()), undoAction(nullptr), redoAction(nullptr), actionDockWidgetToolOptions(nullptr), actionDockWidgetGroups(nullptr), @@ -463,7 +463,7 @@ void MainWindowsNoGUI::PrintTiled() } //--------------------------------------------------------------------------------------------------------------------- -void MainWindowsNoGUI::PrepareDetailsForLayout(const QHash<quint32, VDetail> *details) +void MainWindowsNoGUI::PrepareDetailsForLayout(const QHash<quint32, VPiece> *details) { listDetails.clear(); SCASSERT(details != nullptr) @@ -472,40 +472,10 @@ void MainWindowsNoGUI::PrepareDetailsForLayout(const QHash<quint32, VDetail> *de return; } - QHash<quint32, VDetail>::const_iterator i = details->constBegin(); + QHash<quint32, VPiece>::const_iterator i = details->constBegin(); while (i != details->constEnd()) { - VLayoutDetail det = VLayoutDetail(); - const VDetail d = i.value(); - det.SetCountourPoints(d.ContourPoints(pattern)); - det.SetSeamAllowencePoints(d.SeamAllowancePoints(pattern), d.getSeamAllowance(), d.getClosed()); - det.setName(d.getName()); - const VPatternPieceData& data = d.GetPatternPieceData(); - if (data.IsVisible() == true) - { - det.SetDetail(d.getName(), data, qApp->font()); - } - const VPatternInfoGeometry& geom = d.GetPatternInfo(); - if (geom.IsVisible() == true) - { - VAbstractPattern* pDoc = qApp->getCurrentDocument(); - QDate date; - if (pDoc->IsDateVisible() == true) - { - date = QDate::currentDate(); - } - det.SetPatternInfo(pDoc, geom, qApp->font(), pattern->size(), pattern->height()); - } - const VGrainlineGeometry& grainlineGeom = d.GetGrainlineGeometry(); - if (grainlineGeom.IsVisible() == true) - { - det.SetGrainline(grainlineGeom, *pattern); - } - det.setWidth(qApp->toPixel(d.getWidth())); - det.CreateTextItems(); - det.setForbidFlipping(d.getForbidFlipping()); - - listDetails.append(det); + listDetails.append(VLayoutPiece::Create(i.value(), pattern)); ++i; } } diff --git a/src/app/valentina/mainwindowsnogui.h b/src/app/valentina/mainwindowsnogui.h index 6febda374..17f715dfb 100644 --- a/src/app/valentina/mainwindowsnogui.h +++ b/src/app/valentina/mainwindowsnogui.h @@ -32,8 +32,7 @@ #include <QMainWindow> #include <QPrinter> -#include "../vpatterndb/vdetail.h" -#include "../vlayout/vlayoutdetail.h" +#include "../vlayout/vlayoutpiece.h" #include "xml/vpattern.h" #include "dialogs/dialogsavelayout.h" #include "../vlayout/vlayoutgenerator.h" @@ -59,7 +58,7 @@ public slots: void PrintOrigin(); void PrintTiled(); protected: - QVector<VLayoutDetail> listDetails; + QVector<VLayoutPiece> listDetails; /** @brief currentScene pointer to current scene. */ QGraphicsScene *currentScene; @@ -90,7 +89,7 @@ protected: QMarginsF margins; QSizeF paperSize; - void PrepareDetailsForLayout(const QHash<quint32, VDetail> *details); + void PrepareDetailsForLayout(const QHash<quint32, VPiece> *details); void ExportLayout(const DialogSaveLayout &dialog); void InitTempLayoutScene(); diff --git a/src/app/valentina/share/resources/cursor.qrc b/src/app/valentina/share/resources/cursor.qrc index e92f24e13..44323cc41 100644 --- a/src/app/valentina/share/resources/cursor.qrc +++ b/src/app/valentina/share/resources/cursor.qrc @@ -78,5 +78,7 @@ <file>cursor/move_cursor@2x.png</file> <file>cursor/el_arc_cursor.png</file> <file>cursor/el_arc_cursor@2x.png</file> + <file>cursor/path_cursor.png</file> + <file>cursor/path_cursor@2x.png</file> </qresource> </RCC> diff --git a/src/app/valentina/share/resources/cursor/path_cursor.png b/src/app/valentina/share/resources/cursor/path_cursor.png new file mode 100644 index 000000000..2819f260a Binary files /dev/null and b/src/app/valentina/share/resources/cursor/path_cursor.png differ diff --git a/src/app/valentina/share/resources/cursor/path_cursor@2x.png b/src/app/valentina/share/resources/cursor/path_cursor@2x.png new file mode 100644 index 000000000..09c3a01ab Binary files /dev/null and b/src/app/valentina/share/resources/cursor/path_cursor@2x.png differ diff --git a/src/app/valentina/share/resources/toolicon.qrc b/src/app/valentina/share/resources/toolicon.qrc index 41de1c552..528ab18c2 100644 --- a/src/app/valentina/share/resources/toolicon.qrc +++ b/src/app/valentina/share/resources/toolicon.qrc @@ -76,5 +76,7 @@ <file>toolicon/32x32/move@2x.png</file> <file>toolicon/32x32/el_arc.png</file> <file>toolicon/32x32/el_arc@2x.png</file> + <file>toolicon/32x32/path.png</file> + <file>toolicon/32x32/path@2x.png</file> </qresource> </RCC> diff --git a/src/app/valentina/share/resources/toolicon/32x32/path.png b/src/app/valentina/share/resources/toolicon/32x32/path.png new file mode 100644 index 000000000..a95d6e90d Binary files /dev/null and b/src/app/valentina/share/resources/toolicon/32x32/path.png differ diff --git a/src/app/valentina/share/resources/toolicon/32x32/path@2x.png b/src/app/valentina/share/resources/toolicon/32x32/path@2x.png new file mode 100644 index 000000000..46efce5f6 Binary files /dev/null and b/src/app/valentina/share/resources/toolicon/32x32/path@2x.png differ diff --git a/src/app/valentina/share/resources/toolicon/svg/path.svg b/src/app/valentina/share/resources/toolicon/svg/path.svg new file mode 100644 index 000000000..fede8eb12 --- /dev/null +++ b/src/app/valentina/share/resources/toolicon/svg/path.svg @@ -0,0 +1,85 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + width="32" + height="32" + id="svg3837" + inkscape:version="0.91 r" + sodipodi:docname="path.svg" + inkscape:export-filename="normal.png" + inkscape:export-xdpi="90" + inkscape:export-ydpi="90"> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1855" + inkscape:window-height="1056" + id="namedview12" + showgrid="false" + inkscape:zoom="10.429825" + inkscape:cx="-10.695145" + inkscape:cy="17.373127" + inkscape:window-x="65" + inkscape:window-y="24" + inkscape:window-maximized="1" + inkscape:current-layer="layer1" /> + <defs + id="defs3839" /> + <metadata + id="metadata3842"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + id="layer1"> + <path + style="fill:none;fill-rule:evenodd;stroke:#f70000;stroke-width:1.808;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 0.69867705,29.000338 18.91523895,0" + id="path4205" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + <path + d="m 4.55558,29.025223 a 1.7375,1.7294948 0 0 1 -3.475,0 1.7375,1.7294948 0 1 1 3.475,0 z" + id="path2985-2" + style="fill:#000000;fill-opacity:1;stroke:#370000;stroke-width:1.56700003;stroke-linejoin:round;stroke-miterlimit:4.9000001;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.93950177" + inkscape:connector-curvature="0" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#f70000;stroke-width:1.79597759;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 18.613918,3.1640977 c 16.627356,3.2556205 16.092696,24.3053213 0,25.7434553" + id="path3385" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + <path + inkscape:connector-curvature="0" + style="fill:#000000;fill-opacity:1;stroke:#370000;stroke-width:1.57200003;stroke-linejoin:round;stroke-miterlimit:4.9000001;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.93950177" + id="path5373" + d="m 20.178354,28.833465 a 1.8239208,1.9086996 0 0 1 -3.647841,0 1.8239208,1.9086996 0 1 1 3.647841,0 z" /> + <path + inkscape:connector-curvature="0" + style="fill:#000000;fill-opacity:1;stroke:#370000;stroke-width:1.57200003;stroke-linejoin:round;stroke-miterlimit:4.9000001;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.93950177" + id="path5373-7" + d="m 20.424424,3.1415223 a 1.8239208,1.9086996 0 0 1 -3.647841,0 1.8239208,1.9086996 0 1 1 3.647841,0 z" /> + </g> +</svg> diff --git a/src/app/valentina/xml/vpattern.cpp b/src/app/valentina/xml/vpattern.cpp index ad5eb8c61..1fa4b300a 100644 --- a/src/app/valentina/xml/vpattern.cpp +++ b/src/app/valentina/xml/vpattern.cpp @@ -29,7 +29,7 @@ #include "vpattern.h" #include "../vwidgets/vabstractmainwindow.h" #include "../vtools/tools/vdatatool.h" -#include "../vtools/tools/vtooldetail.h" +#include "../vtools/tools/vtoolseamallowance.h" #include "../vtools/tools/vtooluniondetails.h" #include "../vtools/tools/drawTools/drawtools.h" #include "../vtools/tools/nodeDetails/nodedetails.h" @@ -49,10 +49,13 @@ #include "../vgeometry/vcubicbezier.h" #include "../vgeometry/vcubicbezierpath.h" #include "../core/vapplication.h" +#include "../vpatterndb/vpiecenode.h" #include "../vpatterndb/calculator.h" #include "../vpatterndb/vpatternpiecedata.h" #include "../vpatterndb/vpatterninfogeometry.h" #include "../vpatterndb/vgrainlinegeometry.h" +#include "../vpatterndb/vpiecepath.h" +#include "../vpatterndb/vnodedetail.h" #include <QMessageBox> #include <QUndoStack> @@ -293,8 +296,9 @@ void VPattern::setCurrentData() const VDataTool *vTool = tools.value(id); *data = vTool->getData(); - //Delete special variable if exist + //Delete special variables if exist data->RemoveVariable(currentLength); + data->RemoveVariable(currentSeamAllowance); qCDebug(vXML, "Data successfully updated."); } else @@ -348,6 +352,31 @@ quint32 VPattern::SPointActiveDraw() return 0; } +//--------------------------------------------------------------------------------------------------------------------- +QVector<quint32> VPattern::GetActivePPPieces() const +{ + QVector<quint32> pieces; + QDomElement drawElement; + if (GetActivDrawElement(drawElement)) + { + const QDomElement details = drawElement.firstChildElement(TagDetails); + if (not details.isNull()) + { + QDomElement detail = details.firstChildElement(TagDetail); + while(not detail.isNull()) + { + bool united = GetParametrBool(detail, VToolSeamAllowance::AttrUnited, falseStr); + if (not united) + { + pieces.append(GetParametrId(detail)); + } + detail = detail.nextSiblingElement(TagDetail); + } + } + } + return pieces; +} + //--------------------------------------------------------------------------------------------------------------------- bool VPattern::SaveDocument(const QString &fileName, QString &error) const { @@ -493,6 +522,47 @@ void VPattern::customEvent(QEvent *event) } } +//--------------------------------------------------------------------------------------------------------------------- +VNodeDetail VPattern::ParseDetailNode(const QDomElement &domElement) const +{ + const quint32 id = GetParametrUInt(domElement, AttrIdObject, NULL_ID_STR); + const qreal mx = GetParametrDouble(domElement, AttrMx, "0.0"); + const qreal my = GetParametrDouble(domElement, AttrMy, "0.0"); + const bool reverse = GetParametrUInt(domElement, VAbstractPattern::AttrNodeReverse, "0"); + const NodeDetail nodeType = NodeDetail::Contour; + + const QString t = GetParametrString(domElement, AttrType, "NodePoint"); + Tool tool; + + QStringList types = QStringList() << VAbstractPattern::NodePoint + << VAbstractPattern::NodeArc + << VAbstractPattern::NodeSpline + << VAbstractPattern::NodeSplinePath + << VAbstractPattern::NodeElArc; + switch (types.indexOf(t)) + { + case 0: // NodePoint + tool = Tool::NodePoint; + break; + case 1: // NodeArc + tool = Tool::NodeArc; + break; + case 2: // NodeSpline + tool = Tool::NodeSpline; + break; + case 3: // NodeSplinePath + tool = Tool::NodeSplinePath; + break; + case 4: // NodeElArc + tool = Tool::NodeElArc; + break; + default: + VException e(tr("Wrong tag name '%1'.").arg(t)); + throw e; + } + return VNodeDetail(id, tool, nodeType, mx, my, reverse); +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief ParseDrawElement parse draw tag. @@ -559,8 +629,14 @@ void VPattern::ParseDrawMode(const QDomNode &node, const Document &parse, const { scene = sceneDetail; } - const QStringList tags = QStringList() << TagPoint << TagLine << TagSpline << TagArc << TagTools << TagOperation - << TagElArc; + const QStringList tags = QStringList() << TagPoint + << TagLine + << TagSpline + << TagArc + << TagTools + << TagOperation + << TagElArc + << TagPath; const QDomNodeList nodeList = node.childNodes(); const qint32 num = nodeList.size(); for (qint32 i = 0; i < num; ++i) @@ -597,6 +673,9 @@ void VPattern::ParseDrawMode(const QDomNode &node, const Document &parse, const case 6: // TagElArc qCDebug(vXML, "Tag elliptical arc."); ParseEllipticalArcElement(scene, domElement, parse, domElement.attribute(AttrType, "")); + case 7: // TagPath + qCDebug(vXML, "Tag path."); + ParsePathElement(scene, domElement, parse); break; default: VException e(tr("Wrong tag name '%1'.").arg(domElement.tagName())); @@ -612,143 +691,83 @@ void VPattern::ParseDrawMode(const QDomNode &node, const Document &parse, const * @param domElement tag in xml tree. * @param parse parser file mode. */ -void VPattern::ParseDetailElement(const QDomElement &domElement, const Document &parse) +void VPattern::ParseDetailElement(QDomElement &domElement, const Document &parse) { Q_ASSERT_X(not domElement.isNull(), Q_FUNC_INFO, "domElement is null"); try { - VDetail detail; + VPiece detail; const quint32 id = GetParametrId(domElement); - detail.setName(GetParametrString(domElement, AttrName, "")); - detail.setMx(qApp->toPixel(GetParametrDouble(domElement, AttrMx, "0.0"))); - detail.setMy(qApp->toPixel(GetParametrDouble(domElement, AttrMy, "0.0"))); - detail.setSeamAllowance(GetParametrUInt(domElement, VToolDetail::AttrSupplement, "1")); - detail.setWidth(GetParametrDouble(domElement, VToolDetail::AttrWidth, "10.0")); - detail.setClosed(GetParametrUInt(domElement, VToolDetail::AttrClosed, "1")); - detail.setForbidFlipping(GetParametrUInt(domElement, VToolDetail::AttrForbidFlipping, + detail.SetName(GetParametrString(domElement, AttrName, tr("Detail"))); + detail.SetMx(qApp->toPixel(GetParametrDouble(domElement, AttrMx, "0.0"))); + detail.SetMy(qApp->toPixel(GetParametrDouble(domElement, AttrMy, "0.0"))); + detail.SetSeamAllowance(GetParametrBool(domElement, VToolSeamAllowance::AttrSeamAllowance, falseStr)); + detail.SetForbidFlipping(GetParametrBool(domElement, VToolSeamAllowance::AttrForbidFlipping, QString().setNum(qApp->ValentinaSettings()->GetForbidWorkpieceFlipping()))); detail.SetInLayout(GetParametrBool(domElement, AttrInLayout, trueStr)); + detail.SetUnited(GetParametrBool(domElement, VToolSeamAllowance::AttrUnited, falseStr)); + + const QString width = GetParametrString(domElement, AttrWidth, "0.0"); + QString w = width;//need for saving fixed formula; + const uint version = GetParametrUInt(domElement, VToolSeamAllowance::AttrVersion, "1"); + + const QStringList tags = QStringList() << TagNodes + << TagData + << TagPatternInfo + << TagGrainline + << VToolSeamAllowance::TagCSA + << VToolSeamAllowance::TagIPaths; - QStringList types = QStringList() << VToolDetail::NodePoint - << VToolDetail::NodeArc - << VToolDetail::NodeSpline - << VToolDetail::NodeSplinePath - << VToolDetail::NodeElArc; const QDomNodeList nodeList = domElement.childNodes(); - const qint32 num = nodeList.size(); - for (qint32 i = 0; i < num; ++i) + for (qint32 i = 0; i < nodeList.size(); ++i) { const QDomElement element = nodeList.at(i).toElement(); - if (element.isNull() == false) + if (not element.isNull()) { - if (element.tagName() == VToolDetail::TagNode) + switch (tags.indexOf(element.tagName())) { - const quint32 id = GetParametrUInt(element, AttrIdObject, NULL_ID_STR); - const qreal mx = qApp->toPixel(GetParametrDouble(element, AttrMx, "0.0")); - const qreal my = qApp->toPixel(GetParametrDouble(element, AttrMy, "0.0")); - const bool reverse = GetParametrUInt(element, VToolDetail::AttrReverse, "0"); - const NodeDetail nodeType = NodeDetail::Contour; - - const QString t = GetParametrString(element, AttrType, "NodePoint"); - Tool tool; - - switch (types.indexOf(t)) - { - case 0: // VToolDetail::NodePoint - tool = Tool::NodePoint; - break; - case 1: // VToolDetail::NodeArc - tool = Tool::NodeArc; - break; - case 2: // VToolDetail::NodeSpline - tool = Tool::NodeSpline; - break; - case 3: // VToolDetail::NodeSplinePath - tool = Tool::NodeSplinePath; - break; - case 4: // VToolDetail::NodeElArc - tool = Tool::NodeElArc; - break; - default: - VException e(tr("Wrong tag name '%1'.").arg(t)); - throw e; - } - detail.append(VNodeDetail(id, tool, nodeType, mx, my, reverse)); - } - else if (element.tagName() == TagData) - { - bool bVisible = GetParametrBool(element, AttrVisible, trueStr); - detail.GetPatternPieceData().SetVisible(bVisible); - try - { - QString qsLetter = GetParametrString(element, AttrLetter, ""); - detail.GetPatternPieceData().SetLetter(qsLetter); - } catch(...) - { - detail.GetPatternPieceData().SetLetter(""); - } - QPointF ptPos; - ptPos.setX(GetParametrDouble(element, AttrMx, "0")); - ptPos.setY(GetParametrDouble(element, AttrMy, "0")); - detail.GetPatternPieceData().SetPos(ptPos); - qreal dLW = GetParametrDouble(element, VToolDetail::AttrWidth, "0"); - detail.GetPatternPieceData().SetLabelWidth(dLW); - qreal dLH = GetParametrDouble(element, VToolDetail::AttrHeight, "0"); - detail.GetPatternPieceData().SetLabelHeight(dLH); - int iFS = static_cast<int>(GetParametrUInt(element, VToolDetail::AttrFont, "0")); - detail.GetPatternPieceData().SetFontSize(iFS); - qreal dRot = GetParametrDouble(element, VToolDetail::AttrRotation, "0"); - detail.GetPatternPieceData().SetRotation(dRot); - - QDomNodeList nodeListMCP = element.childNodes(); - for (int iMCP = 0; iMCP < nodeListMCP.count(); ++iMCP) - { - MaterialCutPlacement mcp; - QDomElement domMCP = nodeListMCP.at(iMCP).toElement(); - mcp.m_eMaterial = MaterialType(GetParametrUInt(domMCP, AttrMaterial, 0)); - if (mcp.m_eMaterial == MaterialType::mtUserDefined) + case 0:// TagNodes + if (version == 1) { - mcp.m_qsMaterialUserDef = GetParametrString(domMCP, AttrUserDefined, ""); + // TODO. Delete if minimal supported version is 0.4.0 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 4, 0), + "Time to refactor the code."); + const bool closed = GetParametrUInt(domElement, AttrClosed, "1"); + const qreal width = GetParametrDouble(domElement, AttrWidth, "0.0"); + ParseDetailNodes(element, detail, width, closed); } - mcp.m_iCutNumber = static_cast<int>(GetParametrUInt(domMCP, AttrCutNumber, 0)); - mcp.m_ePlacement = PlacementType(GetParametrUInt(domMCP, AttrPlacement, 0)); - detail.GetPatternPieceData().Append(mcp); - } - } - else if (element.tagName() == TagPatternInfo) - { - detail.GetPatternInfo().SetVisible(GetParametrBool(element, AttrVisible, trueStr)); - QPointF ptPos; - ptPos.setX(GetParametrDouble(element, AttrMx, "0")); - ptPos.setY(GetParametrDouble(element, AttrMy, "0")); - detail.GetPatternInfo().SetPos(ptPos); - qreal dLW = GetParametrDouble(element, VToolDetail::AttrWidth, "0"); - detail.GetPatternInfo().SetLabelWidth(dLW); - qreal dLH = GetParametrDouble(element, VToolDetail::AttrHeight, "0"); - detail.GetPatternInfo().SetLabelHeight(dLH); - int iFS = static_cast<int>(GetParametrUInt(element, VToolDetail::AttrFont, "0")); - detail.GetPatternInfo().SetFontSize(iFS); - qreal dRot = GetParametrDouble(element, VToolDetail::AttrRotation, "0"); - detail.GetPatternInfo().SetRotation(dRot); - } - else if (element.tagName() == TagGrainline) - { - detail.GetGrainlineGeometry().SetVisible(GetParametrBool(element, AttrVisible, falseStr)); - QPointF ptPos; - ptPos.setX(GetParametrDouble(element, AttrMx, "0")); - ptPos.setY(GetParametrDouble(element, AttrMy, "0")); - detail.GetGrainlineGeometry().SetPos(ptPos); - QString qsLength = GetParametrString(element, AttrLength, "0"); - detail.GetGrainlineGeometry().SetLength(qsLength); - QString qsRot = GetParametrString(element, VToolDetail::AttrRotation, "90"); - detail.GetGrainlineGeometry().SetRotation(qsRot); - VGrainlineGeometry::ArrowType eAT = - VGrainlineGeometry::ArrowType(GetParametrUInt(element, AttrArrows, "0")); - detail.GetGrainlineGeometry().SetArrowType(eAT); + else + { + detail.SetPath(ParsePieceNodes(element)); + } + break; + case 1:// TagData + ParsePieceDataTag(element, detail); + break; + case 2:// TagPatternInfo + ParsePiecePatternInfo(element, detail); + break; + case 3:// TagGrainline + ParsePieceGrainline(element, detail); + break; + case 4:// VToolSeamAllowance::TagCSA + detail.SetCustomSARecords(ParsePieceCSARecords(element)); + break; + case 5:// VToolSeamAllowance::TagIPaths + detail.SetInternalPaths(ParsePieceInternalPaths(element)); + default: + break; } } } - VToolDetail::Create(id, detail, sceneDetail, this, data, parse, Source::FromFile); + VToolSeamAllowance::Create(id, detail, w, sceneDetail, this, data, parse, Source::FromFile); + //Rewrite attribute formula. Need for situation when we have wrong formula. + if (w != width) + { + SetAttribute(domElement, AttrWidth, w); + modified = true; + haveLiteChange(); + } } catch (const VExceptionBadId &e) { @@ -758,6 +777,102 @@ void VPattern::ParseDetailElement(const QDomElement &domElement, const Document } } +//--------------------------------------------------------------------------------------------------------------------- +void VPattern::ParseDetailNodes(const QDomElement &domElement, VPiece &detail, qreal width, bool closed) const +{ + QVector<VNodeDetail> oldNodes; + const QDomNodeList nodeList = domElement.childNodes(); + for (qint32 i = 0; i < nodeList.size(); ++i) + { + const QDomElement element = nodeList.at(i).toElement(); + if (not element.isNull() + && element.tagName() == VAbstractPattern::TagNode) // Old detail version need this check! + { + oldNodes.append(ParseDetailNode(element)); + } + } + + detail.GetPath().SetNodes(VNodeDetail::Convert(data, oldNodes, width, closed)); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPattern::ParsePieceDataTag(const QDomElement &domElement, VPiece &detail) const +{ + detail.GetPatternPieceData().SetVisible(GetParametrBool(domElement, AttrVisible, trueStr)); + try + { + QString qsLetter = GetParametrString(domElement, AttrLetter, ""); + detail.GetPatternPieceData().SetLetter(qsLetter); + } + catch(const VExceptionEmptyParameter &e) + { + Q_UNUSED(e) + detail.GetPatternPieceData().SetLetter(""); + } + QPointF ptPos; + ptPos.setX(GetParametrDouble(domElement, AttrMx, "0")); + ptPos.setY(GetParametrDouble(domElement, AttrMy, "0")); + detail.GetPatternPieceData().SetPos(ptPos); + qreal dLW = GetParametrDouble(domElement, AttrWidth, "0"); + detail.GetPatternPieceData().SetLabelWidth(dLW); + qreal dLH = GetParametrDouble(domElement, VToolSeamAllowance::AttrHeight, "0"); + detail.GetPatternPieceData().SetLabelHeight(dLH); + int iFS = static_cast<int>(GetParametrUInt(domElement, VToolSeamAllowance::AttrFont, "0")); + detail.GetPatternPieceData().SetFontSize(iFS); + qreal dRot = GetParametrDouble(domElement, AttrRotation, "0"); + detail.GetPatternPieceData().SetRotation(dRot); + + QDomNodeList nodeListMCP = domElement.childNodes(); + for (int iMCP = 0; iMCP < nodeListMCP.count(); ++iMCP) + { + MaterialCutPlacement mcp; + QDomElement domMCP = nodeListMCP.at(iMCP).toElement(); + mcp.m_eMaterial = MaterialType(GetParametrUInt(domMCP, AttrMaterial, 0)); + if (mcp.m_eMaterial == MaterialType::mtUserDefined) + { + mcp.m_qsMaterialUserDef = GetParametrString(domMCP, AttrUserDefined, ""); + } + mcp.m_iCutNumber = static_cast<int>(GetParametrUInt(domMCP, AttrCutNumber, 0)); + mcp.m_ePlacement = PlacementType(GetParametrUInt(domMCP, AttrPlacement, 0)); + detail.GetPatternPieceData().Append(mcp); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPattern::ParsePiecePatternInfo(const QDomElement &domElement, VPiece &detail) const +{ + detail.GetPatternInfo().SetVisible(GetParametrBool(domElement, AttrVisible, trueStr)); + QPointF ptPos; + ptPos.setX(GetParametrDouble(domElement, AttrMx, "0")); + ptPos.setY(GetParametrDouble(domElement, AttrMy, "0")); + detail.GetPatternInfo().SetPos(ptPos); + qreal dLW = GetParametrDouble(domElement, AttrWidth, "0"); + detail.GetPatternInfo().SetLabelWidth(dLW); + qreal dLH = GetParametrDouble(domElement, VToolSeamAllowance::AttrHeight, "0"); + detail.GetPatternInfo().SetLabelHeight(dLH); + int iFS = static_cast<int>(GetParametrUInt(domElement, VToolSeamAllowance::AttrFont, "0")); + detail.GetPatternInfo().SetFontSize(iFS); + qreal dRot = GetParametrDouble(domElement, AttrRotation, "0"); + detail.GetPatternInfo().SetRotation(dRot); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPattern::ParsePieceGrainline(const QDomElement &domElement, VPiece &detail) const +{ + detail.GetGrainlineGeometry().SetVisible(GetParametrBool(domElement, AttrVisible, falseStr)); + QPointF ptPos; + ptPos.setX(GetParametrDouble(domElement, AttrMx, "0")); + ptPos.setY(GetParametrDouble(domElement, AttrMy, "0")); + detail.GetGrainlineGeometry().SetPos(ptPos); + QString qsLength = GetParametrString(domElement, AttrLength, "0"); + detail.GetGrainlineGeometry().SetLength(qsLength); + QString qsRot = GetParametrString(domElement, AttrRotation, "90"); + detail.GetGrainlineGeometry().SetRotation(qsRot); + VGrainlineGeometry::ArrowType eAT = + VGrainlineGeometry::ArrowType(GetParametrUInt(domElement, AttrArrows, "0")); + detail.GetGrainlineGeometry().SetArrowType(eAT); +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief ParseDetails parse details tag. @@ -772,7 +887,7 @@ void VPattern::ParseDetails(const QDomElement &domElement, const Document &parse { if (domNode.isElement()) { - const QDomElement domElement = domNode.toElement(); + QDomElement domElement = domNode.toElement(); if (domElement.isNull() == false) { if (domElement.tagName() == TagDetail) @@ -3015,13 +3130,17 @@ void VPattern::ParseToolsElement(VMainGraphicsScene *scene, const QDomElement &d { quint32 id = 0; ToolsCommonAttributes(domElement, id); - const quint32 indexD1 = GetParametrUInt(domElement, VToolUnionDetails::AttrIndexD1, "-1"); - const quint32 indexD2 = GetParametrUInt(domElement, VToolUnionDetails::AttrIndexD2, "-1"); - const QVector<VDetail> vector = VToolUnionDetails::GetDetailFromFile(this, domElement); + VToolUnionDetailsInitData initData; + initData.indexD1 = GetParametrUInt(domElement, VToolUnionDetails::AttrIndexD1, "-1"); + initData.indexD2 = GetParametrUInt(domElement, VToolUnionDetails::AttrIndexD2, "-1"); + initData.scene = scene; + initData.doc = this; + initData.data = data; + initData.parse = parse; + initData.typeCreation = Source::FromFile; - VToolUnionDetails::Create(id, vector[0], vector[1], 0, 0, indexD1, indexD2, scene, this, data, parse, - Source::FromFile); + VToolUnionDetails::Create(id, initData); } catch (const VExceptionBadId &e) { @@ -3069,6 +3188,42 @@ void VPattern::ParseOperationElement(VMainGraphicsScene *scene, QDomElement &dom } } +//--------------------------------------------------------------------------------------------------------------------- +void VPattern::ParsePathElement(VMainGraphicsScene *scene, QDomElement &domElement, const Document &parse) +{ + SCASSERT(scene != nullptr); + Q_ASSERT_X(not domElement.isNull(), Q_FUNC_INFO, "domElement is null"); + try + { + quint32 id = 0; + ToolsCommonAttributes(domElement, id); + const QString name = GetParametrString(domElement, AttrName, tr("Unnamed path")); + const QString defType = QString().setNum(static_cast<int>(PiecePathType::CustomSeamAllowance)); + const PiecePathType type = static_cast<PiecePathType>(GetParametrUInt(domElement, AttrType, defType)); + const quint32 idTool = GetParametrUInt(domElement, VAbstractNode::AttrIdTool, NULL_ID_STR); + const QString penType = GetParametrString(domElement, AttrTypeLine, TypeLineLine); + + VPiecePath path; + const QDomElement element = domElement.firstChildElement(VAbstractPattern::TagNodes); + if (not element.isNull()) + { + path = ParsePathNodes(element); + } + + path.SetType(type); + path.SetName(name); + path.SetPenType(VAbstractTool::LineStyleToPenStyle(penType)); + + VToolPiecePath::Create(id, path, 0, scene, this, data, parse, Source::FromFile, "", idTool); + } + catch (const VExceptionBadId &e) + { + VExceptionObjectError excep(tr("Error creating or updating a piece path"), domElement); + excep.AddMoreInformation(e.ErrorMessage()); + throw excep; + } +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief ParseIncrementsElement parse increments tag. @@ -3569,7 +3724,7 @@ QT_WARNING_DISABLE_GCC("-Wswitch-default") QRectF VPattern::ActiveDrawBoundingRect() const { // This check helps to find missed tools in the switch - Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 50, "Not all tools were used."); + Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 51, "Not all tools were used."); QRectF rec; @@ -3694,7 +3849,7 @@ QRectF VPattern::ActiveDrawBoundingRect() const rec = ToolBoundingRect<VToolEllipticalArc>(rec, tool.getId()); break; //These tools are not accesseble in Draw mode, but still 'history' contains them. - case Tool::Detail: + case Tool::Piece: case Tool::UnionDetails: case Tool::NodeArc: case Tool::NodeElArc: @@ -3702,6 +3857,7 @@ QRectF VPattern::ActiveDrawBoundingRect() const case Tool::NodeSpline: case Tool::NodeSplinePath: case Tool::Group: + case Tool::PiecePath: break; } } diff --git a/src/app/valentina/xml/vpattern.h b/src/app/valentina/xml/vpattern.h index 02ce823c7..1c0fb2f3f 100644 --- a/src/app/valentina/xml/vpattern.h +++ b/src/app/valentina/xml/vpattern.h @@ -36,6 +36,7 @@ class VDataTool; class VMainGraphicsScene; +class VNodeDetail; /** * @brief The VPattern class working with pattern file. @@ -59,6 +60,8 @@ public: quint32 SPointActiveDraw(); + QVector<quint32> GetActivePPPieces() const; + virtual void setXMLContent(const QString &fileName) Q_DECL_OVERRIDE; virtual bool SaveDocument(const QString &fileName, QString &error) const Q_DECL_OVERRIDE; @@ -112,9 +115,15 @@ private: VMainGraphicsScene *sceneDraw; VMainGraphicsScene *sceneDetail; + VNodeDetail ParseDetailNode(const QDomElement &domElement) const; + void ParseDrawElement(const QDomNode& node, const Document &parse); void ParseDrawMode(const QDomNode& node, const Document &parse, const Draw &mode); - void ParseDetailElement(const QDomElement &domElement, const Document &parse); + void ParseDetailElement(QDomElement &domElement, const Document &parse); + void ParseDetailNodes(const QDomElement &domElement, VPiece &detail, qreal width, bool closed) const; + void ParsePieceDataTag(const QDomElement &domElement, VPiece &detail) const; + void ParsePiecePatternInfo(const QDomElement &domElement, VPiece &detail) const; + void ParsePieceGrainline(const QDomElement &domElement, VPiece &detail) const; void ParseDetails(const QDomElement &domElement, const Document &parse); void ParsePointElement(VMainGraphicsScene *scene, QDomElement &domElement, @@ -131,6 +140,9 @@ private: const Document &parse, const QString& type); void ParseOperationElement(VMainGraphicsScene *scene, QDomElement &domElement, const Document &parse, const QString& type); + + void ParsePathElement(VMainGraphicsScene *scene, QDomElement &domElement, const Document &parse); + void ParseIncrementsElement(const QDomNode& node); void PrepareForParse(const Document &parse); void ToolsCommonAttributes(const QDomElement &domElement, quint32 &id); diff --git a/src/libs/ifc/ifcdef.cpp b/src/libs/ifc/ifcdef.cpp index 0e4fa1022..eb5565f02 100644 --- a/src/libs/ifc/ifcdef.cpp +++ b/src/libs/ifc/ifcdef.cpp @@ -138,7 +138,8 @@ const QString AttrArc = QStringLiteral("arc"); const QString AttrSuffix = QStringLiteral("suffix"); const QString AttrIdObject = QStringLiteral("idObject"); const QString AttrInLayout = QStringLiteral("inLayout"); -const QString AttrRotationAngle = QStringLiteral("rotationAngle"); +const QString AttrRotationAngle = QStringLiteral("rotationAngle"); +const QString AttrClosed = QStringLiteral("closed"); const QString TypeLineNone = QStringLiteral("none"); const QString TypeLineLine = QStringLiteral("hair"); @@ -166,29 +167,30 @@ const QString ColorDeepSkyBlue = QStringLiteral("deepskyblue"); const QString ColorCornFlowerBlue = QStringLiteral("cornflowerblue"); //variables -const QString line_ = QStringLiteral("Line_"); -const QString angleLine_ = QStringLiteral("AngleLine_"); -const QString spl_ = QStringLiteral(SPL_); -const QString arc_ = QStringLiteral(ARC_); -const QString splPath = QStringLiteral("SplPath"); -const QString radius_V = QStringLiteral("Radius"); -const QString radiusArc_ = radius_V + arc_; -const QString angle1_V = QStringLiteral("Angle1"); -const QString angle2_V = QStringLiteral("Angle2"); -const QString c1Length_V = QStringLiteral("C1Length"); -const QString c2Length_V = QStringLiteral("C2Length"); -const QString c1LengthSpl_ = c1Length_V + spl_; -const QString c2LengthSpl_ = c2Length_V + spl_; -const QString c1LengthSplPath = c1Length_V + splPath; -const QString c2LengthSplPath = c2Length_V + splPath; -const QString angle1Arc_ = angle1_V + arc_; -const QString angle2Arc_ = angle2_V + arc_; -const QString angle1Spl_ = angle1_V + spl_; -const QString angle2Spl_ = angle2_V + spl_; -const QString angle1SplPath = angle1_V + splPath; -const QString angle2SplPath = angle2_V + splPath; -const QString seg_ = QStringLiteral("Seg_"); -const QString currentLength = QStringLiteral("CurrentLength"); +const QString line_ = QStringLiteral("Line_"); +const QString angleLine_ = QStringLiteral("AngleLine_"); +const QString spl_ = QStringLiteral(SPL_); +const QString arc_ = QStringLiteral(ARC_); +const QString splPath = QStringLiteral("SplPath"); +const QString radius_V = QStringLiteral("Radius"); +const QString radiusArc_ = radius_V + arc_; +const QString angle1_V = QStringLiteral("Angle1"); +const QString angle2_V = QStringLiteral("Angle2"); +const QString c1Length_V = QStringLiteral("C1Length"); +const QString c2Length_V = QStringLiteral("C2Length"); +const QString c1LengthSpl_ = c1Length_V + spl_; +const QString c2LengthSpl_ = c2Length_V + spl_; +const QString c1LengthSplPath = c1Length_V + splPath; +const QString c2LengthSplPath = c2Length_V + splPath; +const QString angle1Arc_ = angle1_V + arc_; +const QString angle2Arc_ = angle2_V + arc_; +const QString angle1Spl_ = angle1_V + spl_; +const QString angle2Spl_ = angle2_V + spl_; +const QString angle1SplPath = angle1_V + splPath; +const QString angle2SplPath = angle2_V + splPath; +const QString seg_ = QStringLiteral("Seg_"); +const QString currentLength = QStringLiteral("CurrentLength"); +const QString currentSeamAllowance = QStringLiteral("CurrentSeamAllowance"); const QStringList builInVariables = QStringList() << line_ << angleLine_ @@ -204,6 +206,7 @@ const QStringList builInVariables = QStringList() << line_ << angle2SplPath << seg_ << currentLength + << currentSeamAllowance << c1LengthSpl_ << c2LengthSpl_ << c1LengthSplPath diff --git a/src/libs/ifc/ifcdef.h b/src/libs/ifc/ifcdef.h index dfc86eb6b..143fee251 100644 --- a/src/libs/ifc/ifcdef.h +++ b/src/libs/ifc/ifcdef.h @@ -140,6 +140,7 @@ extern const QString AttrArc; extern const QString AttrSuffix; extern const QString AttrIdObject; extern const QString AttrInLayout; +extern const QString AttrClosed; extern const QString TypeLineNone; extern const QString TypeLineLine; @@ -196,6 +197,7 @@ extern const QString angle1SplPath; extern const QString angle2SplPath; extern const QString seg_; extern const QString currentLength; +extern const QString currentSeamAllowance; extern const QStringList builInVariables; diff --git a/src/libs/ifc/schema.qrc b/src/libs/ifc/schema.qrc index 50b5d4de9..aa5a46d40 100644 --- a/src/libs/ifc/schema.qrc +++ b/src/libs/ifc/schema.qrc @@ -23,6 +23,7 @@ <file>schema/pattern/v0.3.7.xsd</file> <file>schema/pattern/v0.3.8.xsd</file> <file>schema/pattern/v0.3.9.xsd</file> + <file>schema/pattern/v0.4.0.xsd</file> <file>schema/standard_measurements/v0.3.0.xsd</file> <file>schema/standard_measurements/v0.4.0.xsd</file> <file>schema/standard_measurements/v0.4.1.xsd</file> diff --git a/src/libs/ifc/schema/individual_measurements/v0.3.3.xsd b/src/libs/ifc/schema/individual_measurements/v0.3.3.xsd index 489ebd973..044a44471 100644 --- a/src/libs/ifc/schema/individual_measurements/v0.3.3.xsd +++ b/src/libs/ifc/schema/individual_measurements/v0.3.3.xsd @@ -1,72 +1,72 @@ <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> - <xs:element name="vit"> - <xs:complexType> - <xs:sequence> - <xs:element name="version" type="formatVersion"></xs:element> - <xs:element name="read-only" type="xs:boolean"></xs:element> - <xs:element name="notes" type="xs:string" minOccurs="0" maxOccurs="1"></xs:element> - <xs:element name="unit" type="units"></xs:element> - <xs:element name="pm_system" type="psCode"></xs:element> - <xs:element name="personal"> - <xs:complexType> - <xs:sequence> - <xs:element name="family-name" type="xs:string"></xs:element> - <xs:element name="given-name" type="xs:string"></xs:element> - <xs:element name="birth-date" type="xs:date"></xs:element> - <xs:element name="gender" type="gender"></xs:element> - <xs:element name="email" type="xs:string"></xs:element> - </xs:sequence> - </xs:complexType> - </xs:element> - <xs:element name="body-measurements"> - <xs:complexType> - <xs:sequence> - <xs:element name="m" minOccurs="0" maxOccurs="unbounded"> - <xs:complexType> - <xs:attribute name="name" type="shortName" use="required"></xs:attribute> - <xs:attribute name="value" type="xs:string" use="required"></xs:attribute> - <xs:attribute name="full_name" type="xs:string"></xs:attribute> - <xs:attribute name="description" type="xs:string"></xs:attribute> - </xs:complexType> - </xs:element> - </xs:sequence> - </xs:complexType> - </xs:element> - </xs:sequence> - </xs:complexType> - <xs:unique name="measurementName"> - <xs:selector xpath="body-measurements/m"/> - <xs:field xpath="@name"/> - </xs:unique> - </xs:element> - <xs:simpleType name="shortName"> - <xs:restriction base="xs:string"> - <xs:pattern value="^([^\p{Nd}\p{Zs}*/&|!<>^\-()–+−=?:;'\"]){1,1}([^\p{Zs}*/&|!<>^\-()–+−=?:;\"]){0,}$"/> - </xs:restriction> - </xs:simpleType> - <xs:simpleType name="formatVersion"> - <xs:restriction base="xs:string"> - <xs:pattern value="^(0|([1-9][0-9]*))\.(0|([1-9][0-9]*))\.(0|([1-9][0-9]*))$"/> - </xs:restriction> - </xs:simpleType> - <xs:simpleType name="units"> - <xs:restriction base="xs:string"> - <xs:enumeration value="mm"/> - <xs:enumeration value="cm"/> - <xs:enumeration value="inch"/> - </xs:restriction> - </xs:simpleType> - <xs:simpleType name="gender"> - <xs:restriction base="xs:string"> - <xs:enumeration value="unknown"/> - <xs:enumeration value="male"/> - <xs:enumeration value="female"/> - </xs:restriction> - </xs:simpleType> - <xs:simpleType name="psCode"> - <xs:restriction base="xs:string"> - <xs:pattern value="^^(([0-9]|[1-4][0-9]|5[0-4])|998)$"/> - </xs:restriction> - </xs:simpleType> + <xs:element name="vit"> + <xs:complexType> + <xs:sequence> + <xs:element name="version" type="formatVersion"/> + <xs:element name="read-only" type="xs:boolean"/> + <xs:element name="notes" type="xs:string" minOccurs="0" maxOccurs="1"/> + <xs:element name="unit" type="units"/> + <xs:element name="pm_system" type="psCode"/> + <xs:element name="personal"> + <xs:complexType> + <xs:sequence> + <xs:element name="family-name" type="xs:string"/> + <xs:element name="given-name" type="xs:string"/> + <xs:element name="birth-date" type="xs:date"/> + <xs:element name="gender" type="gender"/> + <xs:element name="email" type="xs:string"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="body-measurements"> + <xs:complexType> + <xs:sequence> + <xs:element name="m" minOccurs="0" maxOccurs="unbounded"> + <xs:complexType> + <xs:attribute name="name" type="shortName" use="required"/> + <xs:attribute name="value" type="xs:string" use="required"/> + <xs:attribute name="full_name" type="xs:string"/> + <xs:attribute name="description" type="xs:string"/> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:unique name="measurementName"> + <xs:selector xpath="body-measurements/m"/> + <xs:field xpath="@name"/> + </xs:unique> + </xs:element> + <xs:simpleType name="shortName"> + <xs:restriction base="xs:string"> + <xs:pattern value="^([^\p{Nd}\p{Zs}*/&|!<>^\-()–+−=?:;'\"]){1,1}([^\p{Zs}*/&|!<>^\-()–+−=?:;\"]){0,}$"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="formatVersion"> + <xs:restriction base="xs:string"> + <xs:pattern value="^(0|([1-9][0-9]*))\.(0|([1-9][0-9]*))\.(0|([1-9][0-9]*))$"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="units"> + <xs:restriction base="xs:string"> + <xs:enumeration value="mm"/> + <xs:enumeration value="cm"/> + <xs:enumeration value="inch"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="gender"> + <xs:restriction base="xs:string"> + <xs:enumeration value="unknown"/> + <xs:enumeration value="male"/> + <xs:enumeration value="female"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="psCode"> + <xs:restriction base="xs:string"> + <xs:pattern value="^^(([0-9]|[1-4][0-9]|5[0-4])|998)$"/> + </xs:restriction> + </xs:simpleType> </xs:schema> diff --git a/src/libs/ifc/schema/pattern/v0.3.9.xsd b/src/libs/ifc/schema/pattern/v0.3.9.xsd index bd98bd5e3..0cecf1409 100644 --- a/src/libs/ifc/schema/pattern/v0.3.9.xsd +++ b/src/libs/ifc/schema/pattern/v0.3.9.xsd @@ -416,7 +416,7 @@ <xs:attribute name="my" type="xs:double"></xs:attribute> <xs:attribute name="length" type="xs:string"></xs:attribute> <xs:attribute name="rotation" type="xs:string"></xs:attribute> - <xs:attribute name="arrows" type="arrowType"></xs:attribute> + <xs:attribute name="arrows" type="arrowType"></xs:attribute> </xs:complexType> </xs:element> <xs:element name="node" maxOccurs="unbounded"> diff --git a/src/libs/ifc/schema/pattern/v0.4.0.xsd b/src/libs/ifc/schema/pattern/v0.4.0.xsd new file mode 100644 index 000000000..bcb5da26f --- /dev/null +++ b/src/libs/ifc/schema/pattern/v0.4.0.xsd @@ -0,0 +1,817 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> + <!-- XML Schema Generated from XML Document--> + <xs:element name="pattern"> + <xs:complexType> + <xs:sequence minOccurs="1" maxOccurs="unbounded"> + <xs:element name="version" type="formatVersion"/> + <xs:element name="unit" type="units"/> + <xs:element name="image" minOccurs="0" maxOccurs="1"> + <xs:complexType> + <xs:simpleContent> + <xs:extension base="xs:string"> + <xs:attribute name="extension" type="imageExtension"/> + </xs:extension> + </xs:simpleContent> + </xs:complexType> + </xs:element> + <xs:element name="author" type="xs:string" minOccurs="0" maxOccurs="1"/> + <xs:element name="description" type="xs:string" minOccurs="0" maxOccurs="1"/> + <xs:element name="notes" type="xs:string" minOccurs="0" maxOccurs="1"/> + <xs:element name="gradation" minOccurs="0" maxOccurs="1"> + <xs:complexType> + <xs:sequence> + <xs:element name="heights"> + <xs:complexType> + <xs:attribute name="all" type="xs:boolean" use="required"/> + <xs:attribute name="h50" type="xs:boolean"/> + <xs:attribute name="h56" type="xs:boolean"/> + <xs:attribute name="h62" type="xs:boolean"/> + <xs:attribute name="h68" type="xs:boolean"/> + <xs:attribute name="h74" type="xs:boolean"/> + <xs:attribute name="h80" type="xs:boolean"/> + <xs:attribute name="h86" type="xs:boolean"/> + <xs:attribute name="h92" type="xs:boolean"/> + <xs:attribute name="h98" type="xs:boolean"/> + <xs:attribute name="h104" type="xs:boolean"/> + <xs:attribute name="h110" type="xs:boolean"/> + <xs:attribute name="h116" type="xs:boolean"/> + <xs:attribute name="h122" type="xs:boolean"/> + <xs:attribute name="h128" type="xs:boolean"/> + <xs:attribute name="h134" type="xs:boolean"/> + <xs:attribute name="h140" type="xs:boolean"/> + <xs:attribute name="h146" type="xs:boolean"/> + <xs:attribute name="h152" type="xs:boolean"/> + <xs:attribute name="h158" type="xs:boolean"/> + <xs:attribute name="h164" type="xs:boolean"/> + <xs:attribute name="h170" type="xs:boolean"/> + <xs:attribute name="h176" type="xs:boolean"/> + <xs:attribute name="h182" type="xs:boolean"/> + <xs:attribute name="h188" type="xs:boolean"/> + <xs:attribute name="h194" type="xs:boolean"/> + </xs:complexType> + </xs:element> + <xs:element name="sizes"> + <xs:complexType> + <xs:attribute name="all" type="xs:boolean" use="required"/> + <xs:attribute name="s22" type="xs:boolean"/> + <xs:attribute name="s24" type="xs:boolean"/> + <xs:attribute name="s26" type="xs:boolean"/> + <xs:attribute name="s28" type="xs:boolean"/> + <xs:attribute name="s30" type="xs:boolean"/> + <xs:attribute name="s32" type="xs:boolean"/> + <xs:attribute name="s34" type="xs:boolean"/> + <xs:attribute name="s36" type="xs:boolean"/> + <xs:attribute name="s38" type="xs:boolean"/> + <xs:attribute name="s40" type="xs:boolean"/> + <xs:attribute name="s42" type="xs:boolean"/> + <xs:attribute name="s44" type="xs:boolean"/> + <xs:attribute name="s46" type="xs:boolean"/> + <xs:attribute name="s48" type="xs:boolean"/> + <xs:attribute name="s50" type="xs:boolean"/> + <xs:attribute name="s52" type="xs:boolean"/> + <xs:attribute name="s54" type="xs:boolean"/> + <xs:attribute name="s56" type="xs:boolean"/> + </xs:complexType> + </xs:element> + </xs:sequence> + <xs:attribute name="custom" type="xs:boolean"/> + <xs:attribute name="defHeight" type="baseHeight"/> + <xs:attribute name="defSize" type="baseSize"/> + </xs:complexType> + </xs:element> + <xs:element name="patternName" type="xs:string" minOccurs="0" maxOccurs="1"/> + <xs:element name="patternNumber" type="xs:string" minOccurs="0" maxOccurs="1"/> + <xs:element name="company" type="xs:string" minOccurs="0" maxOccurs="1"/> + <xs:element name="customer" type="xs:string" minOccurs="0" maxOccurs="1"/> + <xs:element name="size" type="xs:string" minOccurs="0" maxOccurs="1"/> + <xs:element name="showDate" type="xs:boolean" minOccurs="0" maxOccurs="1"/> + <xs:element name="showMeasurements" type="xs:boolean" minOccurs="0" maxOccurs="1"/> + <xs:element name="measurements" type="xs:string"/> + <xs:element name="increments" minOccurs="0" maxOccurs="1"> + <xs:complexType> + <xs:sequence minOccurs="0" maxOccurs="unbounded"> + <xs:element name="increment" minOccurs="0" maxOccurs="unbounded"> + <xs:complexType> + <xs:attribute name="description" type="xs:string" use="required"/> + <xs:attribute name="name" type="shortName" use="required"/> + <xs:attribute name="formula" type="xs:string" use="required"/> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:unique name="incrementName"> + <xs:selector xpath="increment"/> + <xs:field xpath="@name"/> + </xs:unique> + </xs:element> + <xs:element name="draw" minOccurs="1" maxOccurs="unbounded"> + <xs:complexType> + <xs:sequence> + <xs:element name="calculation" minOccurs="1" maxOccurs="unbounded"> + <xs:complexType> + <xs:sequence> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="point" minOccurs="0" maxOccurs="unbounded"> + <xs:complexType> + <xs:attribute name="id" type="xs:unsignedInt" use="required"/> + <xs:attribute name="x" type="xs:double"/> + <xs:attribute name="y" type="xs:double"/> + <xs:attribute name="mx" type="xs:double"/> + <xs:attribute name="my" type="xs:double"/> + <xs:attribute name="type" type="xs:string"/> + <xs:attribute name="name" type="shortName"/> + <xs:attribute name="firstPoint" type="xs:unsignedInt"/> + <xs:attribute name="secondPoint" type="xs:unsignedInt"/> + <xs:attribute name="thirdPoint" type="xs:unsignedInt"/> + <xs:attribute name="basePoint" type="xs:unsignedInt"/> + <xs:attribute name="pShoulder" type="xs:unsignedInt"/> + <xs:attribute name="p1Line" type="xs:unsignedInt"/> + <xs:attribute name="p2Line" type="xs:unsignedInt"/> + <xs:attribute name="length" type="xs:string"/> + <xs:attribute name="angle" type="xs:string"/> + <xs:attribute name="typeLine" type="xs:string"/> + <xs:attribute name="splinePath" type="xs:unsignedInt"/> + <xs:attribute name="spline" type="xs:unsignedInt"/> + <xs:attribute name="p1Line1" type="xs:unsignedInt"/> + <xs:attribute name="p1Line2" type="xs:unsignedInt"/> + <xs:attribute name="p2Line1" type="xs:unsignedInt"/> + <xs:attribute name="p2Line2" type="xs:unsignedInt"/> + <xs:attribute name="center" type="xs:unsignedInt"/> + <xs:attribute name="radius" type="xs:string"/> + <xs:attribute name="axisP1" type="xs:unsignedInt"/> + <xs:attribute name="axisP2" type="xs:unsignedInt"/> + <xs:attribute name="arc" type="xs:unsignedInt"/> + <xs:attribute name="elArc" type="xs:unsignedInt"/> + <xs:attribute name="curve" type="xs:unsignedInt"/> + <xs:attribute name="curve1" type="xs:unsignedInt"/> + <xs:attribute name="curve2" type="xs:unsignedInt"/> + <xs:attribute name="lineColor" type="colors"/> + <xs:attribute name="color" type="colors"/> + <xs:attribute name="firstArc" type="xs:unsignedInt"/> + <xs:attribute name="secondArc" type="xs:unsignedInt"/> + <xs:attribute name="crossPoint" type="crossType"/> + <xs:attribute name="vCrossPoint" type="crossType"/> + <xs:attribute name="hCrossPoint" type="crossType"/> + <xs:attribute name="c1Center" type="xs:unsignedInt"/> + <xs:attribute name="c2Center" type="xs:unsignedInt"/> + <xs:attribute name="c1Radius" type="xs:string"/> + <xs:attribute name="c2Radius" type="xs:string"/> + <xs:attribute name="cRadius" type="xs:string"/> + <xs:attribute name="tangent" type="xs:unsignedInt"/> + <xs:attribute name="cCenter" type="xs:unsignedInt"/> + <xs:attribute name="name1" type="shortName"/> + <xs:attribute name="mx1" type="xs:double"/> + <xs:attribute name="my1" type="xs:double"/> + <xs:attribute name="name2" type="shortName"/> + <xs:attribute name="mx2" type="xs:double"/> + <xs:attribute name="my2" type="xs:double"/> + <xs:attribute name="point1" type="xs:unsignedInt"/> + <xs:attribute name="point2" type="xs:unsignedInt"/> + <xs:attribute name="dartP1" type="xs:unsignedInt"/> + <xs:attribute name="dartP2" type="xs:unsignedInt"/> + <xs:attribute name="dartP3" type="xs:unsignedInt"/> + <xs:attribute name="baseLineP1" type="xs:unsignedInt"/> + <xs:attribute name="baseLineP2" type="xs:unsignedInt"/> + </xs:complexType> + </xs:element> + <xs:element name="line" minOccurs="0" maxOccurs="unbounded"> + <xs:complexType> + <xs:attribute name="id" type="xs:unsignedInt" use="required"/> + <xs:attribute name="firstPoint" type="xs:unsignedInt"/> + <xs:attribute name="secondPoint" type="xs:unsignedInt"/> + <xs:attribute name="typeLine" type="xs:string"/> + <xs:attribute name="lineColor" type="colors"/> + </xs:complexType> + </xs:element> + <xs:element name="operation" minOccurs="0" maxOccurs="unbounded"> + <xs:complexType> + <xs:sequence> + <xs:element name="source" minOccurs="1" maxOccurs="1"> + <xs:complexType> + <xs:sequence> + <xs:element name="item" minOccurs="1" maxOccurs="unbounded"> + <xs:complexType> + <xs:attribute name="idObject" type="xs:unsignedInt" use="required"/> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="destination" minOccurs="1" maxOccurs="1"> + <xs:complexType> + <xs:sequence> + <xs:element name="item" minOccurs="1" maxOccurs="unbounded"> + <xs:complexType> + <xs:attribute name="idObject" type="xs:unsignedInt" use="required"/> + <xs:attribute name="mx" type="xs:double"/> + <xs:attribute name="my" type="xs:double"/> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + <xs:attribute name="id" type="xs:unsignedInt" use="required"/> + <xs:attribute name="center" type="xs:unsignedInt"/> + <xs:attribute name="angle" type="xs:string"/> + <xs:attribute name="length" type="xs:string"/> + <xs:attribute name="suffix" type="xs:string"/> + <xs:attribute name="type" type="xs:string" use="required"/> + <xs:attribute name="p1Line" type="xs:unsignedInt"/> + <xs:attribute name="p2Line" type="xs:unsignedInt"/> + <xs:attribute name="axisType" type="axisType"/> + </xs:complexType> + </xs:element> + <xs:element name="arc" minOccurs="0" maxOccurs="unbounded"> + <xs:complexType> + <xs:attribute name="angle1" type="xs:string"/> + <xs:attribute name="id" type="xs:unsignedInt" use="required"/> + <xs:attribute name="angle2" type="xs:string"/> + <xs:attribute name="radius" type="xs:string"/> + <xs:attribute name="center" type="xs:unsignedInt"/> + <xs:attribute name="type" type="xs:string"/> + <xs:attribute name="color" type="colors"/> + <xs:attribute name="length" type="xs:string"/> + </xs:complexType> + </xs:element> + <xs:element name="elArc" minOccurs="0" maxOccurs="unbounded"> + <xs:complexType> + <xs:attribute name="angle1" type="xs:string"/> + <xs:attribute name="id" type="xs:unsignedInt" use="required"/> + <xs:attribute name="angle2" type="xs:string"/> + <xs:attribute name="rotationAngle" type="xs:string"/> + <xs:attribute name="radius1" type="xs:string"/> + <xs:attribute name="radius2" type="xs:string"/> + <xs:attribute name="center" type="xs:unsignedInt"/> + <xs:attribute name="type" type="xs:string"/> + <xs:attribute name="color" type="colors"/> + <xs:attribute name="length" type="xs:string"/> + </xs:complexType> + </xs:element> + <xs:element name="spline" minOccurs="0" maxOccurs="unbounded"> + <xs:complexType> + <xs:sequence> + <xs:element name="pathPoint" minOccurs="0" maxOccurs="unbounded"> + <xs:complexType> + <xs:attribute name="kAsm2" type="xs:string"/> + <xs:attribute name="pSpline" type="xs:unsignedInt"/> + <xs:attribute name="angle" type="xs:string"/> + <xs:attribute name="angle1" type="xs:string"/> + <xs:attribute name="angle2" type="xs:string"/> + <xs:attribute name="length1" type="xs:string"/> + <xs:attribute name="length2" type="xs:string"/> + <xs:attribute name="kAsm1" type="xs:string"/> + </xs:complexType> + </xs:element> + </xs:sequence> + <xs:attribute name="id" type="xs:unsignedInt" use="required"/> + <xs:attribute name="kCurve" type="xs:double"/> + <xs:attribute name="type" type="xs:string"/> + <xs:attribute name="kAsm1" type="xs:double"/> + <xs:attribute name="kAsm2" type="xs:double"/> + <xs:attribute name="angle1" type="xs:string"/> + <xs:attribute name="angle2" type="xs:string"/> + <xs:attribute name="length1" type="xs:string"/> + <xs:attribute name="length2" type="xs:string"/> + <xs:attribute name="point1" type="xs:unsignedInt"/> + <xs:attribute name="point2" type="xs:unsignedInt"/> + <xs:attribute name="point3" type="xs:unsignedInt"/> + <xs:attribute name="point4" type="xs:unsignedInt"/> + <xs:attribute name="color" type="colors"/> + <xs:attribute name="duplicate" type="xs:unsignedInt"/> + </xs:complexType> + </xs:element> + </xs:choice> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="modeling" minOccurs="1" maxOccurs="unbounded"> + <xs:complexType> + <xs:sequence> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="point" minOccurs="0" maxOccurs="unbounded"> + <xs:complexType> + <xs:attribute name="id" type="xs:unsignedInt" use="required"/> + <xs:attribute name="idObject" type="xs:unsignedInt"/> + <xs:attribute name="mx" type="xs:double"/> + <xs:attribute name="my" type="xs:double"/> + <xs:attribute name="type" type="xs:string"/> + <xs:attribute name="idTool" type="xs:unsignedInt"/> + <xs:attribute name="inUse" type="xs:boolean"/> + </xs:complexType> + </xs:element> + <xs:element name="arc" minOccurs="0" maxOccurs="unbounded"> + <xs:complexType> + <xs:attribute name="id" type="xs:unsignedInt" use="required"/> + <xs:attribute name="idObject" type="xs:unsignedInt"/> + <xs:attribute name="type" type="xs:string"/> + <xs:attribute name="idTool" type="xs:unsignedInt"/> + <xs:attribute name="inUse" type="xs:boolean"/> + </xs:complexType> + </xs:element> + <xs:element name="elArc" minOccurs="0" maxOccurs="unbounded"> + <xs:complexType> + <xs:attribute name="id" type="xs:unsignedInt" use="required"/> + <xs:attribute name="idObject" type="xs:unsignedInt"/> + <xs:attribute name="type" type="xs:string"/> + <xs:attribute name="idTool" type="xs:unsignedInt"/> + <xs:attribute name="inUse" type="xs:boolean"/> + </xs:complexType> + </xs:element> + <xs:element name="spline" minOccurs="0" maxOccurs="unbounded"> + <xs:complexType> + <xs:attribute name="id" type="xs:unsignedInt" use="required"/> + <xs:attribute name="idObject" type="xs:unsignedInt"/> + <xs:attribute name="type" type="xs:string"/> + <xs:attribute name="idTool" type="xs:unsignedInt"/> + <xs:attribute name="inUse" type="xs:boolean"/> + </xs:complexType> + </xs:element> + <xs:element name="path" minOccurs="0" maxOccurs="unbounded"> + <xs:complexType> + <xs:sequence> + <xs:element name="nodes" minOccurs="1" maxOccurs="1"> + <xs:complexType> + <xs:sequence> + <xs:element name="node" minOccurs="1" maxOccurs="unbounded"> + <xs:complexType> + <xs:attribute name="type" type="xs:string" use="required"/> + <xs:attribute name="idObject" type="xs:unsignedInt" use="required"/> + <xs:attribute name="reverse" type="xs:unsignedInt"/> + <xs:attribute name="before" type="xs:double"/> + <xs:attribute name="after" type="xs:double"/> + <xs:attribute name="angle" type="nodeAngle"/> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + <xs:attribute name="id" type="xs:unsignedInt" use="required"/> + <xs:attribute name="type" type="piecePathType"/> + <xs:attribute name="idTool" type="xs:unsignedInt"/> + <xs:attribute name="inUse" type="xs:boolean"/> + <xs:attribute name="name" type="xs:string"/> + <xs:attribute name="typeLine" type="xs:string"/> + </xs:complexType> + </xs:element> + <xs:element name="tools" minOccurs="0" maxOccurs="unbounded"> + <xs:complexType> + <xs:sequence> + <xs:element name="det" minOccurs="2" maxOccurs="2"> + <xs:complexType> + <xs:sequence> + <xs:element name="nodes" minOccurs="1" maxOccurs="1"> + <xs:complexType> + <xs:sequence> + <xs:element name="node" minOccurs="1" maxOccurs="unbounded"> + <xs:complexType> + <xs:attribute name="type" type="xs:string" use="required"/> + <xs:attribute name="idObject" type="xs:unsignedInt" use="required"/> + <xs:attribute name="reverse" type="xs:unsignedInt"/> + <xs:attribute name="before" type="xs:string"/> + <xs:attribute name="after" type="xs:string"/> + <xs:attribute name="angle" type="nodeAngle"/> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="csa" minOccurs="0" maxOccurs="1"> + <xs:complexType> + <xs:sequence> + <xs:element name="record" minOccurs="1" maxOccurs="unbounded"> + <xs:complexType> + <xs:attribute name="start" type="xs:unsignedInt"/> + <xs:attribute name="path" type="xs:unsignedInt" use="required"/> + <xs:attribute name="end" type="xs:unsignedInt"/> + <xs:attribute name="reverse" type="xs:boolean"/> + <xs:attribute name="includeAs" type="piecePathIncludeType"/> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="iPaths" minOccurs="0" maxOccurs="1"> + <xs:complexType> + <xs:sequence> + <xs:element name="record" minOccurs="1" maxOccurs="unbounded"> + <xs:complexType> + <xs:attribute name="path" type="xs:unsignedInt" use="required"/> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="children" minOccurs="1" maxOccurs="1"> + <xs:complexType> + <xs:sequence> + <xs:element name="nodes" minOccurs="1" maxOccurs="1"> + <xs:complexType> + <xs:sequence> + <xs:element name="child" type="xs:unsignedInt" minOccurs="1" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="csa" minOccurs="0" maxOccurs="1"> + <xs:complexType> + <xs:sequence> + <xs:element name="child" type="xs:unsignedInt" minOccurs="1" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="iPaths" minOccurs="0" maxOccurs="1"> + <xs:complexType> + <xs:sequence> + <xs:element name="child" type="xs:unsignedInt" minOccurs="1" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + <xs:attribute name="id" type="xs:unsignedInt" use="required"/> + <xs:attribute name="type" type="xs:string"/> + <xs:attribute name="indexD1" type="xs:unsignedInt"/> + <xs:attribute name="indexD2" type="xs:unsignedInt"/> + <xs:attribute name="inUse" type="xs:boolean"/> + </xs:complexType> + </xs:element> + </xs:choice> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="details" minOccurs="1" maxOccurs="unbounded"> + <xs:complexType> + <xs:sequence> + <xs:element name="detail" minOccurs="0" maxOccurs="unbounded"> + <xs:complexType> + <xs:sequence> + <xs:element name="data" minOccurs="0" maxOccurs="1"> + <xs:complexType> + <xs:sequence> + <xs:element name="mcp" minOccurs="0" maxOccurs="unbounded"> + <xs:complexType> + <xs:attribute name="cutNumber" type="xs:unsignedInt"/> + <xs:attribute name="userDef" type="xs:string"/> + <xs:attribute name="material" type="materialType"/> + <xs:attribute name="placement" type="placementType"/> + </xs:complexType> + </xs:element> + </xs:sequence> + <xs:attribute name="letter" type="xs:string"/> + <xs:attribute name="visible" type="xs:boolean"/> + <xs:attribute name="fontSize" type="xs:unsignedInt"/> + <xs:attribute name="mx" type="xs:double"/> + <xs:attribute name="my" type="xs:double"/> + <xs:attribute name="width" type="xs:double"/> + <xs:attribute name="height" type="xs:double"/> + <xs:attribute name="rotation" type="xs:double"/> + </xs:complexType> + </xs:element> + <xs:element name="patternInfo" minOccurs="0" maxOccurs="1"> + <xs:complexType> + <xs:attribute name="visible" type="xs:boolean"/> + <xs:attribute name="fontSize" type="xs:unsignedInt"/> + <xs:attribute name="mx" type="xs:double"/> + <xs:attribute name="my" type="xs:double"/> + <xs:attribute name="width" type="xs:double"/> + <xs:attribute name="height" type="xs:double"/> + <xs:attribute name="rotation" type="xs:double"/> + </xs:complexType> + </xs:element> + <xs:element name="grainline" minOccurs="0" maxOccurs="1"> + <xs:complexType> + <xs:attribute name="visible" type="xs:boolean"/> + <xs:attribute name="mx" type="xs:double"/> + <xs:attribute name="my" type="xs:double"/> + <xs:attribute name="length" type="xs:string"/> + <xs:attribute name="rotation" type="xs:string"/> + <xs:attribute name="arrows" type="arrowType"/> + </xs:complexType> + </xs:element> + <xs:element name="nodes" minOccurs="1" maxOccurs="1"> + <xs:complexType> + <xs:sequence> + <xs:element name="node" minOccurs="1" maxOccurs="unbounded"> + <xs:complexType> + <xs:attribute name="type" type="xs:string" use="required"/> + <xs:attribute name="idObject" type="xs:unsignedInt" use="required"/> + <xs:attribute name="reverse" type="xs:unsignedInt"/> + <xs:attribute name="before" type="xs:string"/> + <xs:attribute name="after" type="xs:string"/> + <xs:attribute name="angle" type="nodeAngle"/> + <xs:attribute name="mx" type="xs:double"/> + <xs:attribute name="my" type="xs:double"/> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="csa" minOccurs="0" maxOccurs="1"> + <xs:complexType> + <xs:sequence> + <xs:element name="record" minOccurs="1" maxOccurs="unbounded"> + <xs:complexType> + <xs:attribute name="start" type="xs:unsignedInt"/> + <xs:attribute name="path" type="xs:unsignedInt" use="required"/> + <xs:attribute name="end" type="xs:unsignedInt"/> + <xs:attribute name="reverse" type="xs:boolean"/> + <xs:attribute name="includeAs" type="piecePathIncludeType"/> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="iPaths" minOccurs="0" maxOccurs="1"> + <xs:complexType> + <xs:sequence> + <xs:element name="record" minOccurs="1" maxOccurs="unbounded"> + <xs:complexType> + <xs:attribute name="path" type="xs:unsignedInt" use="required"/> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + <xs:attribute name="id" type="xs:unsignedInt" use="required"/> + <xs:attribute name="version" type="pieceVersion"/> + <xs:attribute name="mx" type="xs:double"/> + <xs:attribute name="my" type="xs:double"/> + <xs:attribute name="name" type="xs:string"/> + <xs:attribute name="inLayout" type="xs:boolean"/> + <xs:attribute name="forbidFlipping" type="xs:boolean"/> + <xs:attribute name="width" type="xs:string"/> + <xs:attribute name="seamAllowance" type="xs:boolean"/> + <xs:attribute name="united" type="xs:boolean"/> + <xs:attribute name="closed" type="xs:unsignedInt"/> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="groups" minOccurs="0" maxOccurs="1"> + <xs:complexType> + <xs:sequence> + <xs:element name="group" minOccurs="0" maxOccurs="unbounded"> + <xs:complexType> + <xs:sequence> + <xs:element name="item" maxOccurs="unbounded"> + <xs:complexType> + <xs:attribute name="object" type="xs:unsignedInt"/> + <xs:attribute name="tool" type="xs:unsignedInt"/> + </xs:complexType> + </xs:element> + </xs:sequence> + <xs:attribute name="id" type="xs:unsignedInt" use="required"/> + <xs:attribute name="name" type="xs:string"/> + <xs:attribute name="visible" type="xs:boolean"/> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + <xs:attribute name="name" type="xs:string"/> + </xs:complexType> + </xs:element> + </xs:sequence> + <xs:attribute name="readOnly" type="xs:boolean"/> + </xs:complexType> + </xs:element> + <xs:simpleType name="shortName"> + <xs:restriction base="xs:string"> + <xs:pattern value="^([^\p{Nd}\p{Zs}*/&|!<>^\-()–+−=?:;'\"]){1,1}([^\p{Zs}*/&|!<>^\-()–+−=?:;\"]){0,}$"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="units"> + <xs:restriction base="xs:string"> + <xs:enumeration value="mm"/> + <xs:enumeration value="cm"/> + <xs:enumeration value="inch"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="measurementsTypes"> + <xs:restriction base="xs:string"> + <xs:enumeration value="standard"/> + <xs:enumeration value="individual"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="formatVersion"> + <xs:restriction base="xs:string"> + <xs:pattern value="^(0|([1-9][0-9]*))\.(0|([1-9][0-9]*))\.(0|([1-9][0-9]*))$"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="imageExtension"> + <xs:restriction base="xs:string"> + <xs:enumeration value="PNG"/> + <xs:enumeration value="JPG"/> + <xs:enumeration value="BMP"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="colors"> + <xs:restriction base="xs:string"> + <xs:enumeration value="black"/> + <xs:enumeration value="green"/> + <xs:enumeration value="blue"/> + <xs:enumeration value="darkRed"/> + <xs:enumeration value="darkGreen"/> + <xs:enumeration value="darkBlue"/> + <xs:enumeration value="yellow"/> + <xs:enumeration value="lightsalmon"/> + <xs:enumeration value="goldenrod"/> + <xs:enumeration value="orange"/> + <xs:enumeration value="deeppink"/> + <xs:enumeration value="violet"/> + <xs:enumeration value="darkviolet"/> + <xs:enumeration value="mediumseagreen"/> + <xs:enumeration value="lime"/> + <xs:enumeration value="deepskyblue"/> + <xs:enumeration value="cornflowerblue"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="baseHeight"> + <xs:restriction base="xs:unsignedInt"> + <xs:enumeration value="50"/> + <xs:enumeration value="56"/> + <xs:enumeration value="62"/> + <xs:enumeration value="68"/> + <xs:enumeration value="74"/> + <xs:enumeration value="80"/> + <xs:enumeration value="86"/> + <xs:enumeration value="92"/> + <xs:enumeration value="98"/> + <xs:enumeration value="104"/> + <xs:enumeration value="110"/> + <xs:enumeration value="116"/> + <xs:enumeration value="122"/> + <xs:enumeration value="128"/> + <xs:enumeration value="134"/> + <xs:enumeration value="140"/> + <xs:enumeration value="146"/> + <xs:enumeration value="152"/> + <xs:enumeration value="158"/> + <xs:enumeration value="164"/> + <xs:enumeration value="170"/> + <xs:enumeration value="176"/> + <xs:enumeration value="182"/> + <xs:enumeration value="188"/> + <xs:enumeration value="194"/> + <xs:enumeration value="500"/> + <xs:enumeration value="560"/> + <xs:enumeration value="620"/> + <xs:enumeration value="680"/> + <xs:enumeration value="740"/> + <xs:enumeration value="800"/> + <xs:enumeration value="860"/> + <xs:enumeration value="920"/> + <xs:enumeration value="980"/> + <xs:enumeration value="1040"/> + <xs:enumeration value="1100"/> + <xs:enumeration value="1160"/> + <xs:enumeration value="1220"/> + <xs:enumeration value="1280"/> + <xs:enumeration value="1340"/> + <xs:enumeration value="1400"/> + <xs:enumeration value="1460"/> + <xs:enumeration value="1520"/> + <xs:enumeration value="1580"/> + <xs:enumeration value="1640"/> + <xs:enumeration value="1700"/> + <xs:enumeration value="1760"/> + <xs:enumeration value="1820"/> + <xs:enumeration value="1880"/> + <xs:enumeration value="1940"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="baseSize"> + <xs:restriction base="xs:unsignedInt"> + <xs:enumeration value="22"/> + <xs:enumeration value="24"/> + <xs:enumeration value="26"/> + <xs:enumeration value="28"/> + <xs:enumeration value="30"/> + <xs:enumeration value="32"/> + <xs:enumeration value="34"/> + <xs:enumeration value="36"/> + <xs:enumeration value="38"/> + <xs:enumeration value="40"/> + <xs:enumeration value="42"/> + <xs:enumeration value="44"/> + <xs:enumeration value="46"/> + <xs:enumeration value="48"/> + <xs:enumeration value="50"/> + <xs:enumeration value="52"/> + <xs:enumeration value="54"/> + <xs:enumeration value="56"/> + <xs:enumeration value="220"/> + <xs:enumeration value="240"/> + <xs:enumeration value="260"/> + <xs:enumeration value="280"/> + <xs:enumeration value="300"/> + <xs:enumeration value="320"/> + <xs:enumeration value="340"/> + <xs:enumeration value="360"/> + <xs:enumeration value="380"/> + <xs:enumeration value="400"/> + <xs:enumeration value="420"/> + <xs:enumeration value="440"/> + <xs:enumeration value="460"/> + <xs:enumeration value="480"/> + <xs:enumeration value="500"/> + <xs:enumeration value="520"/> + <xs:enumeration value="540"/> + <xs:enumeration value="560"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="crossType"> + <xs:restriction base="xs:unsignedInt"> + <xs:enumeration value="1"/> + <xs:enumeration value="2"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="axisType"> + <xs:restriction base="xs:unsignedInt"> + <xs:enumeration value="1"/> + <xs:enumeration value="2"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="materialType"> + <xs:restriction base="xs:unsignedInt"> + <xs:enumeration value="0"/> + <!--Fabric--> + <xs:enumeration value="1"/> + <!--Lining--> + <xs:enumeration value="2"/> + <!--Interfacing--> + <xs:enumeration value="3"/> + <!--Interlining--> + <xs:enumeration value="4"/> + <!--UserDefined--> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="placementType"> + <xs:restriction base="xs:unsignedInt"> + <xs:enumeration value="0"/> + <!--No placement--> + <xs:enumeration value="1"/> + <!--Cut on Fold--> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="arrowType"> + <xs:restriction base="xs:unsignedInt"> + <xs:enumeration value="0"/> + <!--Both--> + <xs:enumeration value="1"/> + <!--Front--> + <xs:enumeration value="2"/> + <!--Rear--> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="pieceVersion"> + <xs:restriction base="xs:unsignedInt"> + <xs:enumeration value="1"/> + <!--Old version--> + <xs:enumeration value="2"/> + <!--New version--> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="nodeAngle"> + <xs:restriction base="xs:unsignedInt"> + <xs:enumeration value="0"/> + <!--by length--> + <xs:enumeration value="1"/> + <!--by points intersections--> + <xs:enumeration value="2"/> + <!--by second edge symmetry--> + <xs:enumeration value="3"/> + <!--by first edge symmetry--> + <xs:enumeration value="4"/> + <!--by first edge right angle--> + <xs:enumeration value="5"/> + <!--by first edge right angle--> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="piecePathType"> + <xs:restriction base="xs:unsignedInt"> + <xs:enumeration value="1"/> + <!--custom seam allowance--> + <xs:enumeration value="2"/> + <!--internal path--> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="piecePathIncludeType"> + <xs:restriction base="xs:unsignedInt"> + <xs:enumeration value="0"/> + <!--as main path--> + <xs:enumeration value="1"/> + <!--as custom seam allowance--> + </xs:restriction> + </xs:simpleType> +</xs:schema> diff --git a/src/libs/ifc/schema/standard_measurements/v0.4.3.xsd b/src/libs/ifc/schema/standard_measurements/v0.4.3.xsd index dc72b8300..4b246e839 100644 --- a/src/libs/ifc/schema/standard_measurements/v0.4.3.xsd +++ b/src/libs/ifc/schema/standard_measurements/v0.4.3.xsd @@ -1,160 +1,160 @@ <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> - <xs:element name="vst"> - <xs:complexType> - <xs:sequence> - <xs:element name="version" type="formatVersion"></xs:element> - <xs:element name="read-only" type="xs:boolean"></xs:element> - <xs:element name="notes" type="xs:string" minOccurs="0" maxOccurs="1"></xs:element> - <xs:element name="unit" type="units"></xs:element> - <xs:element name="pm_system" type="psCode"></xs:element> - <xs:element name="size"> - <xs:complexType> - <xs:attribute name="base" type="baseSize" use="required"></xs:attribute> - </xs:complexType> - </xs:element> - <xs:element name="height"> - <xs:complexType> - <xs:attribute name="base" type="baseHeight" use="required"></xs:attribute> - </xs:complexType> - </xs:element> - <xs:element name="body-measurements"> - <xs:complexType> - <xs:sequence> - <xs:element name="m" minOccurs="0" maxOccurs="unbounded"> - <xs:complexType> - <xs:attribute name="name" type="shortName" use="required"></xs:attribute> - <xs:attribute name="base" type="xs:double" use="required"></xs:attribute> - <xs:attribute name="height_increase" type="xs:double" use="required"></xs:attribute> - <xs:attribute name="size_increase" type="xs:double" use="required"></xs:attribute> - <xs:attribute name="full_name" type="xs:string"></xs:attribute> - <xs:attribute name="description" type="xs:string"></xs:attribute> - </xs:complexType> - </xs:element> - </xs:sequence> - </xs:complexType> - </xs:element> - </xs:sequence> - </xs:complexType> - <xs:unique name="measurementName"> - <xs:selector xpath="body-measurements/m"/> - <xs:field xpath="@name"/> - </xs:unique> - </xs:element> - <xs:simpleType name="shortName"> - <xs:restriction base="xs:string"> - <xs:pattern value="^([^\p{Nd}\p{Zs}*/&|!<>^\-()–+−=?:;'\"]){1,1}([^\p{Zs}*/&|!<>^\-()–+−=?:;\"]){0,}$"/> - </xs:restriction> - </xs:simpleType> - <xs:simpleType name="units"> - <xs:restriction base="xs:string"> - <xs:enumeration value="mm"/> - <xs:enumeration value="cm"/> - <xs:enumeration value="inch"/> - </xs:restriction> - </xs:simpleType> - <xs:simpleType name="formatVersion"> - <xs:restriction base="xs:string"> - <xs:pattern value="^(0|([1-9][0-9]*))\.(0|([1-9][0-9]*))\.(0|([1-9][0-9]*))$"/> - </xs:restriction> - </xs:simpleType> - <xs:simpleType name="psCode"> - <xs:restriction base="xs:string"> - <xs:pattern value="^^(([0-9]|[1-4][0-9]|5[0-4])|998)$"/> - </xs:restriction> - </xs:simpleType> - <xs:simpleType name="baseHeight"> - <xs:restriction base="xs:unsignedInt"> - <xs:enumeration value="50"/> - <xs:enumeration value="56"/> - <xs:enumeration value="62"/> - <xs:enumeration value="68"/> - <xs:enumeration value="74"/> - <xs:enumeration value="80"/> - <xs:enumeration value="86"/> - <xs:enumeration value="92"/> - <xs:enumeration value="98"/> - <xs:enumeration value="104"/> - <xs:enumeration value="110"/> - <xs:enumeration value="116"/> - <xs:enumeration value="122"/> - <xs:enumeration value="128"/> - <xs:enumeration value="134"/> - <xs:enumeration value="140"/> - <xs:enumeration value="146"/> - <xs:enumeration value="152"/> - <xs:enumeration value="158"/> - <xs:enumeration value="164"/> - <xs:enumeration value="170"/> - <xs:enumeration value="176"/> - <xs:enumeration value="182"/> - <xs:enumeration value="188"/> - <xs:enumeration value="194"/> - <xs:enumeration value="500"/> - <xs:enumeration value="560"/> - <xs:enumeration value="620"/> - <xs:enumeration value="680"/> - <xs:enumeration value="740"/> - <xs:enumeration value="800"/> - <xs:enumeration value="860"/> - <xs:enumeration value="920"/> - <xs:enumeration value="980"/> - <xs:enumeration value="1040"/> - <xs:enumeration value="1100"/> - <xs:enumeration value="1160"/> - <xs:enumeration value="1220"/> - <xs:enumeration value="1280"/> - <xs:enumeration value="1340"/> - <xs:enumeration value="1400"/> - <xs:enumeration value="1460"/> - <xs:enumeration value="1520"/> - <xs:enumeration value="1580"/> - <xs:enumeration value="1640"/> - <xs:enumeration value="1700"/> - <xs:enumeration value="1760"/> - <xs:enumeration value="1820"/> - <xs:enumeration value="1880"/> - <xs:enumeration value="1940"/> - </xs:restriction> - </xs:simpleType> - <xs:simpleType name="baseSize"> - <xs:restriction base="xs:unsignedInt"> - <xs:enumeration value="22"/> - <xs:enumeration value="24"/> - <xs:enumeration value="26"/> - <xs:enumeration value="28"/> - <xs:enumeration value="30"/> - <xs:enumeration value="32"/> - <xs:enumeration value="34"/> - <xs:enumeration value="36"/> - <xs:enumeration value="38"/> - <xs:enumeration value="40"/> - <xs:enumeration value="42"/> - <xs:enumeration value="44"/> - <xs:enumeration value="46"/> - <xs:enumeration value="48"/> - <xs:enumeration value="50"/> - <xs:enumeration value="52"/> - <xs:enumeration value="54"/> - <xs:enumeration value="56"/> - <xs:enumeration value="220"/> - <xs:enumeration value="240"/> - <xs:enumeration value="260"/> - <xs:enumeration value="280"/> - <xs:enumeration value="300"/> - <xs:enumeration value="320"/> - <xs:enumeration value="340"/> - <xs:enumeration value="360"/> - <xs:enumeration value="380"/> - <xs:enumeration value="400"/> - <xs:enumeration value="420"/> - <xs:enumeration value="440"/> - <xs:enumeration value="460"/> - <xs:enumeration value="480"/> - <xs:enumeration value="500"/> - <xs:enumeration value="520"/> - <xs:enumeration value="540"/> - <xs:enumeration value="560"/> - </xs:restriction> - </xs:simpleType> + <xs:element name="vst"> + <xs:complexType> + <xs:sequence> + <xs:element name="version" type="formatVersion"/> + <xs:element name="read-only" type="xs:boolean"/> + <xs:element name="notes" type="xs:string" minOccurs="0" maxOccurs="1"/> + <xs:element name="unit" type="units"/> + <xs:element name="pm_system" type="psCode"/> + <xs:element name="size"> + <xs:complexType> + <xs:attribute name="base" type="baseSize" use="required"/> + </xs:complexType> + </xs:element> + <xs:element name="height"> + <xs:complexType> + <xs:attribute name="base" type="baseHeight" use="required"/> + </xs:complexType> + </xs:element> + <xs:element name="body-measurements"> + <xs:complexType> + <xs:sequence> + <xs:element name="m" minOccurs="0" maxOccurs="unbounded"> + <xs:complexType> + <xs:attribute name="name" type="shortName" use="required"/> + <xs:attribute name="base" type="xs:double" use="required"/> + <xs:attribute name="height_increase" type="xs:double" use="required"/> + <xs:attribute name="size_increase" type="xs:double" use="required"/> + <xs:attribute name="full_name" type="xs:string"/> + <xs:attribute name="description" type="xs:string"/> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:unique name="measurementName"> + <xs:selector xpath="body-measurements/m"/> + <xs:field xpath="@name"/> + </xs:unique> + </xs:element> + <xs:simpleType name="shortName"> + <xs:restriction base="xs:string"> + <xs:pattern value="^([^\p{Nd}\p{Zs}*/&|!<>^\-()–+−=?:;'\"]){1,1}([^\p{Zs}*/&|!<>^\-()–+−=?:;\"]){0,}$"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="units"> + <xs:restriction base="xs:string"> + <xs:enumeration value="mm"/> + <xs:enumeration value="cm"/> + <xs:enumeration value="inch"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="formatVersion"> + <xs:restriction base="xs:string"> + <xs:pattern value="^(0|([1-9][0-9]*))\.(0|([1-9][0-9]*))\.(0|([1-9][0-9]*))$"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="psCode"> + <xs:restriction base="xs:string"> + <xs:pattern value="^^(([0-9]|[1-4][0-9]|5[0-4])|998)$"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="baseHeight"> + <xs:restriction base="xs:unsignedInt"> + <xs:enumeration value="50"/> + <xs:enumeration value="56"/> + <xs:enumeration value="62"/> + <xs:enumeration value="68"/> + <xs:enumeration value="74"/> + <xs:enumeration value="80"/> + <xs:enumeration value="86"/> + <xs:enumeration value="92"/> + <xs:enumeration value="98"/> + <xs:enumeration value="104"/> + <xs:enumeration value="110"/> + <xs:enumeration value="116"/> + <xs:enumeration value="122"/> + <xs:enumeration value="128"/> + <xs:enumeration value="134"/> + <xs:enumeration value="140"/> + <xs:enumeration value="146"/> + <xs:enumeration value="152"/> + <xs:enumeration value="158"/> + <xs:enumeration value="164"/> + <xs:enumeration value="170"/> + <xs:enumeration value="176"/> + <xs:enumeration value="182"/> + <xs:enumeration value="188"/> + <xs:enumeration value="194"/> + <xs:enumeration value="500"/> + <xs:enumeration value="560"/> + <xs:enumeration value="620"/> + <xs:enumeration value="680"/> + <xs:enumeration value="740"/> + <xs:enumeration value="800"/> + <xs:enumeration value="860"/> + <xs:enumeration value="920"/> + <xs:enumeration value="980"/> + <xs:enumeration value="1040"/> + <xs:enumeration value="1100"/> + <xs:enumeration value="1160"/> + <xs:enumeration value="1220"/> + <xs:enumeration value="1280"/> + <xs:enumeration value="1340"/> + <xs:enumeration value="1400"/> + <xs:enumeration value="1460"/> + <xs:enumeration value="1520"/> + <xs:enumeration value="1580"/> + <xs:enumeration value="1640"/> + <xs:enumeration value="1700"/> + <xs:enumeration value="1760"/> + <xs:enumeration value="1820"/> + <xs:enumeration value="1880"/> + <xs:enumeration value="1940"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="baseSize"> + <xs:restriction base="xs:unsignedInt"> + <xs:enumeration value="22"/> + <xs:enumeration value="24"/> + <xs:enumeration value="26"/> + <xs:enumeration value="28"/> + <xs:enumeration value="30"/> + <xs:enumeration value="32"/> + <xs:enumeration value="34"/> + <xs:enumeration value="36"/> + <xs:enumeration value="38"/> + <xs:enumeration value="40"/> + <xs:enumeration value="42"/> + <xs:enumeration value="44"/> + <xs:enumeration value="46"/> + <xs:enumeration value="48"/> + <xs:enumeration value="50"/> + <xs:enumeration value="52"/> + <xs:enumeration value="54"/> + <xs:enumeration value="56"/> + <xs:enumeration value="220"/> + <xs:enumeration value="240"/> + <xs:enumeration value="260"/> + <xs:enumeration value="280"/> + <xs:enumeration value="300"/> + <xs:enumeration value="320"/> + <xs:enumeration value="340"/> + <xs:enumeration value="360"/> + <xs:enumeration value="380"/> + <xs:enumeration value="400"/> + <xs:enumeration value="420"/> + <xs:enumeration value="440"/> + <xs:enumeration value="460"/> + <xs:enumeration value="480"/> + <xs:enumeration value="500"/> + <xs:enumeration value="520"/> + <xs:enumeration value="540"/> + <xs:enumeration value="560"/> + </xs:restriction> + </xs:simpleType> </xs:schema> diff --git a/src/libs/ifc/xml/vabstractpattern.cpp b/src/libs/ifc/xml/vabstractpattern.cpp index e1e5071c5..122428173 100644 --- a/src/libs/ifc/xml/vabstractpattern.cpp +++ b/src/libs/ifc/xml/vabstractpattern.cpp @@ -45,6 +45,7 @@ #include "../ifc/exception/vexceptionbadid.h" #include "../ifc/ifcdef.h" #include "../vpatterndb/vcontainer.h" +#include "../vpatterndb/vpiecenode.h" #include "../vtools/tools/vdatatool.h" #include "vpatternconverter.h" #include "vdomdocument.h" @@ -90,6 +91,9 @@ const QString VAbstractPattern::TagSize = QStringLiteral("size"); const QString VAbstractPattern::TagShowDate = QStringLiteral("showDate"); const QString VAbstractPattern::TagShowMeasurements = QStringLiteral("showMeasurements"); const QString VAbstractPattern::TagGrainline = QStringLiteral("grainline"); +const QString VAbstractPattern::TagPath = QStringLiteral("path"); +const QString VAbstractPattern::TagNodes = QStringLiteral("nodes"); +const QString VAbstractPattern::TagNode = QStringLiteral("node"); const QString VAbstractPattern::AttrName = QStringLiteral("name"); const QString VAbstractPattern::AttrVisible = QStringLiteral("visible"); @@ -102,6 +106,15 @@ const QString VAbstractPattern::AttrUserDefined = QStringLiteral("userDef"); const QString VAbstractPattern::AttrCutNumber = QStringLiteral("cutNumber"); const QString VAbstractPattern::AttrPlacement = QStringLiteral("placement"); const QString VAbstractPattern::AttrArrows = QStringLiteral("arrows"); +const QString VAbstractPattern::AttrNodeReverse = QStringLiteral("reverse"); +const QString VAbstractPattern::AttrSABefore = QStringLiteral("before"); +const QString VAbstractPattern::AttrSAAfter = QStringLiteral("after"); +const QString VAbstractPattern::AttrStart = QStringLiteral("start"); +const QString VAbstractPattern::AttrPath = QStringLiteral("path"); +const QString VAbstractPattern::AttrEnd = QStringLiteral("end"); +const QString VAbstractPattern::AttrIncludeAs = QStringLiteral("includeAs"); +const QString VAbstractPattern::AttrWidth = QStringLiteral("width"); +const QString VAbstractPattern::AttrRotation = QStringLiteral("rotation"); const QString VAbstractPattern::AttrAll = QStringLiteral("all"); @@ -159,10 +172,23 @@ const QString VAbstractPattern::IncrementName = QStringLiteral("name"); const QString VAbstractPattern::IncrementFormula = QStringLiteral("formula"); const QString VAbstractPattern::IncrementDescription = QStringLiteral("description"); +const QString VAbstractPattern::NodeArc = QStringLiteral("NodeArc"); +const QString VAbstractPattern::NodeElArc = QStringLiteral("NodeElArc"); +const QString VAbstractPattern::NodePoint = QStringLiteral("NodePoint"); +const QString VAbstractPattern::NodeSpline = QStringLiteral("NodeSpline"); +const QString VAbstractPattern::NodeSplinePath = QStringLiteral("NodeSplinePath"); + +QHash<quint32, VDataTool*> VAbstractPattern::tools = QHash<quint32, VDataTool*>(); + //--------------------------------------------------------------------------------------------------------------------- VAbstractPattern::VAbstractPattern(QObject *parent) - : QObject(parent), VDomDocument(), nameActivPP(QString()), cursor(0), tools(QHash<quint32, VDataTool*>()), - toolsOnRemove(QVector<VDataTool*>()), history(QVector<VToolRecord>()), patternPieces(QStringList()), + : QObject(parent), + VDomDocument(), + nameActivPP(QString()), + cursor(0), + toolsOnRemove(QVector<VDataTool*>()), + history(QVector<VToolRecord>()), + patternPieces(QStringList()), modified(false) {} @@ -520,7 +546,7 @@ void VAbstractPattern::setCursor(const quint32 &value) * @param id tool id. * @return tool. */ -VDataTool *VAbstractPattern::getTool(const quint32 &id) +VDataTool *VAbstractPattern::getTool(quint32 id) { ToolExists(id); return tools.value(id); @@ -532,11 +558,126 @@ VDataTool *VAbstractPattern::getTool(const quint32 &id) * @param id tool id. * @param tool tool. */ -void VAbstractPattern::AddTool(const quint32 &id, VDataTool *tool) +void VAbstractPattern::AddTool(quint32 id, VDataTool *tool) { Q_ASSERT_X(id != 0, Q_FUNC_INFO, "id == 0"); SCASSERT(tool != nullptr) - tools.insert(id, tool); + tools.insert(id, tool); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VAbstractPattern::RemoveTool(quint32 id) +{ + tools.remove(id); +} + +//--------------------------------------------------------------------------------------------------------------------- +VPiecePath VAbstractPattern::ParsePieceNodes(const QDomElement &domElement) +{ + VPiecePath path; + const QDomNodeList nodeList = domElement.childNodes(); + for (qint32 i = 0; i < nodeList.size(); ++i) + { + const QDomElement element = nodeList.at(i).toElement(); + if (not element.isNull()) + { + path.Append(ParseSANode(element)); + } + } + return path; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<CustomSARecord> VAbstractPattern::ParsePieceCSARecords(const QDomElement &domElement) +{ + QVector<CustomSARecord> records; + const QDomNodeList nodeList = domElement.childNodes(); + for (qint32 i = 0; i < nodeList.size(); ++i) + { + const QDomElement element = nodeList.at(i).toElement(); + if (not element.isNull()) + { + CustomSARecord record; + record.startPoint = GetParametrUInt(element, VAbstractPattern::AttrStart, NULL_ID_STR); + record.path = GetParametrUInt(element, VAbstractPattern::AttrPath, NULL_ID_STR); + record.endPoint = GetParametrUInt(element, VAbstractPattern::AttrEnd, NULL_ID_STR); + record.reverse = GetParametrBool(element, VAbstractPattern::AttrNodeReverse, falseStr); + record.includeType = static_cast<PiecePathIncludeType>(GetParametrUInt(element, + VAbstractPattern::AttrIncludeAs, + "1")); + records.append(record); + } + } + return records; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<quint32> VAbstractPattern::ParsePieceInternalPaths(const QDomElement &domElement) +{ + QVector<quint32> records; + const QDomNodeList nodeList = domElement.childNodes(); + for (qint32 i = 0; i < nodeList.size(); ++i) + { + const QDomElement element = nodeList.at(i).toElement(); + if (not element.isNull()) + { + const quint32 path = GetParametrUInt(element, VAbstractPattern::AttrPath, NULL_ID_STR); + if (path > NULL_ID) + { + records.append(path); + } + } + } + return records; +} + +//--------------------------------------------------------------------------------------------------------------------- +VPieceNode VAbstractPattern::ParseSANode(const QDomElement &domElement) +{ + const quint32 id = VDomDocument::GetParametrUInt(domElement, AttrIdObject, NULL_ID_STR); + const bool reverse = VDomDocument::GetParametrUInt(domElement, VAbstractPattern::AttrNodeReverse, "0"); + const QString saBefore = VDomDocument::GetParametrString(domElement, VAbstractPattern::AttrSABefore, + currentSeamAllowance); + const QString saAfter = VDomDocument::GetParametrString(domElement, VAbstractPattern::AttrSAAfter, + currentSeamAllowance); + const PieceNodeAngle angle = static_cast<PieceNodeAngle>(VDomDocument::GetParametrUInt(domElement, AttrAngle, "0")); + + const QString t = VDomDocument::GetParametrString(domElement, AttrType, VAbstractPattern::NodePoint); + Tool tool; + + const QStringList types = QStringList() << VAbstractPattern::NodePoint + << VAbstractPattern::NodeArc + << VAbstractPattern::NodeSpline + << VAbstractPattern::NodeSplinePath + << VAbstractPattern::NodeElArc; + + switch (types.indexOf(t)) + { + case 0: // VAbstractPattern::NodePoint + tool = Tool::NodePoint; + break; + case 1: // VAbstractPattern::NodeArc + tool = Tool::NodeArc; + break; + case 2: // VAbstractPattern::NodeSpline + tool = Tool::NodeSpline; + break; + case 3: // VAbstractPattern::NodeSplinePath + tool = Tool::NodeSplinePath; + break; + case 4: // NodeElArc + tool = Tool::NodeElArc; + break; + default: + VException e(QObject::tr("Wrong tag name '%1'.").arg(t)); + throw e; + } + VPieceNode node(id, tool, reverse); + node.SetFormulaSABefore(saBefore); + node.SetFormulaSAAfter(saAfter); + node.SetAngleType(angle); + + return node; } //--------------------------------------------------------------------------------------------------------------------- @@ -635,7 +776,7 @@ quint32 VAbstractPattern::SiblingNodeId(const quint32 &nodeId) const const VToolRecord tool = history.at(j-1); switch ( tool.getTypeTool() ) { - case Tool::Detail: + case Tool::Piece: case Tool::UnionDetails: case Tool::NodeArc: case Tool::NodeElArc: @@ -1255,7 +1396,7 @@ void VAbstractPattern::SelectedDetail(quint32 id) } //--------------------------------------------------------------------------------------------------------------------- -void VAbstractPattern::ToolExists(const quint32 &id) const +void VAbstractPattern::ToolExists(const quint32 &id) { if (tools.contains(id) == false) { @@ -1263,6 +1404,22 @@ void VAbstractPattern::ToolExists(const quint32 &id) const } } +//--------------------------------------------------------------------------------------------------------------------- +VPiecePath VAbstractPattern::ParsePathNodes(const QDomElement &domElement) +{ + VPiecePath path; + const QDomNodeList nodeList = domElement.childNodes(); + for (qint32 i = 0; i < nodeList.size(); ++i) + { + const QDomElement element = nodeList.at(i).toElement(); + if (not element.isNull() && element.tagName() == VAbstractPattern::TagNode) + { + path.Append(ParseSANode(element)); + } + } + return path; +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief SetActivPP set current pattern piece. @@ -1411,12 +1568,16 @@ QStringList VAbstractPattern::ListExpressions() const QStringList list; // If new tool bring absolutely new type and has formula(s) create new method to cover it. + // Note. Tool Union Details also contains formulas, but we don't use them for union and keep only to simplifying + // working with nodes. Same code for saving reading. list << ListPointExpressions(); list << ListArcExpressions(); list << ListElArcExpressions(); list << ListSplineExpressions(); list << ListIncrementExpressions(); list << ListOperationExpressions(); + list << ListPathExpressions(); + list << ListPieceExpressions(); return list; } @@ -1427,7 +1588,7 @@ QStringList VAbstractPattern::ListPointExpressions() const // Check if new tool doesn't bring new attribute with a formula. // If no just increment a number. // If new tool bring absolutely new type and has formula(s) create new method to cover it. - Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 50); + Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 51); QStringList expressions; const QDomNodeList list = elementsByTagName(TagPoint); @@ -1499,7 +1660,7 @@ QStringList VAbstractPattern::ListArcExpressions() const // Check if new tool doesn't bring new attribute with a formula. // If no just increment number. // If new tool bring absolutely new type and has formula(s) create new method to cover it. - Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 50); + Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 51); QStringList expressions; const QDomNodeList list = elementsByTagName(TagArc); @@ -1553,7 +1714,7 @@ QStringList VAbstractPattern::ListElArcExpressions() const // Check if new tool doesn't bring new attribute with a formula. // If no just increment number. // If new tool bring absolutely new type and has formula(s) create new method to cover it. - Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 50); + Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 51); QStringList expressions; const QDomNodeList list = elementsByTagName(TagElArc); @@ -1624,7 +1785,7 @@ QStringList VAbstractPattern::ListPathPointExpressions() const // Check if new tool doesn't bring new attribute with a formula. // If no just increment number. // If new tool bring absolutely new type and has formula(s) create new method to cover it. - Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 50); + Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 51); QStringList expressions; const QDomNodeList list = elementsByTagName(AttrPathPoint); @@ -1691,7 +1852,7 @@ QStringList VAbstractPattern::ListOperationExpressions() const // Check if new tool doesn't bring new attribute with a formula. // If no just increment number. // If new tool bring absolutely new type and has formula(s) create new method to cover it. - Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 50); + Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 51); QStringList expressions; const QDomNodeList list = elementsByTagName(TagOperation); @@ -1722,6 +1883,112 @@ QStringList VAbstractPattern::ListOperationExpressions() const return expressions; } +//--------------------------------------------------------------------------------------------------------------------- +QStringList VAbstractPattern::ListNodesExpressions(const QDomElement &nodes) const +{ + QStringList expressions; + VPiecePath path; + if (not nodes.isNull()) + { + path = ParsePathNodes(nodes); + } + + for(int i = 0; i < path.CountNodes(); ++i) + { + expressions.append(path.at(i).GetFormulaSABefore()); + expressions.append(path.at(i).GetFormulaSAAfter()); + } + return expressions; +} + +//--------------------------------------------------------------------------------------------------------------------- +QStringList VAbstractPattern::ListPathExpressions() const +{ + // Check if new tool doesn't bring new attribute with a formula. + // If no just increment number. + // If new tool bring absolutely new type and has formula(s) create new method to cover it. + Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 51); + + QStringList expressions; + const QDomNodeList list = elementsByTagName(TagPath); + for (int i=0; i < list.size(); ++i) + { + const QDomElement dom = list.at(i).toElement(); + if (dom.isNull()) + { + continue; + } + + expressions << ListNodesExpressions(dom.firstChildElement(TagNodes)); + } + + return expressions; +} + +//--------------------------------------------------------------------------------------------------------------------- +QStringList VAbstractPattern::ListGrainlineExpressions(const QDomElement &element) const +{ + QStringList expressions; + if (not element.isNull()) + { + // Each tag can contains several attributes. + try + { + expressions.append(GetParametrString(element, AttrRotation)); + } + catch (VExceptionEmptyParameter &e) + { + Q_UNUSED(e) + } + + try + { + expressions.append(GetParametrString(element, AttrLength)); + } + catch (VExceptionEmptyParameter &e) + { + Q_UNUSED(e) + } + } + + return expressions; +} + +//--------------------------------------------------------------------------------------------------------------------- +QStringList VAbstractPattern::ListPieceExpressions() const +{ + // Check if new tool doesn't bring new attribute with a formula. + // If no just increment number. + // If new tool bring absolutely new type and has formula(s) create new method to cover it. + Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 51); + + QStringList expressions; + const QDomNodeList list = elementsByTagName(TagDetail); + for (int i=0; i < list.size(); ++i) + { + const QDomElement dom = list.at(i).toElement(); + if (dom.isNull()) + { + continue; + } + + // Each tag can contains several attributes. + try + { + expressions.append(GetParametrString(dom, AttrWidth)); + } + catch (VExceptionEmptyParameter &e) + { + Q_UNUSED(e) + } + + expressions << ListNodesExpressions(dom.firstChildElement(TagNodes)); + expressions << ListGrainlineExpressions(dom.firstChildElement(TagGrainline)); + } + + return expressions; +} + //--------------------------------------------------------------------------------------------------------------------- bool VAbstractPattern::IsVariable(const QString &token) const { diff --git a/src/libs/ifc/xml/vabstractpattern.h b/src/libs/ifc/xml/vabstractpattern.h index 213479757..2e590c9a1 100644 --- a/src/libs/ifc/xml/vabstractpattern.h +++ b/src/libs/ifc/xml/vabstractpattern.h @@ -45,6 +45,8 @@ #include "vtoolrecord.h" class QDomElement; +class VPiecePath; +class VPieceNode; enum class Document : char { LiteParse, LitePPParse, FullParse }; enum class LabelType : char {NewPatternPiece, NewLabel}; @@ -77,7 +79,6 @@ public: bool ChangeNamePP(const QString& oldName, const QString &newName); bool appendPP(const QString& name); - bool GetActivDrawElement(QDomElement &element) const; bool GetActivNodeElement(const QString& name, QDomElement& element) const; quint32 getCursor() const; @@ -91,9 +92,13 @@ public: virtual void UpdateToolData(const quint32 &id, VContainer *data)=0; - QHash<quint32, VDataTool *> *getTools(); - VDataTool *getTool(const quint32 &id); - void AddTool(const quint32 &id, VDataTool *tool); + static VDataTool* getTool(quint32 id); + static void AddTool(quint32 id, VDataTool *tool); + static void RemoveTool(quint32 id); + + static VPiecePath ParsePieceNodes(const QDomElement &domElement); + static QVector<CustomSARecord> ParsePieceCSARecords(const QDomElement &domElement); + static QVector<quint32> ParsePieceInternalPaths(const QDomElement &domElement); void AddToolOnRemove(VDataTool *tool); @@ -195,6 +200,9 @@ public: static const QString TagShowDate; static const QString TagShowMeasurements; static const QString TagGrainline; + static const QString TagPath; + static const QString TagNodes; + static const QString TagNode; static const QString AttrName; static const QString AttrVisible; @@ -207,6 +215,15 @@ public: static const QString AttrCutNumber; static const QString AttrPlacement; static const QString AttrArrows; + static const QString AttrNodeReverse; + static const QString AttrSABefore; + static const QString AttrSAAfter; + static const QString AttrStart; + static const QString AttrPath; + static const QString AttrEnd; + static const QString AttrIncludeAs; + static const QString AttrWidth; + static const QString AttrRotation; static const QString AttrAll; @@ -264,6 +281,12 @@ public: static const QString IncrementFormula; static const QString IncrementDescription; + static const QString NodeArc; + static const QString NodeElArc; + static const QString NodePoint; + static const QString NodeSpline; + static const QString NodeSplinePath; + signals: /** * @brief ChangedActivPP change active pattern peace. @@ -320,9 +343,6 @@ protected: /** @brief cursor cursor keep id tool after which we will add new tool in file. */ quint32 cursor; - /** @brief tools list with pointer on tools. */ - QHash<quint32, VDataTool*> tools; - QVector<VDataTool*> toolsOnRemove; /** @brief history history records. */ @@ -334,7 +354,12 @@ protected: /** @brief modified keep state of the document for cases that do not cover QUndoStack*/ mutable bool modified; - void ToolExists(const quint32 &id) const; + /** @brief tools list with pointer on tools. */ + static QHash<quint32, VDataTool*> tools; + + static void ToolExists(const quint32 &id); + static VPiecePath ParsePathNodes(const QDomElement &domElement); + static VPieceNode ParseSANode(const QDomElement &domElement); void SetActivPP(const QString& name); @@ -343,7 +368,8 @@ protected: void SetChildTag(const QString& qsParent, const QString& qsChild, const QString& qsValue); - int GetIndexActivPP() const; + int GetIndexActivPP() const; + bool GetActivDrawElement(QDomElement &element) const; private: Q_DISABLE_COPY(VAbstractPattern) @@ -356,22 +382,17 @@ private: QStringList ListPathPointExpressions() const; QStringList ListIncrementExpressions() const; QStringList ListOperationExpressions() const; + QStringList ListNodesExpressions(const QDomElement &nodes) const; + QStringList ListPathExpressions() const; + QStringList ListGrainlineExpressions(const QDomElement &element) const; + QStringList ListPieceExpressions() const; bool IsVariable(const QString& token) const; bool IsPostfixOperator(const QString& token) const; bool IsFunction(const QString& token) const; QPair<bool, QMap<quint32, quint32> > ParseItemElement(const QDomElement &domElement); + }; -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief getTools return list of tools pointers. - * @return list. - */ -inline QHash<quint32, VDataTool *> *VAbstractPattern::getTools() -{ - return &tools; -} - #endif // VABSTRACTPATTERN_H diff --git a/src/libs/ifc/xml/vdomdocument.cpp b/src/libs/ifc/xml/vdomdocument.cpp index aff76405c..e5a590f11 100644 --- a/src/libs/ifc/xml/vdomdocument.cpp +++ b/src/libs/ifc/xml/vdomdocument.cpp @@ -203,7 +203,7 @@ bool VDomDocument::find(const QDomElement &node, const QString& id) * @param name attribute name * @return long long value */ -quint32 VDomDocument::GetParametrUInt(const QDomElement &domElement, const QString &name, const QString &defValue) const +quint32 VDomDocument::GetParametrUInt(const QDomElement &domElement, const QString &name, const QString &defValue) { Q_ASSERT_X(not name.isEmpty(), Q_FUNC_INFO, "name of parametr is empty"); Q_ASSERT_X(not domElement.isNull(), Q_FUNC_INFO, "domElement is null"); //-V591 @@ -212,7 +212,7 @@ quint32 VDomDocument::GetParametrUInt(const QDomElement &domElement, const QStri QString parametr; quint32 id = 0; - QString message = tr("Can't convert toUInt parameter"); + const QString message = QObject::tr("Can't convert toUInt parameter"); try { parametr = GetParametrString(domElement, name, defValue); @@ -233,7 +233,7 @@ quint32 VDomDocument::GetParametrUInt(const QDomElement &domElement, const QStri } //--------------------------------------------------------------------------------------------------------------------- -bool VDomDocument::GetParametrBool(const QDomElement &domElement, const QString &name, const QString &defValue) const +bool VDomDocument::GetParametrBool(const QDomElement &domElement, const QString &name, const QString &defValue) { Q_ASSERT_X(not name.isEmpty(), Q_FUNC_INFO, "name of parametr is empty"); Q_ASSERT_X(not domElement.isNull(), Q_FUNC_INFO, "domElement is null"); @@ -241,12 +241,15 @@ bool VDomDocument::GetParametrBool(const QDomElement &domElement, const QString QString parametr; bool val = true; - QString message = tr("Can't convert toBool parameter"); + const QString message = QObject::tr("Can't convert toBool parameter"); try { parametr = GetParametrString(domElement, name, defValue); - QStringList bools = QStringList() << QLatin1String("true") << QLatin1String("false"); + const QStringList bools = QStringList() << QLatin1String("true") + << QLatin1String("false") + << QLatin1String("1") + << QLatin1String("0"); switch (bools.indexOf(parametr)) { case 0: // true @@ -255,6 +258,12 @@ bool VDomDocument::GetParametrBool(const QDomElement &domElement, const QString case 1: // false val = false; break; + case 2: // 1 + val = true; + break; + case 3: // 0 + val = false; + break; default:// others throw VExceptionConversionError(message, name); break; @@ -271,7 +280,7 @@ bool VDomDocument::GetParametrBool(const QDomElement &domElement, const QString } //--------------------------------------------------------------------------------------------------------------------- -NodeUsage VDomDocument::GetParametrUsage(const QDomElement &domElement, const QString &name) const +NodeUsage VDomDocument::GetParametrUsage(const QDomElement &domElement, const QString &name) { const bool value = GetParametrBool(domElement, name, trueStr); if (value) @@ -306,7 +315,7 @@ void VDomDocument::SetParametrUsage(QDomElement &domElement, const QString &name * @throw VExceptionEmptyParameter when attribute is empty */ QString VDomDocument::GetParametrString(const QDomElement &domElement, const QString &name, - const QString &defValue) const + const QString &defValue) { Q_ASSERT_X(not name.isEmpty(), Q_FUNC_INFO, "name of parametr is empty"); Q_ASSERT_X(not domElement.isNull(), Q_FUNC_INFO, "domElement is null"); @@ -315,7 +324,7 @@ QString VDomDocument::GetParametrString(const QDomElement &domElement, const QSt { if (defValue.isEmpty()) { - throw VExceptionEmptyParameter(tr("Got empty parameter"), name, domElement); + throw VExceptionEmptyParameter(QObject::tr("Got empty parameter"), name, domElement); } else { @@ -332,7 +341,7 @@ QString VDomDocument::GetParametrString(const QDomElement &domElement, const QSt * @param name attribute name * @return double value */ -qreal VDomDocument::GetParametrDouble(const QDomElement &domElement, const QString &name, const QString &defValue) const +qreal VDomDocument::GetParametrDouble(const QDomElement &domElement, const QString &name, const QString &defValue) { Q_ASSERT_X(not name.isEmpty(), Q_FUNC_INFO, "name of parametr is empty"); Q_ASSERT_X(not domElement.isNull(), Q_FUNC_INFO, "domElement is null"); @@ -340,7 +349,7 @@ qreal VDomDocument::GetParametrDouble(const QDomElement &domElement, const QStri bool ok = false; qreal param = 0; - QString message = tr("Can't convert toDouble parameter"); + const QString message = QObject::tr("Can't convert toDouble parameter"); try { QString parametr = GetParametrString(domElement, name, defValue); @@ -365,13 +374,13 @@ qreal VDomDocument::GetParametrDouble(const QDomElement &domElement, const QStri * @param domElement tag in xml tree. * @return id value. */ -quint32 VDomDocument::GetParametrId(const QDomElement &domElement) const +quint32 VDomDocument::GetParametrId(const QDomElement &domElement) { Q_ASSERT_X(not domElement.isNull(), Q_FUNC_INFO, "domElement is null"); quint32 id = NULL_ID; - const QString message = tr("Got wrong parameter id. Need only id > 0."); + const QString message = QObject::tr("Got wrong parameter id. Need only id > 0."); try { id = GetParametrUInt(domElement, VDomDocument::AttrId, NULL_ID_STR); @@ -486,8 +495,9 @@ void VDomDocument::ValidateXML(const QString &schema, const QString &fileName) { pattern.close(); fileSchema.close(); - const QString errorMsg(tr("Could not load schema file '%1'.").arg(fileSchema.fileName())); - throw VException(errorMsg); + VException e(messageHandler.statusMessage()); + e.AddMoreInformation(tr("Could not load schema file '%1'.").arg(fileSchema.fileName())); + throw e; } qCDebug(vXML, "Schema loaded."); diff --git a/src/libs/ifc/xml/vdomdocument.h b/src/libs/ifc/xml/vdomdocument.h index 1d1ed589b..540be9aea 100644 --- a/src/libs/ifc/xml/vdomdocument.h +++ b/src/libs/ifc/xml/vdomdocument.h @@ -96,16 +96,16 @@ public: template <typename T> void SetAttribute(QDomElement &domElement, const QString &name, const T &value) const; - quint32 GetParametrUInt(const QDomElement& domElement, const QString &name, const QString &defValue) const; - bool GetParametrBool(const QDomElement& domElement, const QString &name, const QString &defValue) const; + static quint32 GetParametrUInt(const QDomElement& domElement, const QString &name, const QString &defValue); + static bool GetParametrBool(const QDomElement& domElement, const QString &name, const QString &defValue); - NodeUsage GetParametrUsage(const QDomElement& domElement, const QString &name) const; - void SetParametrUsage(QDomElement& domElement, const QString &name, const NodeUsage &value); + static NodeUsage GetParametrUsage(const QDomElement& domElement, const QString &name); + static void SetParametrUsage(QDomElement& domElement, const QString &name, const NodeUsage &value); - QString GetParametrString(const QDomElement& domElement, const QString &name, - const QString &defValue = QString()) const; - qreal GetParametrDouble(const QDomElement& domElement, const QString &name, const QString &defValue) const; - quint32 GetParametrId(const QDomElement& domElement) const; + static QString GetParametrString(const QDomElement& domElement, const QString &name, + const QString &defValue = QString()); + static qreal GetParametrDouble(const QDomElement& domElement, const QString &name, const QString &defValue); + static quint32 GetParametrId(const QDomElement& domElement); static void ValidateXML(const QString &schema, const QString &fileName); virtual void setXMLContent(const QString &fileName); diff --git a/src/libs/ifc/xml/vpatternconverter.cpp b/src/libs/ifc/xml/vpatternconverter.cpp index 189c90d53..ab86535da 100644 --- a/src/libs/ifc/xml/vpatternconverter.cpp +++ b/src/libs/ifc/xml/vpatternconverter.cpp @@ -58,63 +58,81 @@ class QDomElement; */ const QString VPatternConverter::PatternMinVerStr = QStringLiteral("0.1.0"); -const QString VPatternConverter::PatternMaxVerStr = QStringLiteral("0.3.9"); -const QString VPatternConverter::CurrentSchema = QStringLiteral("://schema/pattern/v0.3.9.xsd"); +const QString VPatternConverter::PatternMaxVerStr = QStringLiteral("0.4.0"); +const QString VPatternConverter::CurrentSchema = QStringLiteral("://schema/pattern/v0.4.0.xsd"); //VPatternConverter::PatternMinVer; // <== DON'T FORGET TO UPDATE TOO!!!! //VPatternConverter::PatternMaxVer; // <== DON'T FORGET TO UPDATE TOO!!!! // The list of all string we use for conversion // Better to use global variables because repeating QStringLiteral blows up code size -const QString strUnit = QStringLiteral("unit"); -const QString strVersion = QStringLiteral("version"); -const QString strName = QStringLiteral("name"); -const QString strBase = QStringLiteral("base"); -const QString strFormula = QStringLiteral("formula"); -const QString strId = QStringLiteral("id"); -const QString strKGrowth = QStringLiteral("kgrowth"); -const QString strKSize = QStringLiteral("ksize"); -const QString strPoint = QStringLiteral("point"); -const QString strLength = QStringLiteral("length"); -const QString strAngle = QStringLiteral("angle"); -const QString strC1Radius = QStringLiteral("c1Radius"); -const QString strC2Radius = QStringLiteral("c2Radius"); -const QString strCRadius = QStringLiteral("cRadius"); -const QString strArc = QStringLiteral("arc"); -const QString strAngle1 = QStringLiteral("angle1"); -const QString strAngle2 = QStringLiteral("angle2"); -const QString strRadius = QStringLiteral("radius"); -const QString strPathPoint = QStringLiteral("pathPoint"); -const QString strKAsm1 = QStringLiteral("kAsm1"); -const QString strKAsm2 = QStringLiteral("kAsm2"); -const QString strPath = QStringLiteral("path"); -const QString strType = QStringLiteral("type"); -const QString strCutArc = QStringLiteral("cutArc"); -const QString strSpline = QStringLiteral("spline"); -const QString strSplinePath = QStringLiteral("splinePath"); -const QString strCutSpline = QStringLiteral("cutSpline"); -const QString strCutSplinePath = QStringLiteral("cutSplinePath"); -const QString strColor = QStringLiteral("color"); -const QString strMeasurements = QStringLiteral("measurements"); -const QString strIncrement = QStringLiteral("increment"); -const QString strIncrements = QStringLiteral("increments"); -const QString strModeling = QStringLiteral("modeling"); -const QString strTools = QStringLiteral("tools"); -const QString strIdTool = QStringLiteral("idTool"); -const QString strIdObject = QStringLiteral("idObject"); -const QString strChildren = QStringLiteral("children"); -const QString strChild = QStringLiteral("child"); -const QString strPointOfIntersectionCurves = QStringLiteral("pointOfIntersectionCurves"); -const QString strCurveIntersectAxis = QStringLiteral("curveIntersectAxis"); -const QString strCurve = QStringLiteral("curve"); -const QString strCurve1 = QStringLiteral("curve1"); -const QString strCurve2 = QStringLiteral("curve2"); -const QString strModelingPath = QStringLiteral("modelingPath"); -const QString strModelingSpline = QStringLiteral("modelingSpline"); -const QString strPointFromArcAndTangent = QStringLiteral("pointFromArcAndTangent"); -const QString strPointOfIntersectionArcs = QStringLiteral("pointOfIntersectionArcs"); -const QString strFirstArc = QStringLiteral("firstArc"); -const QString strSecondArc = QStringLiteral("secondArc"); +static const QString strUnit = QStringLiteral("unit"); +static const QString strVersion = QStringLiteral("version"); +static const QString strName = QStringLiteral("name"); +static const QString strBase = QStringLiteral("base"); +static const QString strFormula = QStringLiteral("formula"); +static const QString strId = QStringLiteral("id"); +static const QString strKGrowth = QStringLiteral("kgrowth"); +static const QString strKSize = QStringLiteral("ksize"); +static const QString strPoint = QStringLiteral("point"); +static const QString strLength = QStringLiteral("length"); +static const QString strAngle = QStringLiteral("angle"); +static const QString strC1Radius = QStringLiteral("c1Radius"); +static const QString strC2Radius = QStringLiteral("c2Radius"); +static const QString strCRadius = QStringLiteral("cRadius"); +static const QString strArc = QStringLiteral("arc"); +static const QString strAngle1 = QStringLiteral("angle1"); +static const QString strAngle2 = QStringLiteral("angle2"); +static const QString strRadius = QStringLiteral("radius"); +static const QString strPathPoint = QStringLiteral("pathPoint"); +static const QString strKAsm1 = QStringLiteral("kAsm1"); +static const QString strKAsm2 = QStringLiteral("kAsm2"); +static const QString strPath = QStringLiteral("path"); +static const QString strType = QStringLiteral("type"); +static const QString strCutArc = QStringLiteral("cutArc"); +static const QString strSpline = QStringLiteral("spline"); +static const QString strSplinePath = QStringLiteral("splinePath"); +static const QString strCutSpline = QStringLiteral("cutSpline"); +static const QString strCutSplinePath = QStringLiteral("cutSplinePath"); +static const QString strColor = QStringLiteral("color"); +static const QString strMeasurements = QStringLiteral("measurements"); +static const QString strIncrement = QStringLiteral("increment"); +static const QString strIncrements = QStringLiteral("increments"); +static const QString strModeling = QStringLiteral("modeling"); +static const QString strTools = QStringLiteral("tools"); +static const QString strIdTool = QStringLiteral("idTool"); +static const QString strIdObject = QStringLiteral("idObject"); +static const QString strChildren = QStringLiteral("children"); +static const QString strChild = QStringLiteral("child"); +static const QString strPointOfIntersectionCurves = QStringLiteral("pointOfIntersectionCurves"); +static const QString strCurveIntersectAxis = QStringLiteral("curveIntersectAxis"); +static const QString strCurve = QStringLiteral("curve"); +static const QString strCurve1 = QStringLiteral("curve1"); +static const QString strCurve2 = QStringLiteral("curve2"); +static const QString strModelingPath = QStringLiteral("modelingPath"); +static const QString strModelingSpline = QStringLiteral("modelingSpline"); +static const QString strPointFromArcAndTangent = QStringLiteral("pointFromArcAndTangent"); +static const QString strPointOfIntersectionArcs = QStringLiteral("pointOfIntersectionArcs"); +static const QString strFirstArc = QStringLiteral("firstArc"); +static const QString strSecondArc = QStringLiteral("secondArc"); +static const QString strDetail = QStringLiteral("detail"); +static const QString strSupplement = QStringLiteral("supplement"); +static const QString strClosed = QStringLiteral("closed"); +static const QString strWidth = QStringLiteral("width"); +static const QString strNode = QStringLiteral("node"); +static const QString strNodes = QStringLiteral("nodes"); +static const QString strData = QStringLiteral("data"); +static const QString strPatternInfo = QStringLiteral("patternInfo"); +static const QString strGrainline = QStringLiteral("grainline"); +static const QString strReverse = QStringLiteral("reverse"); +static const QString strMx = QStringLiteral("mx"); +static const QString strMy = QStringLiteral("my"); +static const QString strForbidFlipping = QStringLiteral("forbidFlipping"); +static const QString strInLayout = QStringLiteral("inLayout"); +static const QString strSeamAllowance = QStringLiteral("seamAllowance"); +static const QString strNodeType = QStringLiteral("nodeType"); +static const QString strDet = QStringLiteral("det"); +static const QString strTypeObject = QStringLiteral("typeObject"); //--------------------------------------------------------------------------------------------------------------------- VPatternConverter::VPatternConverter(const QString &fileName) @@ -177,6 +195,8 @@ QString VPatternConverter::XSDSchema(int ver) const case (0x000308): return QStringLiteral("://schema/pattern/v0.3.8.xsd"); case (0x000309): + return QStringLiteral("://schema/pattern/v0.3.9.xsd"); + case (0x000400): return CurrentSchema; default: InvalidVersion(ver); @@ -280,6 +300,9 @@ void VPatternConverter::ApplyPatches() ValidateXML(XSDSchema(0x000309), fileName); V_FALLTHROUGH case (0x000309): + ToV0_4_0(); + ValidateXML(XSDSchema(0x000400), fileName); + case (0x000400): break; default: break; @@ -314,6 +337,10 @@ void VPatternConverter::DowngradeToCurrentMaxVersion() //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::ToV0_1_1() { + // TODO. Delete if minimal supported version is 0.1.1 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 1, 1), + "Time to refactor the code."); + SetVersion(QStringLiteral("0.1.1")); Save(); } @@ -321,6 +348,10 @@ void VPatternConverter::ToV0_1_1() //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::ToV0_1_2() { + // TODO. Delete if minimal supported version is 0.1.2 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 1, 2), + "Time to refactor the code."); + SetVersion(QStringLiteral("0.1.2")); Save(); } @@ -328,6 +359,10 @@ void VPatternConverter::ToV0_1_2() //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::ToV0_1_3() { + // TODO. Delete if minimal supported version is 0.1.3 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 1, 3), + "Time to refactor the code."); + SetVersion(QStringLiteral("0.1.3")); Save(); } @@ -335,6 +370,10 @@ void VPatternConverter::ToV0_1_3() //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::ToV0_1_4() { + // TODO. Delete if minimal supported version is 0.1.4 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 1, 4), + "Time to refactor the code."); + SetVersion(QStringLiteral("0.1.4")); Save(); } @@ -342,6 +381,10 @@ void VPatternConverter::ToV0_1_4() //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::ToV0_2_0() { + // TODO. Delete if minimal supported version is 0.2.0 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 2, 0), + "Time to refactor the code."); + SetVersion(QStringLiteral("0.2.0")); TagUnitToV0_2_0(); TagIncrementToV0_2_0(); @@ -353,6 +396,10 @@ void VPatternConverter::ToV0_2_0() //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::ToV0_2_1() { + // TODO. Delete if minimal supported version is 0.2.1 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 2, 1), + "Time to refactor the code."); + SetVersion(QStringLiteral("0.2.1")); ConvertMeasurementsToV0_2_1(); Save(); @@ -361,6 +408,10 @@ void VPatternConverter::ToV0_2_1() //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::ToV0_2_2() { + // TODO. Delete if minimal supported version is 0.2.2 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 2, 2), + "Time to refactor the code."); + SetVersion(QStringLiteral("0.2.2")); Save(); } @@ -368,6 +419,10 @@ void VPatternConverter::ToV0_2_2() //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::ToV0_2_3() { + // TODO. Delete if minimal supported version is 0.2.3 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 2, 3), + "Time to refactor the code."); + SetVersion(QStringLiteral("0.2.3")); Save(); } @@ -375,6 +430,10 @@ void VPatternConverter::ToV0_2_3() //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::ToV0_2_4() { + // TODO. Delete if minimal supported version is 0.2.4 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 2, 4), + "Time to refactor the code."); + FixToolUnionToV0_2_4(); SetVersion(QStringLiteral("0.2.4")); Save(); @@ -383,6 +442,10 @@ void VPatternConverter::ToV0_2_4() //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::ToV0_2_5() { + // TODO. Delete if minimal supported version is 0.2.5 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 2, 5), + "Time to refactor the code."); + SetVersion(QStringLiteral("0.2.5")); Save(); } @@ -390,6 +453,10 @@ void VPatternConverter::ToV0_2_5() //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::ToV0_2_6() { + // TODO. Delete if minimal supported version is 0.2.6 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 2, 6), + "Time to refactor the code."); + SetVersion(QStringLiteral("0.2.6")); Save(); } @@ -397,6 +464,10 @@ void VPatternConverter::ToV0_2_6() //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::ToV0_2_7() { + // TODO. Delete if minimal supported version is 0.2.7 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 2, 7), + "Time to refactor the code."); + SetVersion(QStringLiteral("0.2.7")); Save(); } @@ -404,6 +475,10 @@ void VPatternConverter::ToV0_2_7() //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::ToV0_3_0() { + // TODO. Delete if minimal supported version is 0.3.0 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 3, 0), + "Time to refactor the code."); + //Cutting path do not create anymore subpaths FixCutPoint(); FixCutPoint(); @@ -414,6 +489,10 @@ void VPatternConverter::ToV0_3_0() //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::ToV0_3_1() { + // TODO. Delete if minimal supported version is 0.3.1 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 3, 1), + "Time to refactor the code."); + SetVersion(QStringLiteral("0.3.1")); RemoveColorToolCutV0_3_1(); Save(); @@ -422,6 +501,10 @@ void VPatternConverter::ToV0_3_1() //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::ToV0_3_2() { + // TODO. Delete if minimal supported version is 0.3.2 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 3, 2), + "Time to refactor the code."); + SetVersion(QStringLiteral("0.3.2")); Save(); } @@ -429,6 +512,10 @@ void VPatternConverter::ToV0_3_2() //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::ToV0_3_3() { + // TODO. Delete if minimal supported version is 0.3.3 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 3, 3), + "Time to refactor the code."); + SetVersion(QStringLiteral("0.3.3")); Save(); } @@ -436,6 +523,10 @@ void VPatternConverter::ToV0_3_3() //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::ToV0_3_4() { + // TODO. Delete if minimal supported version is 0.3.4 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 3, 4), + "Time to refactor the code."); + SetVersion(QStringLiteral("0.3.4")); Save(); } @@ -443,6 +534,10 @@ void VPatternConverter::ToV0_3_4() //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::ToV0_3_5() { + // TODO. Delete if minimal supported version is 0.3.5 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 3, 5), + "Time to refactor the code."); + SetVersion(QStringLiteral("0.3.5")); Save(); } @@ -450,6 +545,10 @@ void VPatternConverter::ToV0_3_5() //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::ToV0_3_6() { + // TODO. Delete if minimal supported version is 0.3.6 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 3, 6), + "Time to refactor the code."); + SetVersion(QStringLiteral("0.3.6")); Save(); } @@ -457,6 +556,10 @@ void VPatternConverter::ToV0_3_6() //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::ToV0_3_7() { + // TODO. Delete if minimal supported version is 0.3.7 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 3, 7), + "Time to refactor the code."); + SetVersion(QStringLiteral("0.3.7")); Save(); } @@ -464,6 +567,10 @@ void VPatternConverter::ToV0_3_7() //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::ToV0_3_8() { + // TODO. Delete if minimal supported version is 0.3.8 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 3, 8), + "Time to refactor the code."); + SetVersion(QStringLiteral("0.3.8")); Save(); } @@ -475,9 +582,27 @@ void VPatternConverter::ToV0_3_9() Save(); } +//--------------------------------------------------------------------------------------------------------------------- +void VPatternConverter::ToV0_4_0() +{ + // TODO. Delete if minimal supported version is 0.4.0 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 4, 0), + "Time to refactor the code."); + + SetVersion(QStringLiteral("0.4.0")); + TagRemoveAttributeTypeObjectInV0_4_0(); + TagDetailToV0_4_0(); + TagUnionDetailsToV0_4_0(); + Save(); +} + //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::TagUnitToV0_2_0() { + // TODO. Delete if minimal supported version is 0.2.0 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 2, 0), + "Time to refactor the code."); + QDomElement unit = createElement(strUnit); QDomText newNodeText = createTextNode(MUnitV0_1_4()); unit.appendChild(newNodeText); @@ -489,6 +614,10 @@ void VPatternConverter::TagUnitToV0_2_0() //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::TagIncrementToV0_2_0() { + // TODO. Delete if minimal supported version is 0.2.0 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 2, 0), + "Time to refactor the code."); + const QSet<QString> names = FixIncrementsToV0_2_0(); FixPointExpressionsToV0_2_0(names); @@ -499,6 +628,10 @@ void VPatternConverter::TagIncrementToV0_2_0() //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::ConvertMeasurementsToV0_2_0() { + // TODO. Delete if minimal supported version is 0.2.0 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 2, 0), + "Time to refactor the code."); + const QMap<QString, QString> names = OldNamesToNewNames_InV0_2_0(); ConvertPointExpressionsToV0_2_0(names); ConvertArcExpressionsToV0_2_0(names); @@ -508,6 +641,10 @@ void VPatternConverter::ConvertMeasurementsToV0_2_0() //--------------------------------------------------------------------------------------------------------------------- QSet<QString> VPatternConverter::FixIncrementsToV0_2_0() { + // TODO. Delete if minimal supported version is 0.2.0 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 2, 0), + "Time to refactor the code."); + QSet<QString> names; const QDomElement incr = TagIncrementsV0_1_4(); QDomNode domNode = incr.firstChild(); @@ -550,6 +687,10 @@ QSet<QString> VPatternConverter::FixIncrementsToV0_2_0() //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::FixPointExpressionsToV0_2_0(const QSet<QString> &names) { + // TODO. Delete if minimal supported version is 0.2.0 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 2, 0), + "Time to refactor the code."); + QString formula; const QDomNodeList list = elementsByTagName(strPoint); for (int i=0; i < list.size(); ++i) @@ -610,6 +751,10 @@ void VPatternConverter::FixPointExpressionsToV0_2_0(const QSet<QString> &names) //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::FixArcExpressionsToV0_2_0(const QSet<QString> &names) { + // TODO. Delete if minimal supported version is 0.2.0 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 2, 0), + "Time to refactor the code."); + QString formula; const QDomNodeList list = elementsByTagName(strArc); for (int i=0; i < list.size(); ++i) @@ -661,6 +806,10 @@ void VPatternConverter::FixArcExpressionsToV0_2_0(const QSet<QString> &names) //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::FixPathPointExpressionsToV0_2_0(const QSet<QString> &names) { + // TODO. Delete if minimal supported version is 0.2.0 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 2, 0), + "Time to refactor the code."); + QString formula; const QDomNodeList list = elementsByTagName(strPathPoint); for (int i=0; i < list.size(); ++i) @@ -702,6 +851,10 @@ void VPatternConverter::FixPathPointExpressionsToV0_2_0(const QSet<QString> &nam //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::ConvertPointExpressionsToV0_2_0(const QMap<QString, QString> &names) { + // TODO. Delete if minimal supported version is 0.2.0 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 2, 0), + "Time to refactor the code."); + QString formula; const QDomNodeList list = elementsByTagName(strPoint); for (int i=0; i < list.size(); ++i) @@ -762,6 +915,10 @@ void VPatternConverter::ConvertPointExpressionsToV0_2_0(const QMap<QString, QStr //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::ConvertArcExpressionsToV0_2_0(const QMap<QString, QString> &names) { + // TODO. Delete if minimal supported version is 0.2.0 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 2, 0), + "Time to refactor the code."); + QString formula; const QDomNodeList list = elementsByTagName(strArc); for (int i=0; i < list.size(); ++i) @@ -813,6 +970,10 @@ void VPatternConverter::ConvertArcExpressionsToV0_2_0(const QMap<QString, QStrin //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::ConvertPathPointExpressionsToV0_2_0(const QMap<QString, QString> &names) { + // TODO. Delete if minimal supported version is 0.2.0 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 2, 0), + "Time to refactor the code."); + QString formula; const QDomNodeList list = elementsByTagName(strPathPoint); for (int i=0; i < list.size(); ++i) @@ -854,6 +1015,10 @@ void VPatternConverter::ConvertPathPointExpressionsToV0_2_0(const QMap<QString, //--------------------------------------------------------------------------------------------------------------------- QString VPatternConverter::FixMeasurementInFormulaToV0_2_0(const QString &formula, const QMap<QString, QString> &names) { + // TODO. Delete if minimal supported version is 0.2.0 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 2, 0), + "Time to refactor the code."); + QScopedPointer<qmu::QmuTokenParser> cal(new qmu::QmuTokenParser(formula, false, false));// Eval formula QMap<int, QString> tokens = cal->GetTokens();// Tokens (variables, measurements) delete cal.take(); @@ -884,6 +1049,10 @@ QString VPatternConverter::FixMeasurementInFormulaToV0_2_0(const QString &formul //--------------------------------------------------------------------------------------------------------------------- QString VPatternConverter::FixIncrementInFormulaToV0_2_0(const QString &formula, const QSet<QString> &names) { + // TODO. Delete if minimal supported version is 0.2.0 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 2, 0), + "Time to refactor the code."); + qmu::QmuTokenParser *cal = new qmu::QmuTokenParser(formula, false, false);// Eval formula QMap<int, QString> tokens = cal->GetTokens();// Tokens (variables, measurements) delete cal; @@ -914,6 +1083,10 @@ QString VPatternConverter::FixIncrementInFormulaToV0_2_0(const QString &formula, //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::TagMeasurementsToV0_2_0() { + // TODO. Delete if minimal supported version is 0.2.0 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 2, 0), + "Time to refactor the code."); + QDomElement ms = TagMeasurementsV0_1_4(); const QString path = GetParametrString(ms, strPath); @@ -928,6 +1101,10 @@ void VPatternConverter::TagMeasurementsToV0_2_0() //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::ConvertMeasurementsToV0_2_1() { + // TODO. Delete if minimal supported version is 0.2.1 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 2, 1), + "Time to refactor the code."); + const QMap<QString, QString> names = OldNamesToNewNames_InV0_2_1(); // Structure did not change. We can use the same code. @@ -939,6 +1116,10 @@ void VPatternConverter::ConvertMeasurementsToV0_2_1() //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::RemoveColorToolCutV0_3_1() { + // TODO. Delete if minimal supported version is 0.3.1 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 3, 1), + "Time to refactor the code."); + const QDomNodeList list = elementsByTagName(strPoint); for (int i=0; i < list.size(); ++i) { @@ -957,6 +1138,10 @@ void VPatternConverter::RemoveColorToolCutV0_3_1() //--------------------------------------------------------------------------------------------------------------------- QString VPatternConverter::MUnitV0_1_4() const { + // TODO. Delete if minimal supported version is 0.1.4 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 1, 4), + "Time to refactor the code."); + const QDomElement element = TagMeasurementsV0_1_4(); try { @@ -973,6 +1158,10 @@ QString VPatternConverter::MUnitV0_1_4() const //--------------------------------------------------------------------------------------------------------------------- QDomElement VPatternConverter::TagMeasurementsV0_1_4() const { + // TODO. Delete if minimal supported version is 0.1.4 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 1, 4), + "Time to refactor the code."); + const QDomNodeList list = elementsByTagName(strMeasurements); const QDomElement element = list.at(0).toElement(); if (not element.isElement()) @@ -986,6 +1175,10 @@ QDomElement VPatternConverter::TagMeasurementsV0_1_4() const //--------------------------------------------------------------------------------------------------------------------- QDomElement VPatternConverter::TagIncrementsV0_1_4() const { + // TODO. Delete if minimal supported version is 0.1.4 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 1, 4), + "Time to refactor the code."); + const QDomNodeList list = elementsByTagName(strIncrements); const QDomElement element = list.at(0).toElement(); if (not element.isElement()) @@ -999,6 +1192,10 @@ QDomElement VPatternConverter::TagIncrementsV0_1_4() const //--------------------------------------------------------------------------------------------------------------------- QStringList VPatternConverter::ListPathPointExpressionsV0_1_4() const { + // TODO. Delete if minimal supported version is 0.1.4 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 1, 4), + "Time to refactor the code."); + QStringList expressions; const QDomNodeList list = elementsByTagName(strPathPoint); for (int i=0; i < list.size(); ++i) @@ -1039,6 +1236,10 @@ QStringList VPatternConverter::ListPathPointExpressionsV0_1_4() const //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::FixToolUnionToV0_2_4() { + // TODO. Delete if minimal supported version is 0.2.4 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 2, 4), + "Time to refactor the code."); + QDomElement root = documentElement(); const QDomNodeList modelings = root.elementsByTagName(strModeling); for (int i=0; i<modelings.size(); ++i) @@ -1050,6 +1251,10 @@ void VPatternConverter::FixToolUnionToV0_2_4() //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::ParseModelingToV0_2_4(const QDomElement &modeling) { + // TODO. Delete if minimal supported version is 0.2.4 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 2, 4), + "Time to refactor the code."); + QDomElement node = modeling.firstChild().toElement(); while (not node.isNull()) { @@ -1085,6 +1290,10 @@ void VPatternConverter::ParseModelingToV0_2_4(const QDomElement &modeling) //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::SaveChildrenToolUnionToV0_2_4(quint32 id, const QVector<quint32> &children) { + // TODO. Delete if minimal supported version is 0.2.4 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 2, 4), + "Time to refactor the code."); + QDomElement toolUnion = elementById(id); if (toolUnion.isNull()) { @@ -1106,6 +1315,10 @@ void VPatternConverter::SaveChildrenToolUnionToV0_2_4(quint32 id, const QVector< //--------------------------------------------------------------------------------------------------------------------- QMap<QString, QString> VPatternConverter::OldNamesToNewNames_InV0_2_0() { + // TODO. Delete if minimal supported version is 0.2.0 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 2, 0), + "Time to refactor the code."); + // old name, new name QMap<QString, QString> names; @@ -1282,6 +1495,10 @@ QMap<QString, QString> VPatternConverter::OldNamesToNewNames_InV0_2_0() //--------------------------------------------------------------------------------------------------------------------- QMap<QString, QString> VPatternConverter::OldNamesToNewNames_InV0_2_1() { + // TODO. Delete if minimal supported version is 0.2.1 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 2, 1), + "Time to refactor the code."); + // old name, new name QMap<QString, QString> names; @@ -1480,3 +1697,225 @@ void VPatternConverter::FixSubPaths(int i, quint32 id, quint32 baseCurve) } } } + +//--------------------------------------------------------------------------------------------------------------------- +void VPatternConverter::TagRemoveAttributeTypeObjectInV0_4_0() +{ + // TODO. Delete if minimal supported version is 0.4.0 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 4, 0), + "Time to refactor the code."); + + const QDomNodeList list = elementsByTagName(strModeling); + for (int i = 0; i < list.size(); ++i) + { + QDomElement modeling = list.at(i).toElement(); + if (not modeling.isNull()) + { + QDomNode domNode = modeling.firstChild(); + while (not domNode.isNull()) + { + QDomElement domElement = domNode.toElement(); + if (not domElement.isNull()) + { + if (domElement.hasAttribute(strTypeObject)) + { + domElement.removeAttribute(strTypeObject); + } + } + domNode = domNode.nextSibling(); + } + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPatternConverter::TagDetailToV0_4_0() +{ + // TODO. Delete if minimal supported version is 0.4.0 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 4, 0), + "Time to refactor the code."); + + const QDomNodeList list = elementsByTagName(strDetail); + for (int i=0; i < list.size(); ++i) + { + QDomElement dom = list.at(i).toElement(); + + if (not dom.isNull()) + { + dom.setAttribute(strSeamAllowance, dom.attribute(strSupplement, "0")); + dom.removeAttribute(strSupplement); + + dom.setAttribute(strVersion, "1"); + + const QStringList tags = QStringList() << strNode << strData << strPatternInfo << strGrainline; + + QDomElement tagData; + QDomElement tagPatternInfo; + QDomElement tagGrainline; + QDomElement tagNodes = createElement(strNodes); + + const QDomNodeList childList = dom.childNodes(); + for (qint32 i = 0; i < childList.size(); ++i) + { + const QDomElement element = childList.at(i).toElement(); + if (not element.isNull()) + { + switch (tags.indexOf(element.tagName())) + { + case 0://strNode + { + QDomElement tagNode = createElement(strNode); + + tagNode.setAttribute(strIdObject, element.attribute(strIdObject, NULL_ID_STR)); + + if (element.hasAttribute(strReverse)) + { + tagNode.setAttribute(strReverse, element.attribute(strReverse, "0")); + } + + if (element.hasAttribute(strMx)) + { + tagNode.setAttribute(strMx, element.attribute(strMx, "0")); + } + + if (element.hasAttribute(strMy)) + { + tagNode.setAttribute(strMy, element.attribute(strMy, "0")); + } + + tagNode.setAttribute(strType, element.attribute(strType, "")); + + tagNodes.appendChild(tagNode); + + break; + } + case 1://strData + tagData = element.cloneNode().toElement(); + break; + case 2://strPatternInfo + tagPatternInfo = element.cloneNode().toElement(); + break; + case 3://strGrainline + tagGrainline = element.cloneNode().toElement(); + break; + default: + break; + } + } + } + + RemoveAllChildren(dom); + + dom.appendChild(tagData); + dom.appendChild(tagPatternInfo); + dom.appendChild(tagGrainline); + dom.appendChild(tagNodes); + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +QDomElement VPatternConverter::GetUnionDetailNodesV0_4_0(const QDomElement &detail) +{ + QDomElement tagNodes = createElement(strNodes); + + if (not detail.isNull()) + { + const QDomNodeList childList = detail.childNodes(); + for (qint32 i = 0; i < childList.size(); ++i) + { + const QDomElement node = childList.at(i).toElement(); + if (not node.isNull()) + { + QDomElement tagNode = createElement(strNode); + + tagNode.setAttribute(strIdObject, node.attribute(strIdObject, NULL_ID_STR)); + + if (node.hasAttribute(strReverse)) + { + tagNode.setAttribute(strReverse, node.attribute(strReverse, "0")); + } + + tagNode.setAttribute(strType, node.attribute(strType, "")); + + tagNodes.appendChild(tagNode); + } + } + } + + return tagNodes; +} + +//--------------------------------------------------------------------------------------------------------------------- +QDomElement VPatternConverter::GetUnionChildrenNodesV0_4_0(const QDomElement &detail) +{ + QDomElement tagNodes = createElement(strNodes); + + if (not detail.isNull()) + { + const QDomNodeList childList = detail.childNodes(); + for (qint32 i = 0; i < childList.size(); ++i) + { + const QDomElement node = childList.at(i).toElement(); + if (not node.isNull()) + { + QDomElement tagNode = node.cloneNode().toElement(); + tagNodes.appendChild(tagNode); + } + } + } + + return tagNodes; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPatternConverter::TagUnionDetailsToV0_4_0() +{ + // TODO. Delete if minimal supported version is 0.4.0 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 4, 0), + "Time to refactor the code."); + + const QDomNodeList list = elementsByTagName(strTools); + for (int i=0; i < list.size(); ++i) + { + // Tag 'tools' used only for union details, so no need to check any additional attributes + QDomElement toolDOM = list.at(i).toElement(); + if (not toolDOM.isNull()) + { + const QStringList tags = QStringList() << strDet << strChildren; + + QVector<QDomElement> nodes; + QDomElement tagChildrenNodes = createElement(strChildren); + + const QDomNodeList childList = toolDOM.childNodes(); + for (qint32 i = 0; i < childList.size(); ++i) + { + const QDomElement element = childList.at(i).toElement(); + if (not element.isNull()) + { + switch (tags.indexOf(element.tagName())) + { + case 0://strDet + nodes.append(GetUnionDetailNodesV0_4_0(element)); + break; + case 1://strChildren + tagChildrenNodes.appendChild(GetUnionChildrenNodesV0_4_0(element)); + break; + default: + break; + } + } + } + + RemoveAllChildren(toolDOM); + + for (int i = 0; i < nodes.size(); ++i) + { + QDomElement tagDet = createElement(strDet); + tagDet.appendChild(nodes.at(i)); + toolDOM.appendChild(tagDet); + } + toolDOM.appendChild(tagChildrenNodes); + } + } +} diff --git a/src/libs/ifc/xml/vpatternconverter.h b/src/libs/ifc/xml/vpatternconverter.h index 2a3676c25..3341fecaf 100644 --- a/src/libs/ifc/xml/vpatternconverter.h +++ b/src/libs/ifc/xml/vpatternconverter.h @@ -55,10 +55,10 @@ public: // GCC 4.6 doesn't allow constexpr and const together #if !defined(__INTEL_COMPILER) && !defined(__clang__) && defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) <= 406 static Q_DECL_CONSTEXPR int PatternMinVer = CONVERTER_VERSION_CHECK(0, 1, 0); - static Q_DECL_CONSTEXPR int PatternMaxVer = CONVERTER_VERSION_CHECK(0, 3, 9); + static Q_DECL_CONSTEXPR int PatternMaxVer = CONVERTER_VERSION_CHECK(0, 4, 0); #else static Q_DECL_CONSTEXPR const int PatternMinVer = CONVERTER_VERSION_CHECK(0, 1, 0); - static Q_DECL_CONSTEXPR const int PatternMaxVer = CONVERTER_VERSION_CHECK(0, 3, 9); + static Q_DECL_CONSTEXPR const int PatternMaxVer = CONVERTER_VERSION_CHECK(0, 4, 0); #endif protected: @@ -98,6 +98,7 @@ private: void ToV0_3_7(); void ToV0_3_8(); void ToV0_3_9(); + void ToV0_4_0(); void TagUnitToV0_2_0(); void TagIncrementToV0_2_0(); @@ -133,6 +134,12 @@ private: void FixCutPoint(); void FixSubPaths(int i, quint32 id, quint32 baseCurve); + + void TagRemoveAttributeTypeObjectInV0_4_0(); + void TagDetailToV0_4_0(); + void TagUnionDetailsToV0_4_0(); + QDomElement GetUnionDetailNodesV0_4_0(const QDomElement &detail); + QDomElement GetUnionChildrenNodesV0_4_0(const QDomElement &detail); }; //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/ifc/xml/vvitconverter.cpp b/src/libs/ifc/xml/vvitconverter.cpp index bb5c857c9..49c7a397d 100644 --- a/src/libs/ifc/xml/vvitconverter.cpp +++ b/src/libs/ifc/xml/vvitconverter.cpp @@ -150,6 +150,10 @@ void VVITConverter::DowngradeToCurrentMaxVersion() //--------------------------------------------------------------------------------------------------------------------- void VVITConverter::AddNewTagsForV0_3_0() { + // TODO. Delete if minimal supported version is 0.3.0 + Q_STATIC_ASSERT_X(VVITConverter::MeasurementMinVer < CONVERTER_VERSION_CHECK(0, 3, 0), + "Time to refactor the code."); + QDomElement rootElement = this->documentElement(); QDomNode refChild = rootElement.firstChildElement("version"); @@ -168,12 +172,20 @@ void VVITConverter::AddNewTagsForV0_3_0() //--------------------------------------------------------------------------------------------------------------------- QString VVITConverter::MUnitV0_2_0() { + // TODO. Delete if minimal supported version is 0.3.0 + Q_STATIC_ASSERT_X(VVITConverter::MeasurementMinVer < CONVERTER_VERSION_CHECK(0, 3, 0), + "Time to refactor the code."); + return UniqueTagText(QStringLiteral("unit"), QStringLiteral("cm")); } //--------------------------------------------------------------------------------------------------------------------- void VVITConverter::ConvertMeasurementsToV0_3_0() { + // TODO. Delete if minimal supported version is 0.3.0 + Q_STATIC_ASSERT_X(VVITConverter::MeasurementMinVer < CONVERTER_VERSION_CHECK(0, 3, 0), + "Time to refactor the code."); + const QString tagBM = QStringLiteral("body-measurements"); QDomElement bm = createElement(tagBM); @@ -213,6 +225,10 @@ void VVITConverter::ConvertMeasurementsToV0_3_0() //--------------------------------------------------------------------------------------------------------------------- QDomElement VVITConverter::AddMV0_3_0(const QString &name, qreal value) { + // TODO. Delete if minimal supported version is 0.3.0 + Q_STATIC_ASSERT_X(VVITConverter::MeasurementMinVer < CONVERTER_VERSION_CHECK(0, 3, 0), + "Time to refactor the code."); + QDomElement element = createElement(QStringLiteral("m")); SetAttribute(element, QStringLiteral("name"), name); @@ -226,6 +242,10 @@ QDomElement VVITConverter::AddMV0_3_0(const QString &name, qreal value) //--------------------------------------------------------------------------------------------------------------------- void VVITConverter::GenderV0_3_1() { + // TODO. Delete if minimal supported version is 0.3.1 + Q_STATIC_ASSERT_X(VVITConverter::MeasurementMinVer < CONVERTER_VERSION_CHECK(0, 3, 1), + "Time to refactor the code."); + const QDomNodeList nodeList = this->elementsByTagName(QStringLiteral("sex")); QDomElement sex = nodeList.at(0).toElement(); @@ -239,6 +259,10 @@ void VVITConverter::GenderV0_3_1() //--------------------------------------------------------------------------------------------------------------------- void VVITConverter::PM_SystemV0_3_2() { + // TODO. Delete if minimal supported version is 0.3.2 + Q_STATIC_ASSERT_X(VVITConverter::MeasurementMinVer < CONVERTER_VERSION_CHECK(0, 3, 2), + "Time to refactor the code."); + QDomElement pm_system = createElement(QStringLiteral("pm_system")); pm_system.appendChild(createTextNode(QStringLiteral("998"))); @@ -252,6 +276,10 @@ void VVITConverter::PM_SystemV0_3_2() //--------------------------------------------------------------------------------------------------------------------- void VVITConverter::ConvertMeasurementsToV0_3_3() { + // TODO. Delete if minimal supported version is 0.3.3 + Q_STATIC_ASSERT_X(VVITConverter::MeasurementMinVer < CONVERTER_VERSION_CHECK(0, 3, 3), + "Time to refactor the code."); + const QMap<QString, QString> names = OldNamesToNewNames_InV0_3_3(); auto i = names.constBegin(); while (i != names.constEnd()) @@ -281,6 +309,10 @@ void VVITConverter::ConvertMeasurementsToV0_3_3() //--------------------------------------------------------------------------------------------------------------------- void VVITConverter::ToV0_3_0() { + // TODO. Delete if minimal supported version is 0.3.0 + Q_STATIC_ASSERT_X(VVITConverter::MeasurementMinVer < CONVERTER_VERSION_CHECK(0, 3, 0), + "Time to refactor the code."); + AddRootComment(); SetVersion(QStringLiteral("0.3.0")); AddNewTagsForV0_3_0(); @@ -291,6 +323,10 @@ void VVITConverter::ToV0_3_0() //--------------------------------------------------------------------------------------------------------------------- void VVITConverter::ToV0_3_1() { + // TODO. Delete if minimal supported version is 0.3.1 + Q_STATIC_ASSERT_X(VVITConverter::MeasurementMinVer < CONVERTER_VERSION_CHECK(0, 3, 1), + "Time to refactor the code."); + SetVersion(QStringLiteral("0.3.1")); GenderV0_3_1(); Save(); @@ -299,6 +335,10 @@ void VVITConverter::ToV0_3_1() //--------------------------------------------------------------------------------------------------------------------- void VVITConverter::ToV0_3_2() { + // TODO. Delete if minimal supported version is 0.3.2 + Q_STATIC_ASSERT_X(VVITConverter::MeasurementMinVer < CONVERTER_VERSION_CHECK(0, 3, 2), + "Time to refactor the code."); + SetVersion(QStringLiteral("0.3.2")); PM_SystemV0_3_2(); Save(); @@ -307,6 +347,10 @@ void VVITConverter::ToV0_3_2() //--------------------------------------------------------------------------------------------------------------------- void VVITConverter::ToV0_3_3() { + // TODO. Delete if minimal supported version is 0.3.3 + Q_STATIC_ASSERT_X(VVITConverter::MeasurementMinVer < CONVERTER_VERSION_CHECK(0, 3, 3), + "Time to refactor the code."); + SetVersion(QStringLiteral("0.3.3")); ConvertMeasurementsToV0_3_3(); Save(); diff --git a/src/libs/ifc/xml/vvstconverter.cpp b/src/libs/ifc/xml/vvstconverter.cpp index 051255156..5f7518dbf 100644 --- a/src/libs/ifc/xml/vvstconverter.cpp +++ b/src/libs/ifc/xml/vvstconverter.cpp @@ -150,6 +150,10 @@ void VVSTConverter::DowngradeToCurrentMaxVersion() //--------------------------------------------------------------------------------------------------------------------- void VVSTConverter::AddNewTagsForV0_4_0() { + // TODO. Delete if minimal supported version is 0.4.0 + Q_STATIC_ASSERT_X(VVSTConverter::MeasurementMinVer < CONVERTER_VERSION_CHECK(0, 4, 0), + "Time to refactor the code."); + QDomElement rootElement = this->documentElement(); QDomNode refChild = rootElement.firstChildElement("version"); @@ -171,6 +175,10 @@ void VVSTConverter::AddNewTagsForV0_4_0() //--------------------------------------------------------------------------------------------------------------------- void VVSTConverter::RemoveTagsForV0_4_0() { + // TODO. Delete if minimal supported version is 0.4.0 + Q_STATIC_ASSERT_X(VVSTConverter::MeasurementMinVer < CONVERTER_VERSION_CHECK(0, 4, 0), + "Time to refactor the code."); + QDomElement rootElement = this->documentElement(); { @@ -193,6 +201,10 @@ void VVSTConverter::RemoveTagsForV0_4_0() //--------------------------------------------------------------------------------------------------------------------- void VVSTConverter::ConvertMeasurementsToV0_4_0() { + // TODO. Delete if minimal supported version is 0.4.0 + Q_STATIC_ASSERT_X(VVSTConverter::MeasurementMinVer < CONVERTER_VERSION_CHECK(0, 4, 0), + "Time to refactor the code."); + const QString tagBM = QStringLiteral("body-measurements"); QDomElement bm = createElement(tagBM); @@ -239,6 +251,10 @@ void VVSTConverter::ConvertMeasurementsToV0_4_0() //--------------------------------------------------------------------------------------------------------------------- QDomElement VVSTConverter::AddMV0_4_0(const QString &name, qreal value, qreal sizeIncrease, qreal heightIncrease) { + // TODO. Delete if minimal supported version is 0.4.0 + Q_STATIC_ASSERT_X(VVSTConverter::MeasurementMinVer < CONVERTER_VERSION_CHECK(0, 4, 0), + "Time to refactor the code."); + QDomElement element = createElement(QStringLiteral("m")); SetAttribute(element, QStringLiteral("name"), name); @@ -254,6 +270,10 @@ QDomElement VVSTConverter::AddMV0_4_0(const QString &name, qreal value, qreal si //--------------------------------------------------------------------------------------------------------------------- void VVSTConverter::PM_SystemV0_4_1() { + // TODO. Delete if minimal supported version is 0.4.1 + Q_STATIC_ASSERT_X(VVSTConverter::MeasurementMinVer < CONVERTER_VERSION_CHECK(0, 4, 1), + "Time to refactor the code."); + QDomElement pm_system = createElement(QStringLiteral("pm_system")); pm_system.appendChild(createTextNode(QStringLiteral("998"))); @@ -267,6 +287,10 @@ void VVSTConverter::PM_SystemV0_4_1() //--------------------------------------------------------------------------------------------------------------------- void VVSTConverter::ConvertMeasurementsToV0_4_2() { + // TODO. Delete if minimal supported version is 0.4.2 + Q_STATIC_ASSERT_X(VVSTConverter::MeasurementMinVer < CONVERTER_VERSION_CHECK(0, 4, 2), + "Time to refactor the code."); + const QMap<QString, QString> names = OldNamesToNewNames_InV0_3_3(); auto i = names.constBegin(); while (i != names.constEnd()) @@ -296,6 +320,10 @@ void VVSTConverter::ConvertMeasurementsToV0_4_2() //--------------------------------------------------------------------------------------------------------------------- void VVSTConverter::ToV0_4_0() { + // TODO. Delete if minimal supported version is 0.4.0 + Q_STATIC_ASSERT_X(VVSTConverter::MeasurementMinVer < CONVERTER_VERSION_CHECK(0, 4, 0), + "Time to refactor the code."); + AddRootComment(); SetVersion(QStringLiteral("0.4.0")); AddNewTagsForV0_4_0(); @@ -307,6 +335,10 @@ void VVSTConverter::ToV0_4_0() //--------------------------------------------------------------------------------------------------------------------- void VVSTConverter::ToV0_4_1() { + // TODO. Delete if minimal supported version is 0.4.1 + Q_STATIC_ASSERT_X(VVSTConverter::MeasurementMinVer < CONVERTER_VERSION_CHECK(0, 4, 1), + "Time to refactor the code."); + SetVersion(QStringLiteral("0.4.1")); PM_SystemV0_4_1(); Save(); @@ -315,6 +347,10 @@ void VVSTConverter::ToV0_4_1() //--------------------------------------------------------------------------------------------------------------------- void VVSTConverter::ToV0_4_2() { + // TODO. Delete if minimal supported version is 0.4.2 + Q_STATIC_ASSERT_X(VVSTConverter::MeasurementMinVer < CONVERTER_VERSION_CHECK(0, 4, 2), + "Time to refactor the code."); + SetVersion(QStringLiteral("0.4.2")); ConvertMeasurementsToV0_4_2(); Save(); @@ -323,6 +359,10 @@ void VVSTConverter::ToV0_4_2() //--------------------------------------------------------------------------------------------------------------------- void VVSTConverter::ToV0_4_3() { + // TODO. Delete if minimal supported version is 0.4.3 + Q_STATIC_ASSERT_X(VVSTConverter::MeasurementMinVer < CONVERTER_VERSION_CHECK(0, 4, 3), + "Time to refactor the code."); + SetVersion(QStringLiteral("0.4.3")); Save(); } diff --git a/src/libs/vgeometry/vabstractcurve.cpp b/src/libs/vgeometry/vabstractcurve.cpp index d50762799..5d00aca93 100644 --- a/src/libs/vgeometry/vabstractcurve.cpp +++ b/src/libs/vgeometry/vabstractcurve.cpp @@ -236,6 +236,37 @@ bool VAbstractCurve::IsIntersectLine(const QLineF &line) const return not points.isEmpty(); } +//--------------------------------------------------------------------------------------------------------------------- +bool VAbstractCurve::IsPointOnCurve(const QVector<QPointF> &points, const QPointF &p) +{ + if (points.isEmpty()) + { + return false; + } + else if (points.size() < 2) + { + return points.at(0) == p; + } + else + { + for (qint32 i = 0; i < points.count()-1; ++i) + { + if (IsPointOnLineSegment(p, points.at(i), points.at(i+1))) + { + return true; + } + } + } + + return false; +} + +//--------------------------------------------------------------------------------------------------------------------- +bool VAbstractCurve::IsPointOnCurve(const QPointF &p) const +{ + return IsPointOnCurve(GetPoints(), p); +} + //--------------------------------------------------------------------------------------------------------------------- quint32 VAbstractCurve::GetDuplicate() const { @@ -321,6 +352,11 @@ QPainterPath VAbstractCurve::ShowDirection(const QVector<QPointF> &points) const //--------------------------------------------------------------------------------------------------------------------- qreal VAbstractCurve::PathLength(const QVector<QPointF> &path) { + if (path.size() < 2) + { + return 0; + } + QPainterPath splinePath; splinePath.moveTo(path.at(0)); for (qint32 i = 1; i < path.count(); ++i) diff --git a/src/libs/vgeometry/vabstractcurve.h b/src/libs/vgeometry/vabstractcurve.h index 13d16969c..6cad2bb9c 100644 --- a/src/libs/vgeometry/vabstractcurve.h +++ b/src/libs/vgeometry/vabstractcurve.h @@ -70,6 +70,9 @@ public: virtual QVector<QPointF> IntersectLine(const QLineF &line) const; virtual bool IsIntersectLine(const QLineF &line) const; + static bool IsPointOnCurve(const QVector<QPointF> &points, const QPointF &p); + bool IsPointOnCurve(const QPointF &p) const; + virtual qreal GetStartAngle () const=0; virtual qreal GetEndAngle () const=0; @@ -79,13 +82,14 @@ public: QString GetColor() const; void SetColor(const QString &color); + static qreal PathLength(const QVector<QPointF> &path); + static QVector<QPointF> CurveIntersectLine(const QVector<QPointF> &points, const QLineF &line); virtual QString NameForHistory(const QString &toolName) const=0; protected: QPainterPath ShowDirection(const QVector<QPointF> &points) const; virtual void CreateName() =0; - static qreal PathLength(const QVector<QPointF> &path); private: QSharedDataPointer<VAbstractCurveData> d; diff --git a/src/libs/vgeometry/vgobject.cpp b/src/libs/vgeometry/vgobject.cpp index 3ac67e251..a72e0b8c8 100644 --- a/src/libs/vgeometry/vgobject.cpp +++ b/src/libs/vgeometry/vgobject.cpp @@ -539,28 +539,6 @@ int VGObject::PointInCircle(const QPointF &p, const QPointF ¢er, qreal radiu return 2; // inside circle } -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief GetReversePoint return revers container of points. - * @param points container with points. - * @return reverced points. - */ -QVector<QPointF> VGObject::GetReversePoints(const QVector<QPointF> &points) -{ - if (points.isEmpty()) - { - return points; - } - QVector<QPointF> reversePoints(points.size()); - qint32 j = 0; - for (qint32 i = points.size() - 1; i >= 0; --i) - { - reversePoints.replace(j, points.at(i)); - ++j; - } - return reversePoints; -} - //--------------------------------------------------------------------------------------------------------------------- /** * @brief GetLengthContour return length of contour. diff --git a/src/libs/vgeometry/vgobject.h b/src/libs/vgeometry/vgobject.h index 56ef87f94..18894c77f 100644 --- a/src/libs/vgeometry/vgobject.h +++ b/src/libs/vgeometry/vgobject.h @@ -90,7 +90,8 @@ public: static bool IsPointOnLineSegment (const QPointF &t, const QPointF &p1, const QPointF &p2); static bool IsPointOnLineviaPDP(const QPointF &t, const QPointF &p1, const QPointF &p2); - static QVector<QPointF> GetReversePoints(const QVector<QPointF> &points); + template <typename T> + static QVector<T> GetReversePoints(const QVector<T> &points); static int GetLengthContour(const QVector<QPointF> &contour, const QVector<QPointF> &newPoints); static const double accuracyPointOnLine; @@ -105,6 +106,29 @@ private: static int PointInCircle (const QPointF &p, const QPointF ¢er, qreal radius); }; +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief GetReversePoint return revers container of points. + * @param points container with points. + * @return reverced points. + */ +template <typename T> +QVector<T> VGObject::GetReversePoints(const QVector<T> &points) +{ + if (points.isEmpty()) + { + return points; + } + QVector<T> reversePoints(points.size()); + qint32 j = 0; + for (qint32 i = points.size() - 1; i >= 0; --i) + { + reversePoints.replace(j, points.at(i)); + ++j; + } + return reversePoints; +} + Q_DECLARE_TYPEINFO(VGObject, Q_MOVABLE_TYPE); #endif // VGOBJECT_H diff --git a/src/libs/vlayout/vabstractdetail.cpp b/src/libs/vlayout/vabstractdetail.cpp deleted file mode 100644 index 00372a5c2..000000000 --- a/src/libs/vlayout/vabstractdetail.cpp +++ /dev/null @@ -1,855 +0,0 @@ -/************************************************************************ - ** - ** @file vabstractdetail.cpp - ** @author Roman Telezhynskyi <dismine(at)gmail.com> - ** @date 2 1, 2015 - ** - ** @brief - ** @copyright - ** This source code is part of the Valentine project, a pattern making - ** program, whose allow create and modeling patterns of clothing. - ** Copyright (C) 2013-2015 Valentina project - ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. - ** - ** Valentina is free software: you can redistribute it and/or modify - ** it under the terms of the GNU General Public License as published by - ** the Free Software Foundation, either version 3 of the License, or - ** (at your option) any later version. - ** - ** Valentina is distributed in the hope that it will be useful, - ** but WITHOUT ANY WARRANTY; without even the implied warranty of - ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - ** GNU General Public License for more details. - ** - ** You should have received a copy of the GNU General Public License - ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. - ** - *************************************************************************/ - -#include "vabstractdetail.h" - -#include <QLine> -#include <QLineF> -#include <QMessageLogger> -#include <QPainterPath> -#include <QPoint> -#include <QPointF> -#include <QString> -#include <QVector> -#include <QtDebug> - -#include "../vgeometry/vgobject.h" -#include "vabstractdetail_p.h" - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief VAbstractDetail default contructor. Create empty detail. - */ -VAbstractDetail::VAbstractDetail() - :d(new VAbstractDetailData) -{} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief VAbstractDetail constructor. - * @param name detail name. - */ -VAbstractDetail::VAbstractDetail(const QString &name) - :d(new VAbstractDetailData(name)) -{} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief VAbstractDetail copy constructor. - * @param detail detail. - */ -VAbstractDetail::VAbstractDetail(const VAbstractDetail &detail) - :d (detail.d) -{} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief operator = assignment operator. - * @param detail detail. - * @return new detail. - */ -VAbstractDetail &VAbstractDetail::operator=(const VAbstractDetail &detail) -{ - if ( &detail == this ) - { - return *this; - } - d = detail.d; - return *this; -} - -//--------------------------------------------------------------------------------------------------------------------- -VAbstractDetail::~VAbstractDetail() -{} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief Clear detail full clear. - */ -void VAbstractDetail::Clear() -{ - d->name.clear(); - d->seamAllowance = false; - d->closed = true; - d->width = 0; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief getName return detail name. - * @return name. - */ -QString VAbstractDetail::getName() const -{ - return d->name; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief setName set detail name. - * @param value new name. - */ -void VAbstractDetail::setName(const QString &value) -{ - d->name = value; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief getSeamAllowance keep status for seam allowance detail. - * @return true - need seam allowance, false - no need seam allowance. - */ -bool VAbstractDetail::getSeamAllowance() const -{ - return d->seamAllowance; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief setSeamAllowance set status for seam allowance detail. - * @param value true - need seam allowance, false - no need seam allowance. - */ -void VAbstractDetail::setSeamAllowance(bool value) -{ - d->seamAllowance = value; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief getClosed keep close status for detail equdistant. - * @return true - close equdistant, false - don't close equdistant. - */ -bool VAbstractDetail::getClosed() const -{ - return d->closed; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief setClosed set close status for detail equdistant. - * @param value true - close equdistant, false - don't close equdistant. - */ -void VAbstractDetail::setClosed(bool value) -{ - d->closed = value; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief getWidth return value detail seam allowance. - * @return value in mm. - */ -qreal VAbstractDetail::getWidth() const -{ - return d->width; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief setWidth set value detail seam allowance. - * @param value width in mm. - */ -void VAbstractDetail::setWidth(const qreal &value) -{ - d->width = value; -} - -//--------------------------------------------------------------------------------------------------------------------- -bool VAbstractDetail::getForbidFlipping() const -{ - return d->forbidFlipping; -} - -//--------------------------------------------------------------------------------------------------------------------- -void VAbstractDetail::setForbidFlipping(bool value) -{ - d->forbidFlipping = value; -} - -//--------------------------------------------------------------------------------------------------------------------- -QVector<QPointF> VAbstractDetail::Equidistant(const QVector<QPointF> &points, const EquidistantType &eqv, qreal width) -{ - QVector<QPointF> ekvPoints; - - if (width <= 0) - { - qDebug()<<"Width <= 0."; - return QVector<QPointF>(); - } - - QVector<QPointF> p = CorrectEquidistantPoints(points); - if ( p.size() < 3 ) - { - qDebug()<<"Not enough points for building the equidistant."; - return QVector<QPointF>(); - } - - if (eqv == EquidistantType::CloseEquidistant) - { - p.append(p.at(0)); - } - for (qint32 i = 0; i < p.size(); ++i ) - { - if ( i == 0 && eqv == EquidistantType::CloseEquidistant) - {//first point, polyline closed - ekvPoints<<EkvPoint(QLineF(p.at(p.size()-2), p.at(p.size()-1)), QLineF(p.at(1), p.at(0)), width); - continue; - } - else if (i == 0 && eqv == EquidistantType::OpenEquidistant) - {//first point, polyline doesn't closed - ekvPoints.append(UnclosedEkvPoint(QLineF(p.at(0), p.at(1)), QLineF(p.at(0), p.at(p.size()-1)), width)); - continue; - } - if (i == p.size()-1 && eqv == EquidistantType::CloseEquidistant) - {//last point, polyline closed - if (not ekvPoints.isEmpty()) - { - ekvPoints.append(ekvPoints.at(0)); - } - continue; - } - else if (i == p.size()-1 && eqv == EquidistantType::OpenEquidistant) - {//last point, polyline doesn't closed - ekvPoints.append(UnclosedEkvPoint(QLineF(p.at(p.size()-2), p.at(p.size()-1)), - QLineF(p.at(0), p.at(p.size()-1)), width)); - continue; - } - //points in the middle of polyline - ekvPoints<<EkvPoint(QLineF(p.at(i-1), p.at(i)), QLineF(p.at(i+1), p.at(i)), width); - } - - bool removeFirstAndLast = true; - if (eqv == EquidistantType::CloseEquidistant) - { - removeFirstAndLast = false; - } - - ekvPoints = CheckLoops(CorrectEquidistantPoints(ekvPoints, removeFirstAndLast));//Result path can contain loops - return ekvPoints; -} - -//--------------------------------------------------------------------------------------------------------------------- -QVector<QPointF> VAbstractDetail::RemoveDublicates(const QVector<QPointF> &points, bool removeFirstAndLast) -{ - QVector<QPointF> p = points; - - if (removeFirstAndLast) - { - if (not p.isEmpty() && p.size() > 1) - { - // Path can't be closed - if (p.first() == p.last()) - { - #if QT_VERSION < QT_VERSION_CHECK(5, 1, 0) - p.remove(p.size() - 1); - #else - p.removeLast(); - #endif - } - } - } - - for (int i = 0; i < p.size()-1; ++i) - { - if (p.at(i) == p.at(i+1)) - { - if (not removeFirstAndLast && (i == p.size()-1)) - { - continue; - } - - p.erase(p.begin() + i + 1); - --i; - continue; - } - } - - return p; -} - -//--------------------------------------------------------------------------------------------------------------------- -bool VAbstractDetail::CheckIntersection(const QVector<QPointF> &points, int i, int iNext, int j, int jNext, - const QPointF &crossPoint) -{ - QVector<QPointF> sub1 = SubPath(points, iNext, j); - sub1.append(crossPoint); - sub1 = CheckLoops(CorrectEquidistantPoints(sub1, false)); - const qreal sub1Sum = SumTrapezoids(sub1); - - QVector<QPointF> sub2 = SubPath(points, jNext, i); - sub2.append(crossPoint); - sub2 = CheckLoops(CorrectEquidistantPoints(sub2, false)); - const qreal sub2Sum = SumTrapezoids(sub2); - - if (sub1Sum < 0 && sub2Sum < 0) - { - if (Crossing(sub1, sub2)) - { - return true; - } - } - else - { - if (not Crossing(sub1, sub2)) - { - return true; - } - } - return false; -} - -//--------------------------------------------------------------------------------------------------------------------- -bool VAbstractDetail::ParallelCrossPoint(const QLineF &line1, const QLineF &line2, QPointF &point) -{ - const bool l1p1el2p1 = (line1.p1() == line2.p1()); - const bool l1p2el2p2 = (line1.p2() == line2.p2()); - const bool l1p1el2p2 = (line1.p1() == line2.p2()); - const bool l1p2el2p1 = (line1.p2() == line2.p1()); - - if (l1p2el2p2 || l1p2el2p1) - { - point = line1.p2(); - return true; - } - else if (l1p1el2p1 || l1p1el2p2) - { - point = line1.p1(); - return true; - } - else - { - point = QPointF(); - return false; - } -} - -//--------------------------------------------------------------------------------------------------------------------- -bool VAbstractDetail::Crossing(const QVector<QPointF> &sub1, const QVector<QPointF> &sub2) -{ - if (sub1.isEmpty() || sub2.isEmpty()) - { - return false; - } - - const QRectF sub1Rect = QPolygonF(sub1).boundingRect(); - const QRectF sub2Rect = QPolygonF(sub2).boundingRect(); - if (not sub1Rect.intersects(sub2Rect)) - { - return false; - } - - QPainterPath sub1Path; - sub1Path.setFillRule(Qt::WindingFill); - sub1Path.moveTo(sub1.at(0)); - for (qint32 i = 1; i < sub1.count(); ++i) - { - sub1Path.lineTo(sub1.at(i)); - } - sub1Path.lineTo(sub1.at(0)); - - QPainterPath sub2Path; - sub2Path.setFillRule(Qt::WindingFill); - sub2Path.moveTo(sub2.at(0)); - for (qint32 i = 1; i < sub2.count(); ++i) - { - sub2Path.lineTo(sub2.at(i)); - } - sub2Path.lineTo(sub2.at(0)); - - if (not sub1Path.intersects(sub2Path)) - { - return false; - } - else - { - return true; - } -} - -//--------------------------------------------------------------------------------------------------------------------- -QVector<QPointF> VAbstractDetail::SubPath(const QVector<QPointF> &path, int startIndex, int endIndex) -{ - if (path.isEmpty() - || startIndex < 0 || startIndex >= path.size() - || endIndex < 0 || endIndex >= path.size() - || startIndex == endIndex) - { - return path; - } - - QVector<QPointF> subPath; - int i = startIndex - 1; - do - { - ++i; - if (i >= path.size()) - { - i = 0; - } - subPath.append(path.at(i)); - } while (i != endIndex); - - return subPath; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief CorrectEquidistantPoints clear equivalent points and remove point on line from equdistant. - * @param points list of points equdistant. - * @return corrected list. - */ -QVector<QPointF> VAbstractDetail::CorrectEquidistantPoints(const QVector<QPointF> &points, bool removeFirstAndLast) -{ - if (points.size()<4)//Better don't check if only three points. We can destroy equidistant. - { - qDebug()<<"Only three points."; - return points; - } - - //Clear equivalent points - QVector<QPointF> buf1 = RemoveDublicates(points, removeFirstAndLast); - - if (buf1.size()<3) - { - return buf1; - } - - QVector<QPointF> buf2; - //Remove point on line - for (qint32 i = 0; i < buf1.size(); ++i) - {// In this case we alwayse will have bounded intersection, so all is need is to check if point i is on line. - // Unfortunatelly QLineF::intersect can't be used in this case because of the floating-point accuraccy problem. - int prev = i-1; - int next = i+1; - if (i == 0) - { - prev = buf1.size() - 1; - } - else if (i == buf1.size() - 1) - { - next = 0; - } - - const QPointF &iPoint = buf1.at(i); - const QPointF &prevPoint = buf1.at(prev); - const QPointF &nextPoint = buf1.at(next); - - if (not VGObject::IsPointOnLineviaPDP(buf1.at(i), buf1.at(prev), buf1.at(next)) - && prevPoint != nextPoint) // not zigzag - { - buf2.append(buf1.at(i)); - } - else if ((i == 0 || i == buf1.size() - 1) && (iPoint == prevPoint || iPoint == nextPoint)) - { - // If RemoveDublicates does not remove these points it is a valid case. - // Case where last point equal first point - buf2.append(buf1.at(i)); - } - } - - buf2 = RemoveDublicates(buf2, false); - - return buf2; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief CheckLoops seek and delete loops in equidistant. - * @param points vector of points of equidistant. - * @return vector of points of equidistant. - */ -QVector<QPointF> VAbstractDetail::CheckLoops(const QVector<QPointF> &points) -{ - int count = points.size(); - /*If we got less than 4 points no need seek loops.*/ - if (count < 4) - { - return points; - } - - const bool pathClosed = (points.first() == points.last()); - - QVector<QPointF> ekvPoints; - - qint32 i, j, jNext = 0; - for (i = 0; i < count; ++i) - { - /*Last three points no need check.*/ - /*Triangle has not contain loops*/ - if (i > count-3) - { - ekvPoints.append(points.at(i)); - continue; - } - - enum LoopIntersectType { NoIntersection, BoundedIntersection, ParallelIntersection }; - - QPointF crosPoint; - LoopIntersectType status = NoIntersection; - const QLineF line1(points.at(i), points.at(i+1)); - // Because a path can contains several loops we will seek the last and only then remove the loop(s) - // That's why we parse from the end - for (j = count-1; j >= i+2; --j) - { - j == count-1 ? jNext = 0 : jNext = j+1; - QLineF line2(points.at(j), points.at(jNext)); - - if(qFuzzyIsNull(line2.length())) - {//If a path is closed the edge (count-1;0) length will be 0 - continue; - } - - QSet<qint32> uniqueVertices; - uniqueVertices << i << i+1 << j; - - // For closed path last point is equal to first. Using index of the first. - pathClosed && jNext == count-1 ? uniqueVertices << 0 : uniqueVertices << jNext; - - const QLineF::IntersectType intersect = line1.intersect(line2, &crosPoint); - if (intersect == QLineF::NoIntersection) - { // According to the documentation QLineF::NoIntersection indicates that the lines do not intersect; - // i.e. they are parallel. But parallel also mean they can be on the same line. - // Method IsPointOnLineviaPDP will check it. - if (VGObject::IsPointOnLineviaPDP(points.at(j), points.at(i), points.at(i+1)) - // Lines are not neighbors - && uniqueVertices.size() == 4) - { - // Left to catch case where segments are on the same line, but do not have real intersections. - QLineF tmpLine1 = line1; - QLineF tmpLine2 = line2; - - tmpLine1.setAngle(tmpLine1.angle()+90); - - QPointF tmpCrosPoint; - const QLineF::IntersectType tmpIntrs1 = tmpLine1.intersect(tmpLine2, &tmpCrosPoint); - - tmpLine1 = line1; - tmpLine2.setAngle(tmpLine2.angle()+90); - - const QLineF::IntersectType tmpIntrs2 = tmpLine1.intersect(tmpLine2, &tmpCrosPoint); - - if (tmpIntrs1 == QLineF::BoundedIntersection || tmpIntrs2 == QLineF::BoundedIntersection) - { // Now we really sure that lines are on the same line and have real intersections. - QPointF cPoint; - const bool caseFlag = ParallelCrossPoint(line1, line2, cPoint); - if (not caseFlag || CheckIntersection(points, i, i+1, j, jNext, cPoint)) - { - status = ParallelIntersection; - break; - } - } - } - } - else if (intersect == QLineF::BoundedIntersection) - { - if (uniqueVertices.size() == 4) - { // Break, but not if lines are neighbors - if ((line1.p1() != crosPoint - && line1.p2() != crosPoint - && line2.p1() != crosPoint - && line2.p2() != crosPoint) || CheckIntersection(points, i, i+1, j, jNext, crosPoint)) - { - status = BoundedIntersection; - break; - } - } - } - status = NoIntersection; - } - - switch (status) - { - case ParallelIntersection: - /*We have found a loop.*/ - ekvPoints.append(points.at(i)); - ekvPoints.append(points.at(jNext)); - jNext > j ? i = jNext : i = j; // Skip a loop - break; - case BoundedIntersection: - ekvPoints.append(points.at(i)); - ekvPoints.append(crosPoint); - i = j; - break; - case NoIntersection: - /*We have not found loop.*/ - ekvPoints.append(points.at(i)); - break; - default: - break; - } - } - return ekvPoints; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief EkvPoint return vector of points of equidistant two lines. Last point of two lines must be equal. - * @param line1 first line. - * @param line2 second line. - * @param width width of equidistant. - * @return vector of points. - */ -QVector<QPointF> VAbstractDetail::EkvPoint(const QLineF &line1, const QLineF &line2, const qreal &width) -{ - if (width <= 0) - { - return QVector<QPointF>(); - } - QVector<QPointF> points; - if (line1.p2() != line2.p2()) - { - qDebug()<<"Last points of two lines must be equal."; - return QVector<QPointF>(); - } - QPointF CrosPoint; - const QLineF bigLine1 = ParallelLine(line1, width ); - const QLineF bigLine2 = ParallelLine(QLineF(line2.p2(), line2.p1()), width ); - QLineF::IntersectType type = bigLine1.intersect( bigLine2, &CrosPoint ); - switch (type) - { - case (QLineF::BoundedIntersection): - points.append(CrosPoint); - return points; - break; - case (QLineF::UnboundedIntersection): - { - QLineF line( line1.p2(), CrosPoint ); - - const int angle1 = BisectorAngle(line1.p1(), line1.p2(), line2.p1()); - const int angle2 = BisectorAngle(bigLine1.p1(), CrosPoint, bigLine2.p2()); - - if (angle1 == angle2) - {//Regular equdistant case - const qreal length = line.length(); - if (length > width*2.4) - { // Cutting too long a cut angle - line.setLength(width); // Not sure about width value here - QLineF cutLine(line.p2(), CrosPoint); // Cut line is a perpendicular - cutLine.setLength(length); // Decided take this length - - // We do not check intersection type because intersection must alwayse exist - QPointF px; - cutLine.setAngle(cutLine.angle()+90); - QLineF::IntersectType type = bigLine1.intersect( cutLine, &px ); - if (type == QLineF::NoIntersection) - { - qDebug()<<"Couldn't find intersection with cut line."; - } - points.append(px); - - cutLine.setAngle(cutLine.angle()-180); - type = bigLine2.intersect( cutLine, &px ); - if (type == QLineF::NoIntersection) - { - qDebug()<<"Couldn't find intersection with cut line."; - } - points.append(px); - } - else - { - points.append(CrosPoint); - return points; - } - } - else - {// Dart. Create a loop. - points.append(bigLine1.p2()); - points.append(bigLine2.p1()); - return points; - } - break; - } - case (QLineF::NoIntersection): - /*If we have correct lines this means lines lie on a line.*/ - points.append(bigLine1.p2()); - return points; - break; - default: - break; - } - return points; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief UnclosedEkvPoint helps find point of an unclosed seam allowance. One side of two lines should be equal. - * - * In case of the first seam allowance point equal should be the first point of the two lines. In case the last point - - * the last point of the two lines. - * - * @param line line of a seam allowance - * @param helpLine help line of the main path that cut unclosed seam allowance - * @param width seam allowance width - * @return seam allowance point - */ -QPointF VAbstractDetail::UnclosedEkvPoint(const QLineF &line, const QLineF &helpLine, const qreal &width) -{ - if (width <= 0) - { - return QPointF(); - } - - const bool firstPoint = line.p1() == helpLine.p1(); - if (not (line.p2() == helpLine.p2() || firstPoint)) - { - qDebug()<<"Two points of two lines must be equal."; - return QPointF(); - } - - QPointF CrosPoint; - const QLineF bigLine = ParallelLine(line, width ); - QLineF::IntersectType type = bigLine.intersect( helpLine, &CrosPoint ); - switch (type) - { - case (QLineF::BoundedIntersection): - return CrosPoint; - break; - case (QLineF::UnboundedIntersection): - { - // This case is very tricky. - // User can create very wrong path that will create crospoint far from main path. - // Such an annomaly we try to catch and fix. - // If don't do this the program will crash. - QLineF test; - firstPoint ? test = QLineF(line.p1(), CrosPoint) : test = QLineF(line.p2(), CrosPoint); - const qreal length = test.length(); - if (length > width*2.4) - { - test.setLength(width); - return test.p2(); - } - else - { - return CrosPoint; - } - break; - } - case (QLineF::NoIntersection): - /*If we have correct lines this means lines lie on a line.*/ - if (firstPoint) - { - return bigLine.p1(); - } - else - { - return bigLine.p2(); - } - break; - default: - break; - } - return QPointF(); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief ParallelLine create parallel line. - * @param line starting line. - * @param width width to parallel line. - * @return parallel line. - */ -QLineF VAbstractDetail::ParallelLine(const QLineF &line, qreal width) -{ - QLineF paralel = QLineF (SingleParallelPoint(line, 90, width), SingleParallelPoint(QLineF(line.p2(), line.p1()), - -90, width)); - return paralel; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief SingleParallelPoint return point of parallel line. - * @param line starting line. - * @param angle angle in degree. - * @param width width to parallel line. - * @return point of parallel line. - */ -QPointF VAbstractDetail::SingleParallelPoint(const QLineF &line, const qreal &angle, const qreal &width) -{ - QLineF pLine = line; - pLine.setAngle( pLine.angle() + angle ); - pLine.setLength( width ); - return pLine.p2(); -} - -//--------------------------------------------------------------------------------------------------------------------- -int VAbstractDetail::BisectorAngle(const QPointF &p1, const QPointF &p2, const QPointF &p3) -{ - QLineF line1(p2, p1); - QLineF line2(p2, p3); - QLineF bLine; - - const qreal angle1 = line1.angleTo(line2); - const qreal angle2 = line2.angleTo(line1); - - if (angle1 <= angle2) - { - bLine = line1; - bLine.setAngle(bLine.angle() + angle1/2.0); - } - else - { - bLine = line2; - bLine.setAngle(bLine.angle() + angle2/2.0); - } - - return qRound(bLine.angle()); -} - -//--------------------------------------------------------------------------------------------------------------------- -qreal VAbstractDetail::SumTrapezoids(const QVector<QPointF> &points) -{ - // Calculation a polygon area through the sum of the areas of trapezoids - qreal s, res = 0; - const int n = points.size(); - - if(n > 2) - { - for (int i = 0; i < n; ++i) - { - if (i == 0) - { - s = points.at(i).x()*(points.at(n-1).y() - points.at(i+1).y()); //if i == 0, then y[i-1] replace on y[n-1] - res += s; - } - else - { - if (i == n-1) - { - s = points.at(i).x()*(points.at(i-1).y() - points.at(0).y()); // if i == n-1, then y[i+1] replace on y[0] - res += s; - } - else - { - s = points.at(i).x()*(points.at(i-1).y() - points.at(i+1).y()); - res += s; - } - } - } - } - return res; -} diff --git a/src/libs/vlayout/vabstractdetail.h b/src/libs/vlayout/vabstractdetail.h deleted file mode 100644 index 902b15dd2..000000000 --- a/src/libs/vlayout/vabstractdetail.h +++ /dev/null @@ -1,98 +0,0 @@ -/************************************************************************ - ** - ** @file vabstractdetail.h - ** @author Roman Telezhynskyi <dismine(at)gmail.com> - ** @date 2 1, 2015 - ** - ** @brief - ** @copyright - ** This source code is part of the Valentine project, a pattern making - ** program, whose allow create and modeling patterns of clothing. - ** Copyright (C) 2013-2015 Valentina project - ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. - ** - ** Valentina is free software: you can redistribute it and/or modify - ** it under the terms of the GNU General Public License as published by - ** the Free Software Foundation, either version 3 of the License, or - ** (at your option) any later version. - ** - ** Valentina is distributed in the hope that it will be useful, - ** but WITHOUT ANY WARRANTY; without even the implied warranty of - ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - ** GNU General Public License for more details. - ** - ** You should have received a copy of the GNU General Public License - ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. - ** - *************************************************************************/ - -#ifndef VABSTRACTDETAIL_H -#define VABSTRACTDETAIL_H - -#include <QSharedDataPointer> -#include <QTypeInfo> -#include <QtGlobal> - -#include "vlayoutdef.h" - -class QLineF; -class QPointF; -class QString; -class VAbstractDetailData; -template <typename T> class QVector; - -/** - * @brief The VAbstractDetail class abstract class for all details. - */ -class VAbstractDetail -{ -public: - VAbstractDetail(); - explicit VAbstractDetail(const QString &name); - VAbstractDetail(const VAbstractDetail &detail); - VAbstractDetail &operator=(const VAbstractDetail &detail); - virtual ~VAbstractDetail(); - - void Clear(); - - QString getName() const; - void setName(const QString &value); - - bool getSeamAllowance() const; - void setSeamAllowance(bool value); - - bool getClosed() const; - void setClosed(bool value); - - qreal getWidth() const; - void setWidth(const qreal &value); - - bool getForbidFlipping() const; - void setForbidFlipping(bool value); - - static QVector<QPointF> Equidistant(const QVector<QPointF> &points, const EquidistantType &eqv, qreal width); - static qreal SumTrapezoids(const QVector<QPointF> &points); - static QVector<QPointF> CheckLoops(const QVector<QPointF> &points); - static QVector<QPointF> CorrectEquidistantPoints(const QVector<QPointF> &points, bool removeFirstAndLast = true); - -protected: - static QVector<QPointF> RemoveDublicates(const QVector<QPointF> &points, bool removeFirstAndLast = true); - -private: - QSharedDataPointer<VAbstractDetailData> d; - - static bool CheckIntersection(const QVector<QPointF> &points, int i, int iNext, int j, int jNext, - const QPointF &crossPoint); - static bool ParallelCrossPoint(const QLineF &line1, const QLineF &line2, QPointF &point); - static bool Crossing(const QVector<QPointF> &sub1, const QVector<QPointF> &sub2); - static QVector<QPointF> SubPath(const QVector<QPointF> &path, int startIndex, int endIndex); - static QVector<QPointF> EkvPoint(const QLineF &line1, const QLineF &line2, const qreal &width); - static QPointF UnclosedEkvPoint(const QLineF &line, const QLineF &helpLine, const qreal &width); - static QLineF ParallelLine(const QLineF &line, qreal width ); - static QPointF SingleParallelPoint(const QLineF &line, const qreal &angle, const qreal &width); - static int BisectorAngle(const QPointF &p1, const QPointF &p2, const QPointF &p3); -}; - -Q_DECLARE_TYPEINFO(VAbstractDetail, Q_MOVABLE_TYPE); - -#endif // VABSTRACTDETAIL_H diff --git a/src/libs/vlayout/vabstractpiece.cpp b/src/libs/vlayout/vabstractpiece.cpp new file mode 100644 index 000000000..061375072 --- /dev/null +++ b/src/libs/vlayout/vabstractpiece.cpp @@ -0,0 +1,938 @@ +/************************************************************************ + ** + ** @file + ** @author Roman Telezhynskyi <dismine(at)gmail.com> + ** @date 3 11, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2016 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#include "vabstractpiece.h" +#include "vabstractpiece_p.h" +#include "../vmisc/vabstractapplication.h" +#include "../vgeometry/vpointf.h" + +#include <QLineF> +#include <QSet> +#include <QVector> +#include <QPainterPath> + +const qreal maxL = 2.4; + +//--------------------------------------------------------------------------------------------------------------------- +VAbstractPiece::VAbstractPiece() + : d(new VAbstractPieceData) +{} + +//--------------------------------------------------------------------------------------------------------------------- +VAbstractPiece::VAbstractPiece(const VAbstractPiece &piece) + :d (piece.d) +{} + +//--------------------------------------------------------------------------------------------------------------------- +VAbstractPiece &VAbstractPiece::operator=(const VAbstractPiece &piece) +{ + if ( &piece == this ) + { + return *this; + } + d = piece.d; + return *this; +} + +//--------------------------------------------------------------------------------------------------------------------- +VAbstractPiece::~VAbstractPiece() +{} + +//--------------------------------------------------------------------------------------------------------------------- +QString VAbstractPiece::GetName() const +{ + return d->m_name; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VAbstractPiece::SetName(const QString &value) +{ + d->m_name = value; +} + +//--------------------------------------------------------------------------------------------------------------------- +bool VAbstractPiece::IsForbidFlipping() const +{ + return d->m_forbidFlipping; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VAbstractPiece::SetForbidFlipping(bool value) +{ + d->m_forbidFlipping = value; +} + +//--------------------------------------------------------------------------------------------------------------------- +bool VAbstractPiece::IsSeamAllowance() const +{ + return d->m_seamAllowance; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VAbstractPiece::SetSeamAllowance(bool value) +{ + d->m_seamAllowance = value; +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal VAbstractPiece::GetSAWidth() const +{ + return d->m_width; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VAbstractPiece::SetSAWidth(qreal value) +{ + value >= 0 ? d->m_width = value : d->m_width = 0; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<QPointF> VAbstractPiece::Equidistant(const QVector<VSAPoint> &points, qreal width) +{ + if (width < 0) + { + qDebug()<<"Width < 0."; + return QVector<QPointF>(); + } + + QVector<VSAPoint> p = CorrectEquidistantPoints(points); + if ( p.size() < 3 ) + { + qDebug()<<"Not enough points for building the equidistant."; + return QVector<QPointF>(); + } + + if (p.last().toPoint() != p.first().toPoint()) + { + p.append(p.at(0));// Should be always closed + } + + QVector<QPointF> ekvPoints; + for (qint32 i = 0; i < p.size(); ++i ) + { + if ( i == 0) + {//first point + ekvPoints << EkvPoint(p.at(p.size()-2), p.at(p.size()-1), + p.at(1), p.at(0), width); + continue; + } + + if (i == p.size()-1) + {//last point + if (not ekvPoints.isEmpty()) + { + ekvPoints.append(ekvPoints.at(0)); + } + continue; + } + //points in the middle of polyline + ekvPoints << EkvPoint(p.at(i-1), p.at(i), + p.at(i+1), p.at(i), width); + } + + const bool removeFirstAndLast = false; + ekvPoints = CheckLoops(CorrectEquidistantPoints(ekvPoints, removeFirstAndLast));//Result path can contain loops + return ekvPoints; +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal VAbstractPiece::SumTrapezoids(const QVector<QPointF> &points) +{ + // Calculation a polygon area through the sum of the areas of trapezoids + qreal s, res = 0; + const int n = points.size(); + + if(n > 2) + { + for (int i = 0; i < n; ++i) + { + if (i == 0) + { + //if i == 0, then y[i-1] replace on y[n-1] + s = points.at(i).x()*(points.at(n-1).y() - points.at(i+1).y()); + res += s; + } + else + { + if (i == n-1) + { + // if i == n-1, then y[i+1] replace on y[0] + s = points.at(i).x()*(points.at(i-1).y() - points.at(0).y()); + res += s; + } + else + { + s = points.at(i).x()*(points.at(i-1).y() - points.at(i+1).y()); + res += s; + } + } + } + } + return res; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief CheckLoops seek and delete loops in equidistant. + * @param points vector of points of equidistant. + * @return vector of points of equidistant. + */ +QVector<QPointF> VAbstractPiece::CheckLoops(const QVector<QPointF> &points) +{ + int count = points.size(); + /*If we got less than 4 points no need seek loops.*/ + if (count < 4) + { + return points; + } + + const bool pathClosed = (points.first() == points.last()); + + QVector<QPointF> ekvPoints; + + qint32 i, j, jNext = 0; + for (i = 0; i < count; ++i) + { + /*Last three points no need check.*/ + /*Triangle has not contain loops*/ + if (i > count-3) + { + ekvPoints.append(points.at(i)); + continue; + } + + enum LoopIntersectType { NoIntersection, BoundedIntersection, ParallelIntersection }; + + QPointF crosPoint; + LoopIntersectType status = NoIntersection; + const QLineF line1(points.at(i), points.at(i+1)); + // Because a path can contains several loops we will seek the last and only then remove the loop(s) + // That's why we parse from the end + for (j = count-1; j >= i+2; --j) + { + j == count-1 ? jNext = 0 : jNext = j+1; + QLineF line2(points.at(j), points.at(jNext)); + + if(qFuzzyIsNull(line2.length())) + {//If a path is closed the edge (count-1;0) length will be 0 + continue; + } + + QSet<qint32> uniqueVertices; + uniqueVertices << i << i+1 << j; + + // For closed path last point is equal to first. Using index of the first. + pathClosed && jNext == count-1 ? uniqueVertices << 0 : uniqueVertices << jNext; + + const QLineF::IntersectType intersect = line1.intersect(line2, &crosPoint); + if (intersect == QLineF::NoIntersection) + { // According to the documentation QLineF::NoIntersection indicates that the lines do not intersect; + // i.e. they are parallel. But parallel also mean they can be on the same line. + // Method IsPointOnLineviaPDP will check it. + if (VGObject::IsPointOnLineviaPDP(points.at(j), points.at(i), points.at(i+1)) + // Lines are not neighbors + && uniqueVertices.size() == 4) + { + // Left to catch case where segments are on the same line, but do not have real intersections. + QLineF tmpLine1 = line1; + QLineF tmpLine2 = line2; + + tmpLine1.setAngle(tmpLine1.angle()+90); + + QPointF tmpCrosPoint; + const QLineF::IntersectType tmpIntrs1 = tmpLine1.intersect(tmpLine2, &tmpCrosPoint); + + tmpLine1 = line1; + tmpLine2.setAngle(tmpLine2.angle()+90); + + const QLineF::IntersectType tmpIntrs2 = tmpLine1.intersect(tmpLine2, &tmpCrosPoint); + + if (tmpIntrs1 == QLineF::BoundedIntersection || tmpIntrs2 == QLineF::BoundedIntersection) + { // Now we really sure that lines are on the same lines and have real intersections. + QPointF cPoint; + const bool caseFlag = ParallelCrossPoint(line1, line2, cPoint); + if (not caseFlag || CheckIntersection(points, i, i+1, j, jNext, cPoint)) + { + status = ParallelIntersection; + break; + } + } + } + } + else if (intersect == QLineF::BoundedIntersection) + { + if (uniqueVertices.size() == 4) + { // Break, but not if lines are neighbors + if ((line1.p1() != crosPoint + && line1.p2() != crosPoint + && line2.p1() != crosPoint + && line2.p2() != crosPoint) || CheckIntersection(points, i, i+1, j, jNext, crosPoint)) + { + status = BoundedIntersection; + break; + } + } + } + status = NoIntersection; + } + + switch (status) + { + case ParallelIntersection: + /*We have found a loop.*/ + ekvPoints.append(points.at(i)); + ekvPoints.append(points.at(jNext)); + jNext > j ? i = jNext : i = j; // Skip a loop + break; + case BoundedIntersection: + ekvPoints.append(points.at(i)); + ekvPoints.append(crosPoint); + i = j; + break; + case NoIntersection: + /*We have not found loop.*/ + ekvPoints.append(points.at(i)); + break; + default: + break; + } + } + return ekvPoints; +} + +//--------------------------------------------------------------------------------------------------------------------- +Q_DECL_CONSTEXPR qreal VAbstractPiece::PointPosition(const QPointF &p, const QLineF &line) +{ + return (line.p2().x() - line.p1().x()) * (p.y() - line.p1().y()) - + (line.p2().y() - line.p1().y()) * (p.x() - line.p1().x()); +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal VAbstractPiece::MaxLocalSA(const VSAPoint &p, qreal width) +{ + qreal w1 = p.GetSAAfter(); + if (w1 < 0) + { + w1 = width; + } + + qreal w2 = p.GetSABefore(); + if (w2 < 0) + { + w2 = width; + } + + return qMax(w1, w2); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief EkvPoint return seam aloowance points in place of intersection two edges. Last points of two edges should be + * equal. + * @param width global seam allowance width. + * @return seam aloowance points. + */ +QVector<QPointF> VAbstractPiece::EkvPoint(const VSAPoint &p1Line1, const VSAPoint &p2Line1, + const VSAPoint &p1Line2, const VSAPoint &p2Line2, qreal width) +{ + if (width < 0) + { // width can't be < 0 + return QVector<QPointF>(); + } + + QVector<QPointF> points; + if (p2Line1 != p2Line2) + { + qDebug()<<"Last points of two lines must be equal."; + return QVector<QPointF>(); // Wrong edges + } + + const QLineF bigLine1 = ParallelLine(p1Line1, p2Line1, width ); + const QLineF bigLine2 = ParallelLine(p2Line2, p1Line2, width ); + QPointF CrosPoint; + const QLineF::IntersectType type = bigLine1.intersect( bigLine2, &CrosPoint ); + switch (type) + {// There are at least three big cases + case (QLineF::BoundedIntersection): + // The easiest, real intersection + points.append(CrosPoint); + return points; + break; + case (QLineF::UnboundedIntersection): + { // Most common case + const qreal localWidth = MaxLocalSA(p2Line1, width); + QLineF line( p2Line1, CrosPoint ); + + // Checking two subcases + const QLineF b1 = BisectorLine(p1Line1, p2Line1, p1Line2); + const QLineF b2 = BisectorLine(bigLine1.p1(), CrosPoint, bigLine2.p2()); + + const qreal angle = AngleBetweenBisectors(b1, b2); + + // Comparison bisector angles helps to find direction + if (angle <= 90)// Go in a same direction + {//Regular equdistant case +QT_WARNING_PUSH +QT_WARNING_DISABLE_GCC("-Wswitch-default") + switch (p2Line1.GetAngleType()) + { + case PieceNodeAngle::ByLength: + return AngleByLength(p2Line1, bigLine1.p1(), CrosPoint, bigLine2.p2(), localWidth); + case PieceNodeAngle::ByPointsIntersection: + return AngleByIntersection(p1Line1, p2Line1, p1Line2, bigLine1.p1(), CrosPoint, bigLine2.p2(), + localWidth); + case PieceNodeAngle::ByFirstEdgeSymmetry: + return AngleByFirstSymmetry(p1Line1, p2Line1, bigLine1.p1(), CrosPoint, bigLine2.p2(), + localWidth); + case PieceNodeAngle::BySecondEdgeSymmetry: + return AngleBySecondSymmetry(p2Line1, p1Line2, bigLine1.p1(), CrosPoint,bigLine2.p2(), + localWidth); + case PieceNodeAngle::ByFirstEdgeRightAngle: + return AngleByFirstRightAngle(p1Line1, p2Line1, bigLine1.p1(), CrosPoint, bigLine2.p2(), + localWidth); + case PieceNodeAngle::BySecondEdgeRightAngle: + return AngleBySecondRightAngle(p2Line1, p1Line2, bigLine1.p1(), CrosPoint, bigLine2.p2(), + localWidth); + } +QT_WARNING_POP + } + else + { // Different directions + QLineF bisector(p2Line1, p1Line1); + bisector.setAngle(b1.angle()); + + const qreal result1 = PointPosition(bisector.p2(), QLineF(p1Line1, p2Line1)); + const qreal result2 = PointPosition(bisector.p2(), QLineF(p2Line2, p1Line2)); + + if (result1 <=0 && result2 <= 0) + {// Dart case. A bisector watch outside. In some cases a point still valid, but ignore if going + // outside of an equdistant. + + const QLineF bigEdge = ParallelLine(p1Line1, p1Line2, localWidth ); + QPointF px; + const QLineF::IntersectType type = bigEdge.intersect(line, &px); + if (type != QLineF::BoundedIntersection) + { + if (line.length() < QLineF(p2Line1, px).length()) + { + points.append(CrosPoint); + return points; + } + } + } + else + { // New subcase. This is not a dart. An angle is acute and bisector watch inside. + const qreal result1 = PointPosition(CrosPoint, QLineF(p1Line1, p2Line1)); + const qreal result2 = PointPosition(CrosPoint, QLineF(p2Line2, p1Line2)); + + if (result1 <=0 && result2 <= 0) + {// The cross point is still outside of a piece + if (line.length() >= localWidth) + { + points.append(CrosPoint); + return points; + } + else + {// but not enough far, fix it + line.setLength(localWidth); + points.append(line.p2()); + return points; + } + } + else + {// Wrong cross point, probably inside of a piece. Manually creating correct seam allowance + const QLineF bigEdge = ParallelLine(bigLine1.p2(), bigLine2.p1(), localWidth ); + points.append(bigEdge.p1()); + points.append(bigEdge.p2()); + return points; + } + } + } + break; + } + case (QLineF::NoIntersection): + /*If we have correct lines this means lines lie on a line.*/ + points.append(bigLine1.p2()); + return points; + break; + default: + break; + } + return points; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<QPointF> VAbstractPiece::AngleByLength(const QPointF &p2, const QPointF &sp1, const QPointF &sp2, + const QPointF &sp3, qreal width) +{ + QVector<QPointF> points; + + QLineF line(p2, sp2); + const qreal length = line.length(); + if (length > width*maxL) + { // Cutting too long a cut angle + line.setLength(width); + QLineF cutLine(line.p2(), sp2); // Cut line is a perpendicular + cutLine.setLength(length); // Decided take this length + + // We do not check intersection type because intersection must alwayse exist + QPointF px; + cutLine.setAngle(cutLine.angle()+90); + QLineF::IntersectType type = QLineF(sp1, sp2).intersect(cutLine, &px); + if (type == QLineF::NoIntersection) + { + qDebug()<<"Couldn't find intersection with cut line."; + } + points.append(px); + + cutLine.setAngle(cutLine.angle()-180); + type = QLineF(sp2, sp3).intersect(cutLine, &px); + if (type == QLineF::NoIntersection) + { + qDebug()<<"Couldn't find intersection with cut line."; + } + points.append(px); + } + else + { // The point just fine + points.append(sp2); + } + return points; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<QPointF> VAbstractPiece::AngleByIntersection(const QPointF &p1, const QPointF &p2, const QPointF &p3, + const QPointF &sp1, const QPointF &sp2, const QPointF &sp3, + qreal width) +{ + QVector<QPointF> points; + + QLineF edge2(p2, p3); + QLineF sEdge1(sp1, sp2); + + QPointF px; + QLineF::IntersectType type = edge2.intersect(sEdge1, &px); + if (type == QLineF::NoIntersection) + { + return AngleByLength(p2, sp1, sp2, sp3, width); + } + + if (QLineF(p2, px).length() > width*maxL) + { + return AngleByLength(p2, sp1, sp2, sp3, width); + } + points.append(px); + + QLineF edge1(p1, p2); + QLineF sEdge2(sp2, sp3); + + type = edge1.intersect(sEdge2, &px); + if (type == QLineF::NoIntersection) + { + return AngleByLength(p2, sp1, sp2, sp3, width); + } + + if (QLineF(p2, px).length() > width*maxL) + { + return AngleByLength(p2, sp1, sp2, sp3, width); + } + points.append(px); + + return points; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<QPointF> VAbstractPiece::AngleByFirstSymmetry(const QPointF &p1, const QPointF &p2, + const QPointF &sp1, const QPointF &sp2, const QPointF &sp3, + qreal width) +{ + QVector<QPointF> points; + + QLineF sEdge2(sp2, sp3); + QPointF fp1 = VPointF::FlipPF(sEdge2, p1); + QPointF fp2 = VPointF::FlipPF(sEdge2, p2); + QLineF fEdge(fp1, fp2); + + QPointF px; + QLineF sEdge1(sp1, sp2); + QLineF::IntersectType type = fEdge.intersect(sEdge1, &px); + if (type == QLineF::NoIntersection) + { + return AngleByLength(p2, sp1, sp2, sp3, width); + } + + if (QLineF(p2, px).length() > width*maxL) + { + return AngleByLength(p2, sp1, sp2, sp3, width); + } + points.append(px); + + type = fEdge.intersect(sEdge2, &px); + if (type == QLineF::NoIntersection) + { + return AngleByLength(p2, sp1, sp2, sp3, width); + } + + if (QLineF(p2, px).length() > width*maxL) + { + return AngleByLength(p2, sp1, sp2, sp3, width); + } + points.append(px); + + return points; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<QPointF> VAbstractPiece::AngleBySecondSymmetry(const QPointF &p2, const QPointF &p3, + const QPointF &sp1, const QPointF &sp2, const QPointF &sp3, + qreal width) +{ + QVector<QPointF> points; + + QLineF sEdge1(sp1, sp2); + QPointF fp2 = VPointF::FlipPF(sEdge1, p2); + QPointF fp3 = VPointF::FlipPF(sEdge1, p3); + QLineF fEdge(fp2, fp3); + + QPointF px; + QLineF::IntersectType type = fEdge.intersect(sEdge1, &px); + if (type == QLineF::NoIntersection) + { + return AngleByLength(p2, sp1, sp2, sp3, width); + } + + if (QLineF(p2, px).length() > width*maxL) + { + return AngleByLength(p2, sp1, sp2, sp3, width); + } + points.append(px); + + QLineF sEdge2(sp2, sp3); + type = fEdge.intersect(sEdge2, &px); + if (type == QLineF::NoIntersection) + { + return AngleByLength(p2, sp1, sp2, sp3, width); + } + + if (QLineF(p2, px).length() > width*maxL) + { + return AngleByLength(p2, sp1, sp2, sp3, width); + } + points.append(px); + + return points; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<QPointF> VAbstractPiece::AngleByFirstRightAngle(const QPointF &p1, const QPointF &p2, + const QPointF &sp1, const QPointF &sp2, const QPointF &sp3, + qreal width) +{ + QVector<QPointF> points; + + QLineF edge1(p2, p1); + edge1.setAngle(edge1.angle()-90); + + QPointF px; + QLineF::IntersectType type = edge1.intersect(QLineF(sp1, sp2), &px); + if (type == QLineF::NoIntersection) + { + return AngleByLength(p2, sp1, sp2, sp3, width); + } + + if (QLineF(p2, px).length() > width*maxL) + { + return AngleByLength(p2, sp1, sp2, sp3, width); + } + points.append(px); + + type = edge1.intersect(QLineF(sp2, sp3), &px); + if (type == QLineF::NoIntersection) + { + return AngleByLength(p2, sp1, sp2, sp3, width); + } + + if (QLineF(p2, px).length() > width*maxL) + { + return AngleByLength(p2, sp1, sp2, sp3, width); + } + points.append(px); + + return points; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<QPointF> VAbstractPiece::AngleBySecondRightAngle(const QPointF &p2, const QPointF &p3, + const QPointF &sp1, const QPointF &sp2, const QPointF &sp3, + qreal width) +{ + QVector<QPointF> points; + + QLineF edge2(p2, p3); + edge2.setAngle(edge2.angle()+90); + + QPointF px; + QLineF::IntersectType type = edge2.intersect(QLineF(sp1, sp2), &px); + if (type == QLineF::NoIntersection) + { + return AngleByLength(p2, sp1, sp2, sp3, width); + } + + if (QLineF(p2, px).length() > width*maxL) + { + return AngleByLength(p2, sp1, sp2, sp3, width); + } + points.append(px); + + type = edge2.intersect(QLineF(sp2, sp3), &px); + if (type == QLineF::NoIntersection) + { + return AngleByLength(p2, sp1, sp2, sp3, width); + } + + if (QLineF(p2, px).length() > width*maxL) + { + return AngleByLength(p2, sp1, sp2, sp3, width); + } + points.append(px); + + return points; +} + +//--------------------------------------------------------------------------------------------------------------------- +QLineF VAbstractPiece::ParallelLine(const VSAPoint &p1, const VSAPoint &p2, qreal width) +{ + qreal w1 = p1.GetSAAfter(); + if (w1 < 0) + { + w1 = width; + } + + qreal w2 = p2.GetSABefore(); + if (w2 < 0) + { + w2 = width; + } + + const QLineF paralel = QLineF(SingleParallelPoint(p1, p2, 90, w1), + SingleParallelPoint(p2, p1, -90, w2)); + return paralel; +} + +//--------------------------------------------------------------------------------------------------------------------- +QLineF VAbstractPiece::ParallelLine(const QPointF &p1, const QPointF &p2, qreal width) +{ + const QLineF paralel = QLineF(SingleParallelPoint(p1, p2, 90, width), + SingleParallelPoint(p2, p1, -90, width)); + return paralel; +} + +//--------------------------------------------------------------------------------------------------------------------- +QPointF VAbstractPiece::SingleParallelPoint(const QPointF &p1, const QPointF &p2, qreal angle, qreal width) +{ + QLineF pLine(p1, p2); + pLine.setAngle( pLine.angle() + angle ); + pLine.setLength( width ); + return pLine.p2(); +} + +//--------------------------------------------------------------------------------------------------------------------- +QLineF VAbstractPiece::BisectorLine(const QPointF &p1, const QPointF &p2, const QPointF &p3) +{ + QLineF line1(p2, p1); + QLineF line2(p2, p3); + QLineF bLine; + + const qreal angle1 = line1.angleTo(line2); + const qreal angle2 = line2.angleTo(line1); + + if (angle1 <= angle2) + { + bLine = line1; + bLine.setAngle(bLine.angle() + angle1/2.0); + } + else + { + bLine = line2; + bLine.setAngle(bLine.angle() + angle2/2.0); + } + + return bLine; +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal VAbstractPiece::AngleBetweenBisectors(const QLineF &b1, const QLineF &b2) +{ + const QLineF newB2 = b2.translated(-(b2.p1().x() - b1.p1().x()), -(b2.p1().y() - b1.p1().y())); + + qreal angle1 = newB2.angleTo(b1); + if (VFuzzyComparePossibleNulls(angle1, 360)) + { + angle1 = 0; + } + + qreal angle2 = b1.angleTo(newB2); + if (VFuzzyComparePossibleNulls(angle2, 360)) + { + angle2 = 0; + } + + if (angle1 <= angle2) + { + return angle1; + } + else + { + return angle2; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +bool VAbstractPiece::CheckIntersection(const QVector<QPointF> &points, int i, int iNext, int j, int jNext, + const QPointF &crossPoint) +{ + QVector<QPointF> sub1 = SubPath(points, iNext, j); + sub1.append(crossPoint); + sub1 = CheckLoops(CorrectEquidistantPoints(sub1, false)); + const qreal sub1Sum = SumTrapezoids(sub1); + + QVector<QPointF> sub2 = SubPath(points, jNext, i); + sub2.append(crossPoint); + sub2 = CheckLoops(CorrectEquidistantPoints(sub2, false)); + const qreal sub2Sum = SumTrapezoids(sub2); + + if (sub1Sum < 0 && sub2Sum < 0) + { + if (Crossing(sub1, sub2)) + { + return true; + } + } + else + { + if (not Crossing(sub1, sub2)) + { + return true; + } + } + return false; +} + +//--------------------------------------------------------------------------------------------------------------------- +bool VAbstractPiece::ParallelCrossPoint(const QLineF &line1, const QLineF &line2, QPointF &point) +{ + const bool l1p1el2p1 = (line1.p1() == line2.p1()); + const bool l1p2el2p2 = (line1.p2() == line2.p2()); + const bool l1p1el2p2 = (line1.p1() == line2.p2()); + const bool l1p2el2p1 = (line1.p2() == line2.p1()); + + if (l1p2el2p2 || l1p2el2p1) + { + point = line1.p2(); + return true; + } + else if (l1p1el2p1 || l1p1el2p2) + { + point = line1.p1(); + return true; + } + else + { + point = QPointF(); + return false; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +bool VAbstractPiece::Crossing(const QVector<QPointF> &sub1, const QVector<QPointF> &sub2) +{ + if (sub1.isEmpty() || sub2.isEmpty()) + { + return false; + } + + const QRectF sub1Rect = QPolygonF(sub1).boundingRect(); + const QRectF sub2Rect = QPolygonF(sub2).boundingRect(); + if (not sub1Rect.intersects(sub2Rect)) + { + return false; + } + + QPainterPath sub1Path; + sub1Path.setFillRule(Qt::WindingFill); + sub1Path.moveTo(sub1.at(0)); + for (qint32 i = 1; i < sub1.count(); ++i) + { + sub1Path.lineTo(sub1.at(i)); + } + sub1Path.lineTo(sub1.at(0)); + + QPainterPath sub2Path; + sub2Path.setFillRule(Qt::WindingFill); + sub2Path.moveTo(sub2.at(0)); + for (qint32 i = 1; i < sub2.count(); ++i) + { + sub2Path.lineTo(sub2.at(i)); + } + sub2Path.lineTo(sub2.at(0)); + + if (not sub1Path.intersects(sub2Path)) + { + return false; + } + else + { + return true; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<QPointF> VAbstractPiece::SubPath(const QVector<QPointF> &path, int startIndex, int endIndex) +{ + if (path.isEmpty() + || startIndex < 0 || startIndex >= path.size() + || endIndex < 0 || endIndex >= path.size() + || startIndex == endIndex) + { + return path; + } + + QVector<QPointF> subPath; + int i = startIndex - 1; + do + { + ++i; + if (i >= path.size()) + { + i = 0; + } + subPath.append(path.at(i)); + } while (i != endIndex); + + return subPath; +} diff --git a/src/libs/vlayout/vabstractpiece.h b/src/libs/vlayout/vabstractpiece.h new file mode 100644 index 000000000..a6b0a8dc5 --- /dev/null +++ b/src/libs/vlayout/vabstractpiece.h @@ -0,0 +1,309 @@ +/************************************************************************ + ** + ** @file + ** @author Roman Telezhynskyi <dismine(at)gmail.com> + ** @date 3 11, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2016 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#ifndef VABSTRACTPIECE_H +#define VABSTRACTPIECE_H + +#include <QtGlobal> +#include <QSharedDataPointer> +#include <QPointF> +#include <QDebug> + +#include "../vmisc/diagnostic.h" +#include "../vmisc/def.h" +#include "../vgeometry/vgobject.h" + +template <class T> class QVector; + +class VAbstractPieceData; +class QLineF; + +QT_WARNING_PUSH +QT_WARNING_DISABLE_GCC("-Weffc++") + +/** + * @brief The VSAPoint class seam allowance point + */ +class VSAPoint : public QPointF +{ +public: + Q_DECL_CONSTEXPR VSAPoint(); + Q_DECL_CONSTEXPR VSAPoint(qreal xpos, qreal ypos); + Q_DECL_CONSTEXPR explicit VSAPoint(const QPointF &p); + + Q_DECL_CONSTEXPR qreal GetSABefore() const; + void SetSABefore(qreal value); + + Q_DECL_CONSTEXPR qreal GetSAAfter() const; + void SetSAAfter(qreal value); + + Q_DECL_CONSTEXPR PieceNodeAngle GetAngleType() const; + void SetAngleType(PieceNodeAngle value); + +private: + qreal m_before; + qreal m_after; + PieceNodeAngle m_angle; +}; + +Q_DECLARE_METATYPE(VSAPoint) +Q_DECLARE_TYPEINFO(VSAPoint, Q_MOVABLE_TYPE); + +//--------------------------------------------------------------------------------------------------------------------- +Q_DECL_CONSTEXPR inline VSAPoint::VSAPoint() + : QPointF(), + m_before(-1), + m_after(-1), + m_angle(PieceNodeAngle::ByLength) +{} + +//--------------------------------------------------------------------------------------------------------------------- +Q_DECL_CONSTEXPR inline VSAPoint::VSAPoint(qreal xpos, qreal ypos) + : QPointF(xpos, ypos), + m_before(-1), + m_after(-1), + m_angle(PieceNodeAngle::ByLength) +{} + +//--------------------------------------------------------------------------------------------------------------------- +Q_DECL_CONSTEXPR inline VSAPoint::VSAPoint(const QPointF &p) + : QPointF(p), + m_before(-1), + m_after(-1), + m_angle(PieceNodeAngle::ByLength) +{} + +//--------------------------------------------------------------------------------------------------------------------- +Q_DECL_CONSTEXPR inline qreal VSAPoint::GetSABefore() const +{ + return m_before; +} + +//--------------------------------------------------------------------------------------------------------------------- +inline void VSAPoint::SetSABefore(qreal value) +{ + value < 0 ? m_before = -1 : m_before = value; +} + +//--------------------------------------------------------------------------------------------------------------------- +Q_DECL_CONSTEXPR inline qreal VSAPoint::GetSAAfter() const +{ + return m_after; +} + +//--------------------------------------------------------------------------------------------------------------------- +inline void VSAPoint::SetSAAfter(qreal value) +{ + value < 0 ? m_after = -1 : m_after = value; +} + +//--------------------------------------------------------------------------------------------------------------------- +Q_DECL_CONSTEXPR inline PieceNodeAngle VSAPoint::GetAngleType() const +{ + return m_angle; +} + +//--------------------------------------------------------------------------------------------------------------------- +inline void VSAPoint::SetAngleType(PieceNodeAngle value) +{ + m_angle = value; +} + +QT_WARNING_POP + +class VAbstractPiece +{ +public: + VAbstractPiece(); + VAbstractPiece(const VAbstractPiece &piece); + VAbstractPiece &operator=(const VAbstractPiece &piece); + virtual ~VAbstractPiece(); + + QString GetName() const; + void SetName(const QString &value); + + bool IsForbidFlipping() const; + void SetForbidFlipping(bool value); + + bool IsSeamAllowance() const; + void SetSeamAllowance(bool value); + + qreal GetSAWidth() const; + void SetSAWidth(qreal value); + + static QVector<QPointF> Equidistant(const QVector<VSAPoint> &points, qreal width); + static qreal SumTrapezoids(const QVector<QPointF> &points); + static QVector<QPointF> CheckLoops(const QVector<QPointF> &points); + + template <class T> + static QVector<T> CorrectEquidistantPoints(const QVector<T> &points, bool removeFirstAndLast = true); + +protected: + template <class T> + static QVector<T> RemoveDublicates(const QVector<T> &points, bool removeFirstAndLast = true); + +private: + QSharedDataPointer<VAbstractPieceData> d; + + static bool CheckIntersection(const QVector<QPointF> &points, int i, int iNext, int j, int jNext, + const QPointF &crossPoint); + static bool ParallelCrossPoint(const QLineF &line1, const QLineF &line2, QPointF &point); + static bool Crossing(const QVector<QPointF> &sub1, const QVector<QPointF> &sub2); + static QVector<QPointF> SubPath(const QVector<QPointF> &path, int startIndex, int endIndex); + static Q_DECL_CONSTEXPR qreal PointPosition(const QPointF &p, const QLineF &line); + static qreal MaxLocalSA(const VSAPoint &p, qreal width); + static QVector<QPointF> EkvPoint(const VSAPoint &p1Line1, const VSAPoint &p2Line1, + const VSAPoint &p1Line2, const VSAPoint &p2Line2, qreal width); + static QVector<QPointF> AngleByLength(const QPointF &p2, const QPointF &sp1, const QPointF &sp2, const QPointF &sp3, + qreal width); + static QVector<QPointF> AngleByIntersection(const QPointF &p1, const QPointF &p2, const QPointF &p3, + const QPointF &sp1, const QPointF &sp2, const QPointF &sp3, + qreal width); + static QVector<QPointF> AngleByFirstSymmetry(const QPointF &p1, const QPointF &p2, + const QPointF &sp1, const QPointF &sp2, const QPointF &sp3, + qreal width); + static QVector<QPointF> AngleBySecondSymmetry(const QPointF &p2, const QPointF &p3, + const QPointF &sp1, const QPointF &sp2, const QPointF &sp3, + qreal width); + static QVector<QPointF> AngleByFirstRightAngle(const QPointF &p1, const QPointF &p2, + const QPointF &sp1, const QPointF &sp2, const QPointF &sp3, + qreal width); + static QVector<QPointF> AngleBySecondRightAngle(const QPointF &p2, const QPointF &p3, + const QPointF &sp1, const QPointF &sp2, const QPointF &sp3, + qreal width); + static QLineF ParallelLine(const VSAPoint &p1, const VSAPoint &p2, qreal width); + static QLineF ParallelLine(const QPointF &p1, const QPointF &p2, qreal width); + static QPointF SingleParallelPoint(const QPointF &p1, const QPointF &p2, qreal angle, qreal width); + static QLineF BisectorLine(const QPointF &p1, const QPointF &p2, const QPointF &p3); + static qreal AngleBetweenBisectors(const QLineF &b1, const QLineF &b2); +}; + +Q_DECLARE_TYPEINFO(VAbstractPiece, Q_MOVABLE_TYPE); + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief CorrectEquidistantPoints clear equivalent points and remove point on line from equdistant. + * @param points list of points equdistant. + * @return corrected list. + */ +template <class T> +QVector<T> VAbstractPiece::CorrectEquidistantPoints(const QVector<T> &points, bool removeFirstAndLast) +{ + if (points.size()<4)//Better don't check if only three points. We can destroy equidistant. + { + qDebug()<<"Only three points."; + return points; + } + + //Clear equivalent points + QVector<T> buf1 = RemoveDublicates(points, removeFirstAndLast); + + if (buf1.size()<3) + { + return buf1; + } + + QVector<T> buf2; + //Remove point on line + for (qint32 i = 0; i < buf1.size(); ++i) + {// In this case we alwayse will have bounded intersection, so all is need is to check if point i is on line. + // Unfortunatelly QLineF::intersect can't be used in this case because of the floating-point accuraccy problem. + int prev = i-1; + int next = i+1; + if (i == 0) + { + prev = buf1.size() - 1; + } + else if (i == buf1.size() - 1) + { + next = 0; + } + + const QPointF &iPoint = buf1.at(i); + const QPointF &prevPoint = buf1.at(prev); + const QPointF &nextPoint = buf1.at(next); + + if (not VGObject::IsPointOnLineviaPDP(buf1.at(i), buf1.at(prev), buf1.at(next)) + && prevPoint != nextPoint) // not zigzag + { + buf2.append(buf1.at(i)); + } + else if ((i == 0 || i == buf1.size() - 1) && (iPoint == prevPoint || iPoint == nextPoint)) + { + // If RemoveDublicates does not remove these points it is a valid case. + // Case where last point equal first point + buf2.append(buf1.at(i)); + } + } + + buf2 = RemoveDublicates(buf2, false); + + return buf2; +} + +//--------------------------------------------------------------------------------------------------------------------- +template <class T> +QVector<T> VAbstractPiece::RemoveDublicates(const QVector<T> &points, bool removeFirstAndLast) +{ + QVector<T> p = points; + + if (removeFirstAndLast) + { + if (not p.isEmpty() && p.size() > 1) + { + // Path can't be closed + if (p.first() == p.last()) + { + #if QT_VERSION < QT_VERSION_CHECK(5, 1, 0) + p.remove(p.size() - 1); + #else + p.removeLast(); + #endif + } + } + } + + for (int i = 0; i < p.size()-1; ++i) + { + if (p.at(i) == p.at(i+1)) + { + if (not removeFirstAndLast && (i == p.size()-1)) + { + continue; + } + + p.erase(p.begin() + i + 1); + --i; + continue; + } + } + + return p; +} + +#endif // VABSTRACTPIECE_H diff --git a/src/libs/vlayout/vabstractdetail_p.h b/src/libs/vlayout/vabstractpiece_p.h similarity index 53% rename from src/libs/vlayout/vabstractdetail_p.h rename to src/libs/vlayout/vabstractpiece_p.h index 54fded0b3..c99abd5c0 100644 --- a/src/libs/vlayout/vabstractdetail_p.h +++ b/src/libs/vlayout/vabstractpiece_p.h @@ -1,14 +1,14 @@ /************************************************************************ ** - ** @file vabstractdetail_p.h + ** @file ** @author Roman Telezhynskyi <dismine(at)gmail.com> - ** @date 2 1, 2015 + ** @date 9 11, 2016 ** ** @brief ** @copyright ** This source code is part of the Valentine project, a pattern making ** program, whose allow create and modeling patterns of clothing. - ** Copyright (C) 2013-2015 Valentina project + ** Copyright (C) 2016 Valentina project ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. ** ** Valentina is free software: you can redistribute it and/or modify @@ -26,50 +26,53 @@ ** *************************************************************************/ -#ifndef VABSTRACTDETAIL_P_H -#define VABSTRACTDETAIL_P_H +#ifndef VABSTRACTPIECE_P_H +#define VABSTRACTPIECE_P_H #include <QSharedData> #include <QString> +#include <QCoreApplication> #include "../vmisc/diagnostic.h" QT_WARNING_PUSH QT_WARNING_DISABLE_GCC("-Weffc++") -class VAbstractDetailData : public QSharedData +class VAbstractPieceData : public QSharedData { + Q_DECLARE_TR_FUNCTIONS(VAbstractPieceData) public: - VAbstractDetailData() - :name(QString()), seamAllowance(false), closed(true), width(0), forbidFlipping(false) + VAbstractPieceData() + : m_name(tr("Detail")), + m_forbidFlipping(false), + m_seamAllowance(false), + m_width(0) {} - explicit VAbstractDetailData(const QString &name) - :name(name), seamAllowance(false), closed(true), width(0), forbidFlipping(false) + VAbstractPieceData(const VAbstractPieceData &piece) + : QSharedData(piece), + m_name(piece.m_name), + m_forbidFlipping(piece.m_forbidFlipping), + m_seamAllowance(piece.m_seamAllowance), + m_width(piece.m_width) {} - VAbstractDetailData(const VAbstractDetailData &detail) - :QSharedData(detail), name(detail.name), seamAllowance(detail.seamAllowance), closed(detail.closed), - width(detail.width), forbidFlipping(detail.forbidFlipping) - {} + ~VAbstractPieceData(); - ~VAbstractDetailData() {} - - /** @brief name detail name. */ - QString name; - /** @brief seamAllowance status seamAllowance detail. */ - bool seamAllowance; - /** @brief closed status equdistant detail. */ - bool closed; - /** @brief width value seamAllowance in mm. */ - qreal width; + QString m_name; /** @brief forbidFlipping forbid piece be mirrored in a layout. */ - bool forbidFlipping; + bool m_forbidFlipping; + bool m_seamAllowance; + qreal m_width; private: - VAbstractDetailData &operator=(const VAbstractDetailData &) Q_DECL_EQ_DELETE; + VAbstractPieceData &operator=(const VAbstractPieceData &) Q_DECL_EQ_DELETE; }; +VAbstractPieceData::~VAbstractPieceData() +{} + QT_WARNING_POP -#endif // VABSTRACTDETAIL_P_H +#endif // VABSTRACTPIECE_P_H + diff --git a/src/libs/vlayout/vbank.cpp b/src/libs/vlayout/vbank.cpp index f28787391..9d889a9c7 100644 --- a/src/libs/vlayout/vbank.cpp +++ b/src/libs/vlayout/vbank.cpp @@ -32,7 +32,7 @@ #include "../vmisc/diagnostic.h" #include "../vmisc/logging.h" -#include "vlayoutdetail.h" +#include "vlayoutpiece.h" QT_WARNING_PUSH QT_WARNING_DISABLE_CLANG("-Wmissing-prototypes") @@ -52,7 +52,7 @@ QT_WARNING_POP //--------------------------------------------------------------------------------------------------------------------- VBank::VBank() - :details(QVector<VLayoutDetail>()), unsorted(QHash<int, qint64>()), big(QHash<int, qint64>()), + :details(QVector<VLayoutPiece>()), unsorted(QHash<int, qint64>()), big(QHash<int, qint64>()), middle(QHash<int, qint64>()), small(QHash<int, qint64>()), layoutWidth(0), caseType(Cases::CaseDesc), prepare(false), diagonal(0) {} @@ -71,7 +71,7 @@ void VBank::SetLayoutWidth(const qreal &value) } //--------------------------------------------------------------------------------------------------------------------- -void VBank::SetDetails(const QVector<VLayoutDetail> &details) +void VBank::SetDetails(const QVector<VLayoutPiece> &details) { this->details = details; Reset(); @@ -111,7 +111,7 @@ int VBank::GetTiket() } //--------------------------------------------------------------------------------------------------------------------- -VLayoutDetail VBank::GetDetail(int i) const +VLayoutPiece VBank::GetDetail(int i) const { if (i >= 0 && i < details.size()) { @@ -119,7 +119,7 @@ VLayoutDetail VBank::GetDetail(int i) const } else { - return VLayoutDetail(); + return VLayoutPiece(); } } @@ -191,7 +191,7 @@ bool VBank::Prepare() for (int i=0; i < details.size(); ++i) { details[i].SetLayoutWidth(layoutWidth); - details[i].SetLayoutAllowencePoints(); + details[i].SetLayoutAllowancePoints(); const qreal d = details.at(i).Diagonal(); if (d > diagonal) diff --git a/src/libs/vlayout/vbank.h b/src/libs/vlayout/vbank.h index 51cd7e312..340f034d2 100644 --- a/src/libs/vlayout/vbank.h +++ b/src/libs/vlayout/vbank.h @@ -43,7 +43,7 @@ #endif class QPointF; -class VLayoutDetail; +class VLayoutPiece; enum class Cases : char { CaseThreeGroup = 0, CaseTwoGroup, CaseDesc, UnknownCase}; @@ -55,9 +55,9 @@ public: qreal GetLayoutWidth() const; void SetLayoutWidth(const qreal &value); - void SetDetails(const QVector<VLayoutDetail> &details); + void SetDetails(const QVector<VLayoutPiece> &details); int GetTiket(); - VLayoutDetail GetDetail(int i) const; + VLayoutPiece GetDetail(int i) const; void Arranged(int i); void NotArranged(int i); @@ -74,7 +74,7 @@ public: private: Q_DISABLE_COPY(VBank) - QVector<VLayoutDetail> details; + QVector<VLayoutPiece> details; QHash<int, qint64> unsorted; QHash<int, qint64> big; diff --git a/src/libs/vlayout/vcontour.cpp b/src/libs/vlayout/vcontour.cpp index 03ae18dee..da72142cb 100644 --- a/src/libs/vlayout/vcontour.cpp +++ b/src/libs/vlayout/vcontour.cpp @@ -37,7 +37,7 @@ #include <Qt> #include "vcontour_p.h" -#include "vlayoutdetail.h" +#include "vlayoutpiece.h" #include "../vmisc/vmath.h" //--------------------------------------------------------------------------------------------------------------------- @@ -125,7 +125,7 @@ QSizeF VContour::GetSize() const } //--------------------------------------------------------------------------------------------------------------------- -QVector<QPointF> VContour::UniteWithContour(const VLayoutDetail &detail, int globalI, int detJ, BestFrom type) const +QVector<QPointF> VContour::UniteWithContour(const VLayoutPiece &detail, int globalI, int detJ, BestFrom type) const { QVector<QPointF> newContour; if (d->globalContour.isEmpty()) //-V807 @@ -333,7 +333,7 @@ QPainterPath VContour::ContourPath() const } //--------------------------------------------------------------------------------------------------------------------- -void VContour::AppendWhole(QVector<QPointF> &contour, const VLayoutDetail &detail, int detJ) const +void VContour::AppendWhole(QVector<QPointF> &contour, const VLayoutPiece &detail, int detJ) const { int processedEdges = 0; const int nD = detail.LayoutEdgesCount(); diff --git a/src/libs/vlayout/vcontour.h b/src/libs/vlayout/vcontour.h index baa64f963..cfa622da4 100644 --- a/src/libs/vlayout/vcontour.h +++ b/src/libs/vlayout/vcontour.h @@ -43,7 +43,7 @@ class QPointF; class QRectF; class QSizeF; class VContourData; -class VLayoutDetail; +class VLayoutPiece; class VContour { @@ -68,7 +68,7 @@ public: QSizeF GetSize() const; - QVector<QPointF> UniteWithContour(const VLayoutDetail &detail, int globalI, int detJ, BestFrom type) const; + QVector<QPointF> UniteWithContour(const VLayoutPiece &detail, int globalI, int detJ, BestFrom type) const; QLineF EmptySheetEdge() const; int GlobalEdgesCount() const; @@ -85,7 +85,7 @@ public: private: QSharedDataPointer<VContourData> d; - void AppendWhole(QVector<QPointF> &contour, const VLayoutDetail &detail, int detJ) const; + void AppendWhole(QVector<QPointF> &contour, const VLayoutPiece &detail, int detJ) const; }; Q_DECLARE_TYPEINFO(VContour, Q_MOVABLE_TYPE); diff --git a/src/libs/vlayout/vgraphicsfillitem.cpp b/src/libs/vlayout/vgraphicsfillitem.cpp index d619b1278..e29fbb5b0 100644 --- a/src/libs/vlayout/vgraphicsfillitem.cpp +++ b/src/libs/vlayout/vgraphicsfillitem.cpp @@ -29,8 +29,8 @@ #include "vgraphicsfillitem.h" //--------------------------------------------------------------------------------------------------------------------- -VGraphicsFillItem::VGraphicsFillItem() - :QGraphicsPathItem() +VGraphicsFillItem::VGraphicsFillItem(QGraphicsItem *parent) + :QGraphicsPathItem(parent) {} //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/vlayout/vgraphicsfillitem.h b/src/libs/vlayout/vgraphicsfillitem.h index 467d62e12..564e36986 100644 --- a/src/libs/vlayout/vgraphicsfillitem.h +++ b/src/libs/vlayout/vgraphicsfillitem.h @@ -38,7 +38,7 @@ public: /** * @brief VGraphicsFillItem Constructor */ - VGraphicsFillItem(); + explicit VGraphicsFillItem(QGraphicsItem *parent = nullptr); /** * @brief ~VGraphicsFillItem Destructor */ diff --git a/src/libs/vlayout/vlayout.pri b/src/libs/vlayout/vlayout.pri index 6d82d469f..11a46ad9c 100644 --- a/src/libs/vlayout/vlayout.pri +++ b/src/libs/vlayout/vlayout.pri @@ -4,10 +4,6 @@ HEADERS += \ $$PWD/stable.h \ $$PWD/vlayoutgenerator.h \ - $$PWD/vlayoutdetail.h \ - $$PWD/vabstractdetail.h \ - $$PWD/vabstractdetail_p.h \ - $$PWD/vlayoutdetail_p.h \ $$PWD/vlayoutdef.h \ $$PWD/vlayoutpaper.h \ $$PWD/vlayoutpaper_p.h \ @@ -17,20 +13,24 @@ HEADERS += \ $$PWD/vbestsquare.h \ $$PWD/vposition.h \ $$PWD/vtextmanager.h \ - vposter.h \ - vgraphicsfillitem.h + $$PWD/vposter.h \ + $$PWD/vgraphicsfillitem.h \ + $$PWD/vabstractpiece.h \ + $$PWD/vabstractpiece_p.h \ + $$PWD/vlayoutpiece.h \ + $$PWD/vlayoutpiece_p.h SOURCES += \ $$PWD/vlayoutgenerator.cpp \ - $$PWD/vlayoutdetail.cpp \ - $$PWD/vabstractdetail.cpp \ $$PWD/vlayoutpaper.cpp \ $$PWD/vbank.cpp \ $$PWD/vcontour.cpp \ $$PWD/vbestsquare.cpp \ $$PWD/vposition.cpp \ $$PWD/vtextmanager.cpp \ - vposter.cpp \ - vgraphicsfillitem.cpp + $$PWD/vposter.cpp \ + $$PWD/vgraphicsfillitem.cpp \ + $$PWD/vabstractpiece.cpp \ + $$PWD/vlayoutpiece.cpp win32-msvc*:SOURCES += $$PWD/stable.cpp diff --git a/src/libs/vlayout/vlayoutdef.h b/src/libs/vlayout/vlayoutdef.h index 19fbcc297..d302fd957 100644 --- a/src/libs/vlayout/vlayoutdef.h +++ b/src/libs/vlayout/vlayoutdef.h @@ -33,8 +33,6 @@ #include <ciso646> #endif /* Q_CC_MSVC */ -enum class EquidistantType : char { OpenEquidistant, CloseEquidistant }; - enum class LayoutErrors : char { NoError, diff --git a/src/libs/vlayout/vlayoutgenerator.cpp b/src/libs/vlayout/vlayoutgenerator.cpp index cc374eed7..0117f04ee 100644 --- a/src/libs/vlayout/vlayoutgenerator.cpp +++ b/src/libs/vlayout/vlayoutgenerator.cpp @@ -34,7 +34,7 @@ #include "../vmisc/def.h" #include "../vmisc/vmath.h" -#include "vlayoutdetail.h" +#include "vlayoutpiece.h" #include "vlayoutpaper.h" class QMarginsF; @@ -54,7 +54,7 @@ VLayoutGenerator::~VLayoutGenerator() } //--------------------------------------------------------------------------------------------------------------------- -void VLayoutGenerator::SetDetails(const QVector<VLayoutDetail> &details) +void VLayoutGenerator::SetDetails(const QVector<VLayoutPiece> &details) { bank->SetDetails(details); } @@ -273,7 +273,7 @@ void VLayoutGenerator::GatherPages() return; } - QList<QList<VLayoutDetail>> nDetails; + QList<QList<VLayoutPiece>> nDetails; qreal length = 0; int j = 0; // papers count @@ -328,7 +328,7 @@ void VLayoutGenerator::UnitePages() } QList<qreal> papersLength; - QList<QList<VLayoutDetail> > nDetails; + QList<QList<VLayoutPiece> > nDetails; qreal length = 0; int j = 0; // papers count @@ -385,7 +385,7 @@ void VLayoutGenerator::UnitePages() } //--------------------------------------------------------------------------------------------------------------------- -void VLayoutGenerator::UniteDetails(int j, QList<QList<VLayoutDetail> > &nDetails, qreal length, int i) +void VLayoutGenerator::UniteDetails(int j, QList<QList<VLayoutPiece> > &nDetails, qreal length, int i) { if ((j == 0 && nDetails.isEmpty()) || j >= nDetails.size()) {//First or new details in paper @@ -411,17 +411,17 @@ void VLayoutGenerator::UnitePapers(int j, QList<qreal> &papersLength, qreal leng } //--------------------------------------------------------------------------------------------------------------------- -QList<VLayoutDetail> VLayoutGenerator::MoveDetails(qreal length, const QVector<VLayoutDetail> &details) +QList<VLayoutPiece> VLayoutGenerator::MoveDetails(qreal length, const QVector<VLayoutPiece> &details) { if (qFuzzyIsNull(length)) { return details.toList(); } - QList<VLayoutDetail> newDetails; + QList<VLayoutPiece> newDetails; for (int i = 0; i < details.size(); ++i) { - VLayoutDetail d = details.at(i); + VLayoutPiece d = details.at(i); d.Translate(0, length); newDetails.append(d); } diff --git a/src/libs/vlayout/vlayoutgenerator.h b/src/libs/vlayout/vlayoutgenerator.h index 90caa59bd..822e35658 100644 --- a/src/libs/vlayout/vlayoutgenerator.h +++ b/src/libs/vlayout/vlayoutgenerator.h @@ -50,7 +50,7 @@ class QMarginsF; #endif class QGraphicsItem; -class VLayoutDetail; +class VLayoutPiece; class VLayoutPaper; class VLayoutGenerator :public QObject @@ -60,7 +60,7 @@ public: explicit VLayoutGenerator(QObject *parent = nullptr); virtual ~VLayoutGenerator() Q_DECL_OVERRIDE; - void SetDetails(const QVector<VLayoutDetail> &details); + void SetDetails(const QVector<VLayoutPiece> &details); void SetLayoutWidth(qreal width); void SetCaseType(Cases caseType); int DetailsCount(); @@ -140,9 +140,9 @@ private: void GatherPages(); void UnitePages(); - void UniteDetails(int j, QList<QList<VLayoutDetail> > &nDetails, qreal length, int i); + void UniteDetails(int j, QList<QList<VLayoutPiece> > &nDetails, qreal length, int i); void UnitePapers(int j, QList<qreal> &papersLength, qreal length); - QList<VLayoutDetail> MoveDetails(qreal length, const QVector<VLayoutDetail> &details); + QList<VLayoutPiece> MoveDetails(qreal length, const QVector<VLayoutPiece> &details); }; typedef std::shared_ptr<VLayoutGenerator> VLayoutGeneratorPtr; diff --git a/src/libs/vlayout/vlayoutpaper.cpp b/src/libs/vlayout/vlayoutpaper.cpp index 3cd1b4b15..d3c21749c 100644 --- a/src/libs/vlayout/vlayoutpaper.cpp +++ b/src/libs/vlayout/vlayoutpaper.cpp @@ -45,7 +45,7 @@ #include "vbestsquare.h" #include "vcontour.h" -#include "vlayoutdetail.h" +#include "vlayoutpiece.h" #include "vlayoutpaper_p.h" #include "vposition.h" @@ -185,7 +185,7 @@ void VLayoutPaper::SetPaperIndex(quint32 index) } //--------------------------------------------------------------------------------------------------------------------- -bool VLayoutPaper::ArrangeDetail(const VLayoutDetail &detail, volatile bool &stop) +bool VLayoutPaper::ArrangeDetail(const VLayoutPiece &detail, volatile bool &stop) { // First need set size of paper if (d->globalContour.GetHeight() <= 0 || d->globalContour.GetWidth() <= 0) @@ -198,7 +198,7 @@ bool VLayoutPaper::ArrangeDetail(const VLayoutDetail &detail, volatile bool &sto return false;//Not enough edges } - if (detail.getForbidFlipping() && not d->globalRotate) + if (detail.IsForbidFlipping() && not d->globalRotate) { // Compensate forbidden flipping by rotating. 180 degree will be enough. d->localRotate = true; d->localRotationIncrease = 180; @@ -221,7 +221,7 @@ int VLayoutPaper::Count() const } //--------------------------------------------------------------------------------------------------------------------- -bool VLayoutPaper::AddToSheet(const VLayoutDetail &detail, volatile bool &stop) +bool VLayoutPaper::AddToSheet(const VLayoutPiece &detail, volatile bool &stop) { VBestSquare bestResult(d->globalContour.GetSize(), d->saveLength); QThreadPool *thread_pool = QThreadPool::globalInstance(); @@ -289,11 +289,11 @@ bool VLayoutPaper::AddToSheet(const VLayoutDetail &detail, volatile bool &stop) } //--------------------------------------------------------------------------------------------------------------------- -bool VLayoutPaper::SaveResult(const VBestSquare &bestResult, const VLayoutDetail &detail) +bool VLayoutPaper::SaveResult(const VBestSquare &bestResult, const VLayoutPiece &detail) { if (bestResult.ValidResult()) { - VLayoutDetail workDetail = detail; + VLayoutPiece workDetail = detail; workDetail.SetMatrix(bestResult.Matrix());// Don't forget set matrix workDetail.SetMirror(bestResult.Mirror()); const QVector<QPointF> newGContour = d->globalContour.UniteWithContour(workDetail, bestResult.GContourEdge(), @@ -354,28 +354,18 @@ QList<QGraphicsItem *> VLayoutPaper::GetItemDetails() const for (int i=0; i < d->details.count(); ++i) { list.append(d->details.at(i).GetItem()); - for (int iT = 0; iT < d->details.at(i).GetTextItemsCount(); ++iT) - { - list.append(d->details.at(i).GetTextItem(iT)); - } - - QGraphicsItem* pItem = d->details.at(i).GetGrainlineItem(); - if (pItem != 0) - { - list.append(pItem); - } } return list; } //--------------------------------------------------------------------------------------------------------------------- -QVector<VLayoutDetail> VLayoutPaper::GetDetails() const +QVector<VLayoutPiece> VLayoutPaper::GetDetails() const { return d->details; } //--------------------------------------------------------------------------------------------------------------------- -void VLayoutPaper::SetDetails(const QList<VLayoutDetail> &details) +void VLayoutPaper::SetDetails(const QList<VLayoutPiece> &details) { d->details = details.toVector(); } diff --git a/src/libs/vlayout/vlayoutpaper.h b/src/libs/vlayout/vlayoutpaper.h index 8c48a076d..7a28b8d74 100644 --- a/src/libs/vlayout/vlayoutpaper.h +++ b/src/libs/vlayout/vlayoutpaper.h @@ -40,7 +40,7 @@ class QGraphicsItem; class QGraphicsRectItem; class QRectF; class VBestSquare; -class VLayoutDetail; +class VLayoutPiece; class VLayoutPaperData; template <typename T> class QList; template <typename T> class QVector; @@ -77,22 +77,22 @@ public: void SetPaperIndex(quint32 index); - bool ArrangeDetail(const VLayoutDetail &detail, volatile bool &stop); + bool ArrangeDetail(const VLayoutPiece &detail, volatile bool &stop); int Count() const; QGraphicsRectItem *GetPaperItem(bool autoCrop) const Q_REQUIRED_RESULT; QList<QGraphicsItem *> GetItemDetails() const Q_REQUIRED_RESULT; - QVector<VLayoutDetail> GetDetails() const; - void SetDetails(const QList<VLayoutDetail>& details); + QVector<VLayoutPiece> GetDetails() const; + void SetDetails(const QList<VLayoutPiece>& details); QRectF DetailsBoundingRect() const; private: QSharedDataPointer<VLayoutPaperData> d; - bool AddToSheet(const VLayoutDetail &detail, volatile bool &stop); + bool AddToSheet(const VLayoutPiece &detail, volatile bool &stop); - bool SaveResult(const VBestSquare &bestResult, const VLayoutDetail &detail); + bool SaveResult(const VBestSquare &bestResult, const VLayoutPiece &detail); }; diff --git a/src/libs/vlayout/vlayoutpaper_p.h b/src/libs/vlayout/vlayoutpaper_p.h index 34ec699bf..81acb7a45 100644 --- a/src/libs/vlayout/vlayoutpaper_p.h +++ b/src/libs/vlayout/vlayoutpaper_p.h @@ -33,7 +33,7 @@ #include <QVector> #include <QPointF> -#include "vlayoutdetail.h" +#include "vlayoutpiece.h" #include "vcontour.h" QT_WARNING_PUSH @@ -43,7 +43,7 @@ class VLayoutPaperData : public QSharedData { public: VLayoutPaperData() - : details(QVector<VLayoutDetail>()), + : details(QVector<VLayoutPiece>()), globalContour(VContour()), paperIndex(0), frame(0), @@ -57,7 +57,7 @@ public: VLayoutPaperData(int height, int width) - : details(QVector<VLayoutDetail>()), + : details(QVector<VLayoutPiece>()), globalContour(VContour(height, width)), paperIndex(0), frame(0), @@ -86,7 +86,7 @@ public: ~VLayoutPaperData() {} /** @brief details list of arranged details. */ - QVector<VLayoutDetail> details; + QVector<VLayoutPiece> details; /** @brief globalContour list of global points contour. */ VContour globalContour; diff --git a/src/libs/vlayout/vlayoutdetail.cpp b/src/libs/vlayout/vlayoutpiece.cpp similarity index 74% rename from src/libs/vlayout/vlayoutdetail.cpp rename to src/libs/vlayout/vlayoutpiece.cpp index cb00675b7..e8585188e 100644 --- a/src/libs/vlayout/vlayoutdetail.cpp +++ b/src/libs/vlayout/vlayoutpiece.cpp @@ -26,7 +26,7 @@ ** *************************************************************************/ -#include "vlayoutdetail.h" +#include "vlayoutpiece.h" #include <QBrush> #include <QFlags> @@ -49,7 +49,7 @@ #include "../vmisc/vabstractapplication.h" #include "../vpatterndb/calculator.h" #include "vlayoutdef.h" -#include "vlayoutdetail_p.h" +#include "vlayoutpiece_p.h" #include "vtextmanager.h" #include "vgraphicsfillitem.h" @@ -58,79 +58,114 @@ class QLineF; class VAbstractPattern; //--------------------------------------------------------------------------------------------------------------------- -VLayoutDetail::VLayoutDetail() - :VAbstractDetail(), d(new VLayoutDetailData) +VLayoutPiece::VLayoutPiece() + :VAbstractPiece(), d(new VLayoutPieceData) {} //--------------------------------------------------------------------------------------------------------------------- -VLayoutDetail::VLayoutDetail(const VLayoutDetail &detail) - :VAbstractDetail(detail), d(detail.d) +VLayoutPiece::VLayoutPiece(const VLayoutPiece &detail) + :VAbstractPiece(detail), d(detail.d) {} //--------------------------------------------------------------------------------------------------------------------- -VLayoutDetail &VLayoutDetail::operator=(const VLayoutDetail &detail) +VLayoutPiece &VLayoutPiece::operator=(const VLayoutPiece &detail) { if ( &detail == this ) { return *this; } - VAbstractDetail::operator=(detail); + VAbstractPiece::operator=(detail); d = detail.d; return *this; } //--------------------------------------------------------------------------------------------------------------------- -VLayoutDetail::~VLayoutDetail() +VLayoutPiece::~VLayoutPiece() {} +//--------------------------------------------------------------------------------------------------------------------- +VLayoutPiece VLayoutPiece::Create(const VPiece &piece, const VContainer *pattern) +{ + VLayoutPiece det; + det.SetCountourPoints(piece.MainPathPoints(pattern)); + det.SetSeamAllowancePoints(piece.SeamAllowancePoints(pattern), piece.IsSeamAllowance()); + det.SetInternlaPathsPoints(piece.GetInternalPathsPoints(pattern)); + det.SetName(piece.GetName()); + const VPatternPieceData& data = piece.GetPatternPieceData(); + if (data.IsVisible() == true) + { + det.SetDetail(piece.GetName(), data, qApp->font()); + } + const VPatternInfoGeometry& geom = piece.GetPatternInfo(); + if (geom.IsVisible() == true) + { + VAbstractPattern* pDoc = qApp->getCurrentDocument(); + QDate date; + if (pDoc->IsDateVisible() == true) + { + date = QDate::currentDate(); + } + det.SetPatternInfo(pDoc, geom, qApp->font(), pattern->size(), pattern->height()); + } + const VGrainlineGeometry& grainlineGeom = piece.GetGrainlineGeometry(); + if (grainlineGeom.IsVisible() == true) + { + det.SetGrainline(grainlineGeom, *pattern); + } + det.SetSAWidth(qApp->toPixel(piece.GetSAWidth())); + det.CreateTextItems(); + det.SetForbidFlipping(piece.IsForbidFlipping()); + + return det; +} + //--------------------------------------------------------------------------------------------------------------------- // cppcheck-suppress unusedFunction -QVector<QPointF> VLayoutDetail::GetContourPoints() const +QVector<QPointF> VLayoutPiece::GetContourPoints() const { return Map(d->contour); } //--------------------------------------------------------------------------------------------------------------------- -void VLayoutDetail::SetCountourPoints(const QVector<QPointF> &points) +void VLayoutPiece::SetCountourPoints(const QVector<QPointF> &points) { - d->contour = RemoveDublicates(RoundPoints(points)); + d->contour = RemoveDublicates(RoundPoints(points), false); } //--------------------------------------------------------------------------------------------------------------------- // cppcheck-suppress unusedFunction -QVector<QPointF> VLayoutDetail::GetSeamAllowencePoints() const +QVector<QPointF> VLayoutPiece::GetSeamAllowancePoints() const { - return Map(d->seamAllowence); + return Map(d->seamAllowance); } //--------------------------------------------------------------------------------------------------------------------- -void VLayoutDetail::SetSeamAllowencePoints(const QVector<QPointF> &points, bool seamAllowence, bool closed) +void VLayoutPiece::SetSeamAllowancePoints(const QVector<QPointF> &points, bool seamAllowance) { - if (seamAllowence) + if (seamAllowance) { - setSeamAllowance(seamAllowence); - setClosed(closed); - d->seamAllowence = points; - if (not d->seamAllowence.isEmpty()) + SetSeamAllowance(seamAllowance); + d->seamAllowance = points; + if (not d->seamAllowance.isEmpty()) { - d->seamAllowence = RemoveDublicates(RoundPoints(d->seamAllowence)); + d->seamAllowance = RemoveDublicates(RoundPoints(d->seamAllowance), false); } else { qWarning()<<"Seam allowance is empty."; - setSeamAllowance(false); + SetSeamAllowance(false); } } } //--------------------------------------------------------------------------------------------------------------------- -QVector<QPointF> VLayoutDetail::GetLayoutAllowencePoints() const +QVector<QPointF> VLayoutPiece::GetLayoutAllowancePoints() const { - return Map(d->layoutAllowence); + return Map(d->layoutAllowance); } //--------------------------------------------------------------------------------------------------------------------- -void VLayoutDetail::SetDetail(const QString& qsName, const VPatternPieceData& data, const QFont &font) +void VLayoutPiece::SetDetail(const QString& qsName, const VPatternPieceData& data, const QFont &font) { d->detailData = data; qreal dAng = qDegreesToRadians(data.GetRotation()); @@ -156,7 +191,7 @@ void VLayoutDetail::SetDetail(const QString& qsName, const VPatternPieceData& da } //--------------------------------------------------------------------------------------------------------------------- -void VLayoutDetail::SetPatternInfo(const VAbstractPattern* pDoc, const VPatternInfoGeometry& geom, const QFont &font, +void VLayoutPiece::SetPatternInfo(const VAbstractPattern* pDoc, const VPatternInfoGeometry& geom, const QFont &font, qreal dSize, qreal dHeight) { d->patternGeom = geom; @@ -185,7 +220,7 @@ void VLayoutDetail::SetPatternInfo(const VAbstractPattern* pDoc, const VPatternI } //--------------------------------------------------------------------------------------------------------------------- -void VLayoutDetail::SetGrainline(const VGrainlineGeometry& geom, const VContainer& rPattern) +void VLayoutPiece::SetGrainline(const VGrainlineGeometry& geom, const VContainer& rPattern) { d->grainlineGeom = geom; qreal dAng; @@ -252,31 +287,31 @@ void VLayoutDetail::SetGrainline(const VGrainlineGeometry& geom, const VContaine } //--------------------------------------------------------------------------------------------------------------------- -QTransform VLayoutDetail::GetMatrix() const +QTransform VLayoutPiece::GetMatrix() const { return d->matrix; } //--------------------------------------------------------------------------------------------------------------------- -void VLayoutDetail::SetMatrix(const QTransform &matrix) +void VLayoutPiece::SetMatrix(const QTransform &matrix) { d->matrix = matrix; } //--------------------------------------------------------------------------------------------------------------------- -qreal VLayoutDetail::GetLayoutWidth() const +qreal VLayoutPiece::GetLayoutWidth() const { return d->layoutWidth; } //--------------------------------------------------------------------------------------------------------------------- -void VLayoutDetail::SetLayoutWidth(const qreal &value) +void VLayoutPiece::SetLayoutWidth(const qreal &value) { d->layoutWidth = value; } //--------------------------------------------------------------------------------------------------------------------- -void VLayoutDetail::Translate(qreal dx, qreal dy) +void VLayoutPiece::Translate(qreal dx, qreal dy) { QTransform m; m.translate(dx, dy); @@ -284,7 +319,7 @@ void VLayoutDetail::Translate(qreal dx, qreal dy) } //--------------------------------------------------------------------------------------------------------------------- -void VLayoutDetail::Rotate(const QPointF &originPoint, qreal degrees) +void VLayoutPiece::Rotate(const QPointF &originPoint, qreal degrees) { QTransform m; m.translate(originPoint.x(), originPoint.y()); @@ -294,7 +329,7 @@ void VLayoutDetail::Rotate(const QPointF &originPoint, qreal degrees) } //--------------------------------------------------------------------------------------------------------------------- -void VLayoutDetail::Mirror(const QLineF &edge) +void VLayoutPiece::Mirror(const QLineF &edge) { if (edge.isNull()) { @@ -327,48 +362,48 @@ void VLayoutDetail::Mirror(const QLineF &edge) } //--------------------------------------------------------------------------------------------------------------------- -int VLayoutDetail::DetailEdgesCount() const +int VLayoutPiece::DetailEdgesCount() const { return DetailPath().count(); } //--------------------------------------------------------------------------------------------------------------------- -int VLayoutDetail::LayoutEdgesCount() const +int VLayoutPiece::LayoutEdgesCount() const { - return d->layoutAllowence.count(); + return d->layoutAllowance.count(); } //--------------------------------------------------------------------------------------------------------------------- -QLineF VLayoutDetail::DetailEdge(int i) const +QLineF VLayoutPiece::DetailEdge(int i) const { return Edge(DetailPath(), i); } //--------------------------------------------------------------------------------------------------------------------- -QLineF VLayoutDetail::LayoutEdge(int i) const +QLineF VLayoutPiece::LayoutEdge(int i) const { - return Edge(d->layoutAllowence, i); + return Edge(d->layoutAllowance, i); } //--------------------------------------------------------------------------------------------------------------------- -int VLayoutDetail::DetailEdgeByPoint(const QPointF &p1) const +int VLayoutPiece::DetailEdgeByPoint(const QPointF &p1) const { return EdgeByPoint(DetailPath(), p1); } //--------------------------------------------------------------------------------------------------------------------- -int VLayoutDetail::LayoutEdgeByPoint(const QPointF &p1) const +int VLayoutPiece::LayoutEdgeByPoint(const QPointF &p1) const { - return EdgeByPoint(d->layoutAllowence, p1); + return EdgeByPoint(d->layoutAllowance, p1); } //--------------------------------------------------------------------------------------------------------------------- -QRectF VLayoutDetail::DetailBoundingRect() const +QRectF VLayoutPiece::DetailBoundingRect() const { QVector<QPointF> points; - if (getSeamAllowance()) + if (IsSeamAllowance()) { - points = GetSeamAllowencePoints(); + points = GetSeamAllowancePoints(); } else { @@ -380,26 +415,26 @@ QRectF VLayoutDetail::DetailBoundingRect() const } //--------------------------------------------------------------------------------------------------------------------- -QRectF VLayoutDetail::LayoutBoundingRect() const +QRectF VLayoutPiece::LayoutBoundingRect() const { - QVector<QPointF> points = GetLayoutAllowencePoints(); + QVector<QPointF> points = GetLayoutAllowancePoints(); points.append(points.first()); return QPolygonF(points).boundingRect(); } //--------------------------------------------------------------------------------------------------------------------- -qreal VLayoutDetail::Diagonal() const +qreal VLayoutPiece::Diagonal() const { const QRectF rec = LayoutBoundingRect(); return qSqrt(pow(rec.height(), 2) + pow(rec.width(), 2)); } //--------------------------------------------------------------------------------------------------------------------- -bool VLayoutDetail::isNull() const +bool VLayoutPiece::isNull() const { if (d->contour.isEmpty() == false && d->layoutWidth > 0) { - if (getSeamAllowance() && d->seamAllowence.isEmpty() == false) + if (IsSeamAllowance() && d->seamAllowance.isEmpty() == false) { return false; } @@ -415,58 +450,69 @@ bool VLayoutDetail::isNull() const } //--------------------------------------------------------------------------------------------------------------------- -qint64 VLayoutDetail::Square() const +qint64 VLayoutPiece::Square() const { - if (d->layoutAllowence.isEmpty()) //-V807 + if (d->layoutAllowance.isEmpty()) //-V807 { return 0; } - const qreal res = SumTrapezoids(d->layoutAllowence); + const qreal res = SumTrapezoids(d->layoutAllowance); const qint64 sq = qFloor(qAbs(res/2.0)); return sq; } //--------------------------------------------------------------------------------------------------------------------- -void VLayoutDetail::SetLayoutAllowencePoints() +void VLayoutPiece::SetLayoutAllowancePoints() { if (d->layoutWidth > 0) { - if (getSeamAllowance()) + if (IsSeamAllowance()) { - d->layoutAllowence = Equidistant(GetSeamAllowencePoints(), EquidistantType::CloseEquidistant, - d->layoutWidth); - if (d->layoutAllowence.isEmpty() == false) + d->layoutAllowance = Equidistant(PrepareAllowance(GetSeamAllowancePoints()), d->layoutWidth); + if (d->layoutAllowance.isEmpty() == false) { #if QT_VERSION < QT_VERSION_CHECK(5, 1, 0) - d->layoutAllowence.remove(d->layoutAllowence.size() - 1); + d->layoutAllowance.remove(d->layoutAllowance.size() - 1); #else - d->layoutAllowence.removeLast(); + d->layoutAllowance.removeLast(); #endif } } else { - d->layoutAllowence = Equidistant(GetContourPoints(), EquidistantType::CloseEquidistant, d->layoutWidth); - if (d->layoutAllowence.isEmpty() == false) + d->layoutAllowance = Equidistant(PrepareAllowance(GetContourPoints()), d->layoutWidth); + if (d->layoutAllowance.isEmpty() == false) { #if QT_VERSION < QT_VERSION_CHECK(5, 1, 0) - d->layoutAllowence.remove(d->layoutAllowence.size() - 1); + d->layoutAllowance.remove(d->layoutAllowance.size() - 1); #else - d->layoutAllowence.removeLast(); + d->layoutAllowance.removeLast(); #endif } } } else { - d->layoutAllowence.clear(); + d->layoutAllowance.clear(); } } //--------------------------------------------------------------------------------------------------------------------- -QVector<QPointF> VLayoutDetail::Map(const QVector<QPointF> &points) const +QVector<QVector<QPointF>> VLayoutPiece::GetInternlaPathsPoints() const +{ + return d->m_internalPaths; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VLayoutPiece::SetInternlaPathsPoints(const QVector<QVector<QPointF>> &internalPathsPoints) +{ + d->m_internalPaths = internalPathsPoints; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<QPointF> VLayoutPiece::Map(const QVector<QPointF> &points) const { QVector<QPointF> p; for (int i = 0; i < points.size(); ++i) @@ -487,7 +533,7 @@ QVector<QPointF> VLayoutDetail::Map(const QVector<QPointF> &points) const } //--------------------------------------------------------------------------------------------------------------------- -QVector<QPointF> VLayoutDetail::RoundPoints(const QVector<QPointF> &points) +QVector<QPointF> VLayoutPiece::RoundPoints(const QVector<QPointF> &points) { QVector<QPointF> p; for (int i=0; i < points.size(); ++i) @@ -498,7 +544,7 @@ QVector<QPointF> VLayoutDetail::RoundPoints(const QVector<QPointF> &points) } //--------------------------------------------------------------------------------------------------------------------- -QPainterPath VLayoutDetail::ContourPath() const +QPainterPath VLayoutPiece::ContourPath() const { QPainterPath path; @@ -512,13 +558,13 @@ QPainterPath VLayoutDetail::ContourPath() const path.lineTo(points.at(0)); // seam allowance - if (getSeamAllowance() == true) + if (IsSeamAllowance() == true) { - points = GetSeamAllowencePoints(); + points = GetSeamAllowancePoints(); - if (getClosed() == true) + if (points.last().toPoint() != points.first().toPoint()) { - points.append(points.at(0)); + points.append(points.at(0));// Should be always closed } QPainterPath ekv; @@ -536,13 +582,13 @@ QPainterPath VLayoutDetail::ContourPath() const } //--------------------------------------------------------------------------------------------------------------------- -void VLayoutDetail::ClearTextItems() +void VLayoutPiece::ClearTextItems() { d->m_liPP.clear(); } //--------------------------------------------------------------------------------------------------------------------- -void VLayoutDetail::CreateTextItems() +void VLayoutPiece::CreateTextItems() { ClearTextItems(); // first add detail texts @@ -662,21 +708,17 @@ void VLayoutDetail::CreateTextItems() } } -//--------------------------------------------------------------------------------------------------------------------- -int VLayoutDetail::GetTextItemsCount() const -{ - return d->m_liPP.count(); -} - //--------------------------------------------------------------------------------------------------------------------- /** - * @brief VLayoutDetail::GetTextItem Creates and returns the i-th text item + * @brief CreateTextItem Creates the i-th text item * @param i index of the requested item - * @return pointer to the newly created item. The caller is responsible to delete it. + * @param parent parent of this text item. Can't be null. */ -QGraphicsItem* VLayoutDetail::GetTextItem(int i) const +void VLayoutPiece::CreateTextItem(int i, QGraphicsItem *parent) const { - QGraphicsPathItem* item = new QGraphicsPathItem(); + SCASSERT(parent != nullptr) + + QGraphicsPathItem* item = new QGraphicsPathItem(parent); QTransform transform = d->matrix; QPainterPath path = transform.map(d->m_liPP[i]); @@ -714,16 +756,15 @@ QGraphicsItem* VLayoutDetail::GetTextItem(int i) const item->setPath(path); item->setBrush(QBrush(Qt::black)); - return item; } //--------------------------------------------------------------------------------------------------------------------- -QPainterPath VLayoutDetail::LayoutAllowencePath() const +QPainterPath VLayoutPiece::LayoutAllowancePath() const { QPainterPath path; path.setFillRule(Qt::WindingFill); - const QVector<QPointF> points = GetLayoutAllowencePoints(); + const QVector<QPointF> points = GetLayoutAllowancePoints(); path.moveTo(points.at(0)); for (qint32 i = 1; i < points.count(); ++i) { @@ -735,21 +776,33 @@ QPainterPath VLayoutDetail::LayoutAllowencePath() const } //--------------------------------------------------------------------------------------------------------------------- -QGraphicsItem *VLayoutDetail::GetItem() const +QGraphicsItem *VLayoutPiece::GetItem() const { QGraphicsPathItem *item = new QGraphicsPathItem(); - item->setPath(ContourPath()); + QPainterPath contour = ContourPath(); + contour.addPath(InternalPathsPath()); + item->setPath(contour); + + for (int i = 0; i < d->m_liPP.count(); ++i) + { + CreateTextItem(i, item); + } + + CreateGrainlineItem(item); + return item; } //--------------------------------------------------------------------------------------------------------------------- -QGraphicsItem* VLayoutDetail::GetGrainlineItem() const +void VLayoutPiece::CreateGrainlineItem(QGraphicsItem *parent) const { + SCASSERT(parent != nullptr) + if (d->grainlinePoints.count() < 2) { - return 0; + return; } - VGraphicsFillItem* item = new VGraphicsFillItem(); + VGraphicsFillItem* item = new VGraphicsFillItem(parent); QPainterPath path; QVector<QPointF> v = Map(d->grainlinePoints); path.moveTo(v.at(0)); @@ -758,15 +811,37 @@ QGraphicsItem* VLayoutDetail::GetGrainlineItem() const path.lineTo(v.at(i)); } item->setPath(path); - return item; } //--------------------------------------------------------------------------------------------------------------------- -QVector<QPointF> VLayoutDetail::DetailPath() const +QPainterPath VLayoutPiece::InternalPathsPath() const { - if (getSeamAllowance()) + QPainterPath allPaths; + allPaths.setFillRule(Qt::WindingFill); + + for (qint32 i = 0; i < d->m_internalPaths.count(); ++i) { - return d->seamAllowence; + const QVector<QPointF> points = Map(d->m_internalPaths.at(i)); + QPainterPath path; + path.setFillRule(Qt::WindingFill); + path.moveTo(points.at(0)); + for (qint32 j = 1; j < points.count(); ++j) + { + path.lineTo(points.at(j)); + } + path.lineTo(points.at(0)); + allPaths.addPath(path); + } + + return allPaths; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<QPointF> VLayoutPiece::DetailPath() const +{ + if (IsSeamAllowance()) + { + return d->seamAllowance; } else { @@ -775,13 +850,24 @@ QVector<QPointF> VLayoutDetail::DetailPath() const } //--------------------------------------------------------------------------------------------------------------------- -bool VLayoutDetail::IsMirror() const +QVector<VSAPoint> VLayoutPiece::PrepareAllowance(const QVector<QPointF> &points) +{ + QVector<VSAPoint> allowancePoints; + for(int i = 0; i < points.size(); ++i) + { + allowancePoints.append(VSAPoint(points.at(i))); + } + return allowancePoints; +} + +//--------------------------------------------------------------------------------------------------------------------- +bool VLayoutPiece::IsMirror() const { return d->mirror; } //--------------------------------------------------------------------------------------------------------------------- -void VLayoutDetail::SetMirror(bool value) +void VLayoutPiece::SetMirror(bool value) { d->mirror = value; } @@ -794,7 +880,7 @@ void VLayoutDetail::SetMirror(bool value) * @param dAng angle of rotation * @return position of point pt after rotating it around the center for dAng radians */ -QPointF VLayoutDetail::RotatePoint(const QPointF &ptCenter, const QPointF& pt, qreal dAng) +QPointF VLayoutPiece::RotatePoint(const QPointF &ptCenter, const QPointF& pt, qreal dAng) { QPointF ptDest; QPointF ptRel = pt - ptCenter; @@ -811,7 +897,7 @@ QPointF VLayoutDetail::RotatePoint(const QPointF &ptCenter, const QPointF& pt, q * @param points list of 4 label vertices * @return list of flipped points */ -QVector<QPointF> VLayoutDetail::Mirror(const QVector<QPointF> &points) const +QVector<QPointF> VLayoutPiece::Mirror(const QVector<QPointF> &points) const { // should only call this method with rectangular shapes Q_ASSERT(points.count() == 4); @@ -836,7 +922,7 @@ QVector<QPointF> VLayoutDetail::Mirror(const QVector<QPointF> &points) const * @param pt2 second point * @return Euclidian distance between the two points */ -qreal VLayoutDetail::GetDistance(const QPointF &pt1, const QPointF &pt2) +qreal VLayoutPiece::GetDistance(const QPointF &pt1, const QPointF &pt2) { const qreal dX = pt1.x() - pt2.x(); const qreal dY = pt1.y() - pt2.y(); @@ -845,7 +931,7 @@ qreal VLayoutDetail::GetDistance(const QPointF &pt1, const QPointF &pt2) } //--------------------------------------------------------------------------------------------------------------------- -QLineF VLayoutDetail::Edge(const QVector<QPointF> &path, int i) const +QLineF VLayoutPiece::Edge(const QVector<QPointF> &path, int i) const { if (i < 1 || i > path.count()) { // Doesn't exist such edge @@ -879,7 +965,7 @@ QLineF VLayoutDetail::Edge(const QVector<QPointF> &path, int i) const } //--------------------------------------------------------------------------------------------------------------------- -int VLayoutDetail::EdgeByPoint(const QVector<QPointF> &path, const QPointF &p1) const +int VLayoutPiece::EdgeByPoint(const QVector<QPointF> &path, const QPointF &p1) const { if (p1.isNull()) { diff --git a/src/libs/vlayout/vlayoutdetail.h b/src/libs/vlayout/vlayoutpiece.h similarity index 77% rename from src/libs/vlayout/vlayoutdetail.h rename to src/libs/vlayout/vlayoutpiece.h index e23924dcf..5bd966a0a 100644 --- a/src/libs/vlayout/vlayoutdetail.h +++ b/src/libs/vlayout/vlayoutpiece.h @@ -45,7 +45,7 @@ #include "../vpatterndb/vpatterninfogeometry.h" #include "../vpatterndb/vpatternpiecedata.h" #include "../vpatterndb/vcontainer.h" -#include "vabstractdetail.h" +#include "vabstractpiece.h" class QFont; class QGraphicsItem; @@ -55,27 +55,32 @@ class QPointF; class QRectF; class QTransform; class VAbstractPattern; -class VLayoutDetailData; +class VLayoutPieceData; class VPatternInfoGeometry; class VPatternPieceData; class VGrainlineGeometry; -class VLayoutDetail :public VAbstractDetail +class VLayoutPiece :public VAbstractPiece { public: - VLayoutDetail(); - VLayoutDetail(const VLayoutDetail &detail); - VLayoutDetail &operator=(const VLayoutDetail &detail); - virtual ~VLayoutDetail() Q_DECL_OVERRIDE; + VLayoutPiece(); + VLayoutPiece(const VLayoutPiece &detail); + VLayoutPiece &operator=(const VLayoutPiece &detail); + virtual ~VLayoutPiece() Q_DECL_OVERRIDE; + + static VLayoutPiece Create(const VPiece &piece, const VContainer *pattern); QVector<QPointF> GetContourPoints() const; void SetCountourPoints(const QVector<QPointF> &points); - QVector<QPointF> GetSeamAllowencePoints() const; - void SetSeamAllowencePoints(const QVector<QPointF> &points, bool seamAllowence = true, bool closed = true); + QVector<QPointF> GetSeamAllowancePoints() const; + void SetSeamAllowancePoints(const QVector<QPointF> &points, bool seamAllowance = true); - QVector<QPointF> GetLayoutAllowencePoints() const; - void SetLayoutAllowencePoints(); + QVector<QPointF> GetLayoutAllowancePoints() const; + void SetLayoutAllowancePoints(); + + QVector<QVector<QPointF>> GetInternlaPathsPoints() const; + void SetInternlaPathsPoints(const QVector<QVector<QPointF>> &internalPathsPoints); void SetDetail(const QString &qsName, const VPatternPieceData& data, const QFont& font); @@ -113,19 +118,24 @@ public: bool isNull() const; qint64 Square() const; QPainterPath ContourPath() const; - void ClearTextItems(); - void CreateTextItems(); - int GetTextItemsCount() const Q_REQUIRED_RESULT; - QGraphicsItem* GetTextItem(int i) const Q_REQUIRED_RESULT; - QPainterPath LayoutAllowencePath() const; + + QPainterPath LayoutAllowancePath() const; QGraphicsItem *GetItem() const Q_REQUIRED_RESULT; - QGraphicsItem* GetGrainlineItem() const Q_REQUIRED_RESULT; private: - QSharedDataPointer<VLayoutDetailData> d; + QSharedDataPointer<VLayoutPieceData> d; QVector<QPointF> DetailPath() const; + void ClearTextItems(); + void CreateTextItems(); + + void CreateTextItem(int i, QGraphicsItem *parent) const; + void CreateGrainlineItem(QGraphicsItem *parent) const; + + QPainterPath InternalPathsPath() const; + + static QVector<VSAPoint> PrepareAllowance(const QVector<QPointF> &points); QVector<QPointF> Map(const QVector<QPointF> &points) const; static QVector<QPointF> RoundPoints(const QVector<QPointF> &points); @@ -137,6 +147,6 @@ private: int EdgeByPoint(const QVector<QPointF> &path, const QPointF &p1) const; }; -Q_DECLARE_TYPEINFO(VLayoutDetail, Q_MOVABLE_TYPE); +Q_DECLARE_TYPEINFO(VLayoutPiece, Q_MOVABLE_TYPE); #endif // VLAYOUTDETAIL_H diff --git a/src/libs/vlayout/vlayoutdetail_p.h b/src/libs/vlayout/vlayoutpiece_p.h similarity index 51% rename from src/libs/vlayout/vlayoutdetail_p.h rename to src/libs/vlayout/vlayoutpiece_p.h index cd4478fb7..aab150348 100644 --- a/src/libs/vlayout/vlayoutdetail_p.h +++ b/src/libs/vlayout/vlayoutpiece_p.h @@ -43,65 +43,91 @@ QT_WARNING_PUSH QT_WARNING_DISABLE_GCC("-Weffc++") -class VLayoutDetailData : public QSharedData +class VLayoutPieceData : public QSharedData { public: - VLayoutDetailData() - :contour(QVector<QPointF>()), seamAllowence(QVector<QPointF>()), layoutAllowence(QVector<QPointF>()), - matrix(QMatrix()), layoutWidth(0), mirror(false), detailLabel(QVector<QPointF>()), - patternInfo(QVector<QPointF>()), grainlinePoints(QVector<QPointF>()), detailData(), patternGeom(), - grainlineGeom(), m_tmDetail(), m_tmPattern(), m_liPP(QList<QPainterPath>()) + VLayoutPieceData() + : contour(), + seamAllowance(), + layoutAllowance(), + m_internalPaths(), + matrix(), + layoutWidth(0), + mirror(false), + detailLabel(), + patternInfo(), + grainlinePoints(), + detailData(), + patternGeom(), + grainlineGeom(), + m_tmDetail(), + m_tmPattern(), + m_liPP() {} - VLayoutDetailData(const VLayoutDetailData &detail) - :QSharedData(detail), contour(detail.contour), seamAllowence(detail.seamAllowence), - layoutAllowence(detail.layoutAllowence), matrix(detail.matrix), - layoutWidth(detail.layoutWidth), mirror(detail.mirror), detailLabel(detail.detailLabel), - patternInfo(detail.patternInfo), grainlinePoints(detail.grainlinePoints), detailData(detail.detailData), - patternGeom(detail.patternGeom), grainlineGeom(detail.grainlineGeom), m_tmDetail(detail.m_tmDetail), - m_tmPattern(detail.m_tmPattern), m_liPP(detail.m_liPP) + VLayoutPieceData(const VLayoutPieceData &detail) + : QSharedData(detail), + contour(detail.contour), + seamAllowance(detail.seamAllowance), + layoutAllowance(detail.layoutAllowance), + m_internalPaths(detail.m_internalPaths), + matrix(detail.matrix), + layoutWidth(detail.layoutWidth), + mirror(detail.mirror), + detailLabel(detail.detailLabel), + patternInfo(detail.patternInfo), + grainlinePoints(detail.grainlinePoints), + detailData(detail.detailData), + patternGeom(detail.patternGeom), + grainlineGeom(detail.grainlineGeom), + m_tmDetail(detail.m_tmDetail), + m_tmPattern(detail.m_tmPattern), + m_liPP(detail.m_liPP) {} - ~VLayoutDetailData() {} + ~VLayoutPieceData() {} /** @brief contour list of contour points. */ - QVector<QPointF> contour; + QVector<QPointF> contour; - /** @brief seamAllowence list of seam allowance points. */ - QVector<QPointF> seamAllowence; + /** @brief seamAllowance list of seam allowance points. */ + QVector<QPointF> seamAllowance; - /** @brief layoutAllowence list of layout allowance points. */ - QVector<QPointF> layoutAllowence; + /** @brief layoutAllowance list of layout allowance points. */ + QVector<QPointF> layoutAllowance; + + /** @brief m_internalPaths list of internal paths points. */ + QVector<QVector<QPointF>> m_internalPaths; /** @brief matrix transformation matrix*/ - QTransform matrix; + QTransform matrix; /** @brief layoutWidth value layout allowance width in pixels. */ - qreal layoutWidth; + qreal layoutWidth; - bool mirror; + bool mirror; /** @brief detailLabel detail label rectangle */ - QVector<QPointF> detailLabel; + QVector<QPointF> detailLabel; /** @brief patternInfo pattern info rectangle */ - QVector<QPointF> patternInfo; + QVector<QPointF> patternInfo; /** @brief grainlineInfo line */ - QVector<QPointF> grainlinePoints; + QVector<QPointF> grainlinePoints; /** @brief detailData detail data */ - VPatternPieceData detailData; + VPatternPieceData detailData; /** @brief patternGeom pattern geometry */ - VPatternInfoGeometry patternGeom; + VPatternInfoGeometry patternGeom; /** @brief grainlineGeom grainline geometry */ - VGrainlineGeometry grainlineGeom; + VGrainlineGeometry grainlineGeom; /** @brief m_tmDetail text manager for laying out detail info */ - VTextManager m_tmDetail; + VTextManager m_tmDetail; /** @brief m_tmPattern text manager for laying out pattern info */ - VTextManager m_tmPattern; + VTextManager m_tmPattern; /** @bried m_liPP list of generated text painter paths */ - QList<QPainterPath> m_liPP; + QList<QPainterPath> m_liPP; private: - VLayoutDetailData &operator=(const VLayoutDetailData &) Q_DECL_EQ_DELETE; + VLayoutPieceData &operator=(const VLayoutPieceData &) Q_DECL_EQ_DELETE; }; QT_WARNING_POP diff --git a/src/libs/vlayout/vposition.cpp b/src/libs/vlayout/vposition.cpp index 9308536f2..6c7345a67 100644 --- a/src/libs/vlayout/vposition.cpp +++ b/src/libs/vlayout/vposition.cpp @@ -50,10 +50,10 @@ #include "../vmisc/vmath.h" //--------------------------------------------------------------------------------------------------------------------- -VPosition::VPosition(const VContour &gContour, int j, const VLayoutDetail &detail, int i, volatile bool *stop, +VPosition::VPosition(const VContour &gContour, int j, const VLayoutPiece &detail, int i, volatile bool *stop, bool rotate, int rotationIncrease, bool saveLength) :QRunnable(), bestResult(VBestSquare(gContour.GetSize(), saveLength)), gContour(gContour), detail(detail), i(i), - j(j), paperIndex(0), frame(0), detailsCount(0), details(QVector<VLayoutDetail>()), stop(stop), rotate(rotate), + j(j), paperIndex(0), frame(0), detailsCount(0), details(QVector<VLayoutPiece>()), stop(stop), rotate(rotate), rotationIncrease(rotationIncrease), angle_between(0) { if ((rotationIncrease >= 1 && rotationIncrease <= 180 && 360 % rotationIncrease == 0) == false) @@ -71,7 +71,7 @@ void VPosition::run() } // We should use copy of the detail. - VLayoutDetail workDetail = detail; + VLayoutPiece workDetail = detail; int dEdge = i;// For mirror detail edge will be different if (CheckCombineEdges(workDetail, j, dEdge)) @@ -139,7 +139,7 @@ void VPosition::setDetailsCount(const quint32 &value) } //--------------------------------------------------------------------------------------------------------------------- -void VPosition::setDetails(const QVector<VLayoutDetail> &details) +void VPosition::setDetails(const QVector<VLayoutPiece> &details) { this->details = details; } @@ -151,8 +151,8 @@ VBestSquare VPosition::getBestResult() const } //--------------------------------------------------------------------------------------------------------------------- -void VPosition::DrawDebug(const VContour &contour, const VLayoutDetail &detail, int frame, quint32 paperIndex, - int detailsCount, const QVector<VLayoutDetail> &details) +void VPosition::DrawDebug(const VContour &contour, const VLayoutPiece &detail, int frame, quint32 paperIndex, + int detailsCount, const QVector<VLayoutPiece> &details) { const int biasWidth = Bias(contour.GetWidth(), QIMAGE_MAX); const int biasHeight = Bias(contour.GetHeight(), QIMAGE_MAX); @@ -178,7 +178,7 @@ void VPosition::DrawDebug(const VContour &contour, const VLayoutDetail &detail, #ifdef SHOW_CANDIDATE paint.setPen(QPen(Qt::darkGreen, 6, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin)); - p = DrawContour(detail.GetLayoutAllowencePoints()); + p = DrawContour(detail.GetLayoutAllowancePoints()); p.translate(biasWidth/2, biasHeight/2); paint.drawPath(p); #else @@ -242,7 +242,7 @@ int VPosition::Bias(int length, int maxLength) } //--------------------------------------------------------------------------------------------------------------------- -void VPosition::SaveCandidate(VBestSquare &bestResult, const VLayoutDetail &detail, int globalI, int detJ, +void VPosition::SaveCandidate(VBestSquare &bestResult, const VLayoutPiece &detail, int globalI, int detJ, BestFrom type) { QVector<QPointF> newGContour = gContour.UniteWithContour(detail, globalI, detJ, type); @@ -252,7 +252,7 @@ void VPosition::SaveCandidate(VBestSquare &bestResult, const VLayoutDetail &deta } //--------------------------------------------------------------------------------------------------------------------- -bool VPosition::CheckCombineEdges(VLayoutDetail &detail, int j, int &dEdge) +bool VPosition::CheckCombineEdges(VLayoutPiece &detail, int j, int &dEdge) { const QLineF globalEdge = gContour.GlobalEdge(j); bool flagMirror = false; @@ -294,7 +294,7 @@ bool VPosition::CheckCombineEdges(VLayoutDetail &detail, int j, int &dEdge) break; } - if (flagMirror && not detail.getForbidFlipping()) + if (flagMirror && not detail.IsForbidFlipping()) { #ifdef LAYOUT_DEBUG #ifdef SHOW_MIRROR @@ -340,7 +340,7 @@ bool VPosition::CheckCombineEdges(VLayoutDetail &detail, int j, int &dEdge) } //--------------------------------------------------------------------------------------------------------------------- -bool VPosition::CheckRotationEdges(VLayoutDetail &detail, int j, int dEdge, int angle) const +bool VPosition::CheckRotationEdges(VLayoutPiece &detail, int j, int dEdge, int angle) const { const QLineF globalEdge = gContour.GlobalEdge(j); bool flagSquare = false; @@ -376,7 +376,7 @@ bool VPosition::CheckRotationEdges(VLayoutDetail &detail, int j, int dEdge, int } //--------------------------------------------------------------------------------------------------------------------- -VPosition::CrossingType VPosition::Crossing(const VLayoutDetail &detail) const +VPosition::CrossingType VPosition::Crossing(const VLayoutPiece &detail) const { const QRectF gRect = gContour.BoundingRect(); if (not gRect.intersects(detail.LayoutBoundingRect()) && not gRect.contains(detail.DetailBoundingRect())) @@ -386,7 +386,7 @@ VPosition::CrossingType VPosition::Crossing(const VLayoutDetail &detail) const } const QPainterPath gPath = gContour.ContourPath(); - if (not gPath.intersects(detail.LayoutAllowencePath()) && not gPath.contains(detail.ContourPath())) + if (not gPath.intersects(detail.LayoutAllowancePath()) && not gPath.contains(detail.ContourPath())) { return CrossingType::NoIntersection; } @@ -404,7 +404,7 @@ bool VPosition::SheetContains(const QRectF &rect) const } //--------------------------------------------------------------------------------------------------------------------- -void VPosition::CombineEdges(VLayoutDetail &detail, const QLineF &globalEdge, const int &dEdge) +void VPosition::CombineEdges(VLayoutPiece &detail, const QLineF &globalEdge, const int &dEdge) { QLineF detailEdge; if (gContour.GetContour().isEmpty()) @@ -433,7 +433,7 @@ void VPosition::CombineEdges(VLayoutDetail &detail, const QLineF &globalEdge, co } //--------------------------------------------------------------------------------------------------------------------- -void VPosition::RotateEdges(VLayoutDetail &detail, const QLineF &globalEdge, int dEdge, int angle) const +void VPosition::RotateEdges(VLayoutPiece &detail, const QLineF &globalEdge, int dEdge, int angle) const { QLineF detailEdge; if (gContour.GetContour().isEmpty()) @@ -472,7 +472,7 @@ void VPosition::Rotate(int increase) } // We should use copy of the detail. - VLayoutDetail workDetail = detail; + VLayoutPiece workDetail = detail; if (CheckRotationEdges(workDetail, j, i, angle)) { @@ -549,7 +549,7 @@ QPainterPath VPosition::DrawContour(const QVector<QPointF> &points) } //--------------------------------------------------------------------------------------------------------------------- -QPainterPath VPosition::DrawDetails(const QVector<VLayoutDetail> &details) +QPainterPath VPosition::DrawDetails(const QVector<VLayoutPiece> &details) { QPainterPath path; path.setFillRule(Qt::WindingFill); diff --git a/src/libs/vlayout/vposition.h b/src/libs/vlayout/vposition.h index 692d05d42..c607d4777 100644 --- a/src/libs/vlayout/vposition.h +++ b/src/libs/vlayout/vposition.h @@ -37,7 +37,7 @@ #include "vbestsquare.h" #include "vcontour.h" #include "vlayoutdef.h" -#include "vlayoutdetail.h" +#include "vlayoutpiece.h" class QLineF; class QPainterPath; @@ -48,7 +48,7 @@ class QRectF; class VPosition : public QRunnable { public: - VPosition(const VContour &gContour, int j, const VLayoutDetail &detail, int i, volatile bool *stop, bool rotate, + VPosition(const VContour &gContour, int j, const VLayoutPiece &detail, int i, volatile bool *stop, bool rotate, int rotationIncrease, bool saveLength); virtual ~VPosition() Q_DECL_OVERRIDE{} @@ -61,12 +61,12 @@ public: quint32 getDetailsCount() const; void setDetailsCount(const quint32 &value); - void setDetails(const QVector<VLayoutDetail> &details); + void setDetails(const QVector<VLayoutPiece> &details); VBestSquare getBestResult() const; - static void DrawDebug(const VContour &contour, const VLayoutDetail &detail, int frame, quint32 paperIndex, - int detailsCount, const QVector<VLayoutDetail> &details = QVector<VLayoutDetail>()); + static void DrawDebug(const VContour &contour, const VLayoutPiece &detail, int frame, quint32 paperIndex, + int detailsCount, const QVector<VLayoutPiece> &details = QVector<VLayoutPiece>()); static int Bias(int length, int maxLength); @@ -74,13 +74,13 @@ private: Q_DISABLE_COPY(VPosition) VBestSquare bestResult; const VContour gContour; - const VLayoutDetail detail; + const VLayoutPiece detail; int i; int j; quint32 paperIndex; quint32 frame; quint32 detailsCount; - QVector<VLayoutDetail> details; + QVector<VLayoutPiece> details; volatile bool *stop; bool rotate; int rotationIncrease; @@ -105,20 +105,20 @@ private: virtual void run() Q_DECL_OVERRIDE; - void SaveCandidate(VBestSquare &bestResult, const VLayoutDetail &detail, int globalI, int detJ, BestFrom type); + void SaveCandidate(VBestSquare &bestResult, const VLayoutPiece &detail, int globalI, int detJ, BestFrom type); - bool CheckCombineEdges(VLayoutDetail &detail, int j, int &dEdge); - bool CheckRotationEdges(VLayoutDetail &detail, int j, int dEdge, int angle) const; + bool CheckCombineEdges(VLayoutPiece &detail, int j, int &dEdge); + bool CheckRotationEdges(VLayoutPiece &detail, int j, int dEdge, int angle) const; - CrossingType Crossing(const VLayoutDetail &detail) const; + CrossingType Crossing(const VLayoutPiece &detail) const; bool SheetContains(const QRectF &rect) const; - void CombineEdges(VLayoutDetail &detail, const QLineF &globalEdge, const int &dEdge); - void RotateEdges(VLayoutDetail &detail, const QLineF &globalEdge, int dEdge, int angle) const; + void CombineEdges(VLayoutPiece &detail, const QLineF &globalEdge, const int &dEdge); + void RotateEdges(VLayoutPiece &detail, const QLineF &globalEdge, int dEdge, int angle) const; static QPainterPath ShowDirection(const QLineF &edge); static QPainterPath DrawContour(const QVector<QPointF> &points); - static QPainterPath DrawDetails(const QVector<VLayoutDetail> &details); + static QPainterPath DrawDetails(const QVector<VLayoutPiece> &details); void Rotate(int increase); }; diff --git a/src/libs/vmisc/abstracttest.cpp b/src/libs/vmisc/abstracttest.cpp index d22c3e696..74e5d79b9 100644 --- a/src/libs/vmisc/abstracttest.cpp +++ b/src/libs/vmisc/abstracttest.cpp @@ -67,7 +67,8 @@ void AbstractTest::Comparison(const QVector<QPointF> &ekv, const QVector<QPointF { const QPoint p1 = ekv.at(i).toPoint(); const QPoint p2 = ekvOrig.at(i).toPoint(); - const QString msg = QString("Got '%1;%2', Exprected '%3;%4'.").arg(p1.x(), p1.y()).arg(p2.x(), p2.y()); + const QString msg = QString("Index: %1. Got '%2;%3', Expected '%4;%5'.") + .arg(i).arg(p1.x()).arg(p1.y()).arg(p2.x()).arg(p2.y()); // Check each point. Don't use comparison float values QVERIFY2(p1 == p2, qUtf8Printable(msg)); } diff --git a/src/libs/vmisc/def.h b/src/libs/vmisc/def.h index c23c9785a..15a5ef7aa 100644 --- a/src/libs/vmisc/def.h +++ b/src/libs/vmisc/def.h @@ -75,6 +75,24 @@ enum class Source : char { FromGui, FromFile, FromTool }; enum class NodeUsage : bool {NotInUse = false, InUse = true}; enum class SelectionType : bool {ByMousePress, ByMouseRelease}; +enum class PieceNodeAngle : unsigned char +{ + ByLength = 0, + ByPointsIntersection, + ByFirstEdgeSymmetry, + BySecondEdgeSymmetry, + ByFirstEdgeRightAngle, + BySecondEdgeRightAngle +}; + +enum class PiecePathIncludeType : unsigned char +{ + AsMainPath = 0, + AsCustomSA = 1 +}; + +enum class PiecePathType : unsigned char {PiecePath = 0, CustomSeamAllowance = 1, InternalPath = 2, Unknown = 3}; + typedef unsigned char ToolVisHolderType; enum class Tool : ToolVisHolderType { @@ -102,7 +120,8 @@ enum class Tool : ToolVisHolderType CubicBezierPath, CutSplinePath, PointOfContact, - Detail, + Piece, + PiecePath, NodePoint, NodeArc, NodeElArc, @@ -172,7 +191,9 @@ enum class Vis : ToolVisHolderType ToolFlippingByLine, ToolFlippingByAxis, ToolMove, - ToolEllipticalArc + ToolEllipticalArc, + ToolPiece, + ToolPiecePath }; enum class VarType : char { Measurement, Increment, LineLength, CurveLength, CurveCLength, LineAngle, CurveAngle, @@ -675,6 +696,29 @@ static inline bool VFuzzyComparePossibleNulls(double p1, double p2) } } +/** + * @brief The CustomSA struct contains record about custom seam allowanse (SA). + */ +struct CustomSARecord +{ + CustomSARecord() + : startPoint(0), + path(0), + endPoint(0), + reverse(false), + includeType(PiecePathIncludeType::AsCustomSA) + {} + + quint32 startPoint; + quint32 path; + quint32 endPoint; + bool reverse; + PiecePathIncludeType includeType; +}; + +Q_DECLARE_METATYPE(CustomSARecord) +Q_DECLARE_TYPEINFO(CustomSARecord, Q_MOVABLE_TYPE); + /**************************************************************************** ** This file is derived from code bearing the following notice: ** The sole author of this file, Adam Higerd, has explicitly disclaimed all diff --git a/src/libs/vmisc/vabstractapplication.cpp b/src/libs/vmisc/vabstractapplication.cpp index 2a2774b72..d7d97cbae 100644 --- a/src/libs/vmisc/vabstractapplication.cpp +++ b/src/libs/vmisc/vabstractapplication.cpp @@ -290,12 +290,12 @@ VCommonSettings *VAbstractApplication::Settings() //--------------------------------------------------------------------------------------------------------------------- QGraphicsScene *VAbstractApplication::getCurrentScene() const { - SCASSERT(currentScene != nullptr) - return currentScene; + SCASSERT(*currentScene != nullptr) + return *currentScene; } //--------------------------------------------------------------------------------------------------------------------- -void VAbstractApplication::setCurrentScene(QGraphicsScene *value) +void VAbstractApplication::setCurrentScene(QGraphicsScene **value) { currentScene = value; } diff --git a/src/libs/vmisc/vabstractapplication.h b/src/libs/vmisc/vabstractapplication.h index cf13f287d..a00a980b4 100644 --- a/src/libs/vmisc/vabstractapplication.h +++ b/src/libs/vmisc/vabstractapplication.h @@ -88,7 +88,7 @@ public: QString LocaleToString(const T &value); QGraphicsScene *getCurrentScene() const; - void setCurrentScene(QGraphicsScene *value); + void setCurrentScene(QGraphicsScene **value); VMainGraphicsView *getSceneView() const; void setSceneView(VMainGraphicsView *value); @@ -137,7 +137,7 @@ private: MeasurementsType _patternType; - QGraphicsScene *currentScene; + QGraphicsScene **currentScene; VMainGraphicsView *sceneView; VAbstractPattern *doc; diff --git a/src/libs/vpatterndb/vcontainer.cpp b/src/libs/vpatterndb/vcontainer.cpp index 12e070407..2034fbc3d 100644 --- a/src/libs/vpatterndb/vcontainer.cpp +++ b/src/libs/vpatterndb/vcontainer.cpp @@ -151,16 +151,24 @@ const val VContainer::GetObject(const QHash<key, val> &obj, key id) const } //--------------------------------------------------------------------------------------------------------------------- -/** - * @brief GetDetail return detail by id - * @param id id of detail - * @return detail - */ -const VDetail VContainer::GetDetail(quint32 id) const +VPiece VContainer::GetPiece(quint32 id) const { - if (d->details->contains(id)) + if (d->pieces->contains(id)) { - return d->details->value(id); + return d->pieces->value(id); + } + else + { + throw VExceptionBadId(tr("Can't find object"), id); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +VPiecePath VContainer::GetPiecePath(quint32 id) const +{ + if (d->piecePaths->contains(id)) + { + return d->piecePaths->value(id); } else { @@ -183,15 +191,18 @@ quint32 VContainer::AddGObject(VGObject *obj) } //--------------------------------------------------------------------------------------------------------------------- -/** - * @brief AddDetail add new detail to container - * @param detail new detail - * @return return id of new detail in container - */ -quint32 VContainer::AddDetail(const VDetail &detail) +quint32 VContainer::AddPiece(const VPiece &detail) { const quint32 id = getNextId(); - d->details->insert(id, detail); + d->pieces->insert(id, detail); + return id; +} + +//--------------------------------------------------------------------------------------------------------------------- +quint32 VContainer::AddPiecePath(const VPiecePath &path) +{ + const quint32 id = getNextId(); + d->piecePaths->insert(id, path); return id; } @@ -262,7 +273,8 @@ void VContainer::Clear() qCDebug(vCon, "Clearing container data."); _id = NULL_ID; - d->details->clear(); + d->pieces->clear(); + d->piecePaths->clear(); ClearVariables(); ClearGObjects(); ClearUniqueNames(); @@ -274,7 +286,8 @@ void VContainer::ClearForFullParse() qCDebug(vCon, "Clearing container data for full parse."); _id = NULL_ID; - d->details->clear(); + d->pieces->clear(); + d->piecePaths->clear(); ClearVariables(VarType::Increment); ClearVariables(VarType::LineAngle); ClearVariables(VarType::LineLength); @@ -473,6 +486,12 @@ void VContainer::RemoveVariable(const QString &name) d->variables.remove(name); } +//--------------------------------------------------------------------------------------------------------------------- +void VContainer::RemovePiece(quint32 id) +{ + d->pieces->remove(id); +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief AddObject add object to container @@ -505,15 +524,18 @@ void VContainer::UpdateGObject(quint32 id, VGObject* obj) } //--------------------------------------------------------------------------------------------------------------------- -/** - * @brief UpdateDetail update detail by id - * @param id id of existing detail - * @param detail detail - */ -void VContainer::UpdateDetail(quint32 id, const VDetail &detail) +void VContainer::UpdatePiece(quint32 id, const VPiece &detail) { Q_ASSERT_X(id != NULL_ID, Q_FUNC_INFO, "id == 0"); //-V654 //-V712 - d->details->insert(id, detail); + d->pieces->insert(id, detail); + UpdateId(id); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VContainer::UpdatePiecePath(quint32 id, const VPiecePath &path) +{ + Q_ASSERT_X(id != NULL_ID, Q_FUNC_INFO, "id == 0"); //-V654 //-V712 + d->piecePaths->insert(id, path); UpdateId(id); } @@ -666,13 +688,6 @@ const QMap<QString, QSharedPointer<T> > VContainer::DataVar(const VarType &type) return map; } -//--------------------------------------------------------------------------------------------------------------------- -// cppcheck-suppress unusedFunction -void VContainer::ClearDetails() -{ - d->details->clear(); -} - //--------------------------------------------------------------------------------------------------------------------- void VContainer::ClearUniqueNames() { @@ -742,13 +757,9 @@ const QHash<quint32, QSharedPointer<VGObject> > *VContainer::DataGObjects() cons } //--------------------------------------------------------------------------------------------------------------------- -/** - * @brief data container with dataDetails return container of details - * @return pointer on container of details - */ -const QHash<quint32, VDetail> *VContainer::DataDetails() const +const QHash<quint32, VPiece> *VContainer::DataPieces() const { - return d->details.data(); + return d->pieces.data(); } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/vpatterndb/vcontainer.h b/src/libs/vpatterndb/vcontainer.h index 845808ac1..562cc8330 100644 --- a/src/libs/vpatterndb/vcontainer.h +++ b/src/libs/vpatterndb/vcontainer.h @@ -53,7 +53,8 @@ #include "../vmisc/diagnostic.h" #include "variables.h" #include "variables/vinternalvariable.h" -#include "vdetail.h" +#include "vpiece.h" +#include "vpiecepath.h" #include "vtranslatevars.h" class VAbstractCubicBezierPath; @@ -81,15 +82,18 @@ public: VContainerData(const VTranslateVars *trVars, const Unit *patternUnit) : gObjects(QHash<quint32, QSharedPointer<VGObject> >()), variables(QHash<QString, QSharedPointer<VInternalVariable> > ()), - details(QSharedPointer<QHash<quint32, VDetail>>(new QHash<quint32, VDetail>())), - trVars(trVars), patternUnit(patternUnit) + pieces(QSharedPointer<QHash<quint32, VPiece>>(new QHash<quint32, VPiece>())), + piecePaths(QSharedPointer<QHash<quint32, VPiecePath>>(new QHash<quint32, VPiecePath>())), + trVars(trVars), + patternUnit(patternUnit) {} VContainerData(const VContainerData &data) : QSharedData(data), gObjects(data.gObjects), variables(data.variables), - details(data.details), + pieces(data.pieces), + piecePaths(data.piecePaths), trVars(data.trVars), patternUnit(data.patternUnit) {} @@ -105,10 +109,9 @@ public: * @brief variables container for measurements, increments, lines lengths, lines angles, arcs lengths, curve lengths */ QHash<QString, QSharedPointer<VInternalVariable>> variables; - /** - * @brief details container of details - */ - QSharedPointer<QHash<quint32, VDetail>> details; + + QSharedPointer<QHash<quint32, VPiece>> pieces; + QSharedPointer<QHash<quint32, VPiecePath>> piecePaths; const VTranslateVars *trVars; const Unit *patternUnit; @@ -135,7 +138,8 @@ public: const QSharedPointer<T> GeometricObject(const quint32 &id) const; const QSharedPointer<VGObject> GetGObject(quint32 id) const; static const QSharedPointer<VGObject> GetFakeGObject(quint32 id); - const VDetail GetDetail(quint32 id) const; + VPiece GetPiece(quint32 id) const; + VPiecePath GetPiecePath(quint32 id) const; qreal GetTableValue(const QString& name, MeasurementsType patternType) const; template <typename T> QSharedPointer<T> GetVariable(QString name) const; @@ -144,7 +148,8 @@ public: static void UpdateId(quint32 newId); quint32 AddGObject(VGObject *obj); - quint32 AddDetail(const VDetail &detail); + quint32 AddPiece(const VPiece &detail); + quint32 AddPiecePath(const VPiecePath &path); void AddLine(const quint32 &firstPointId, const quint32 &secondPointId); void AddArc(const QSharedPointer<VAbstractCurve> &arc, const quint32 &arcId, const quint32 &parentId = NULL_ID); @@ -155,16 +160,17 @@ public: template <typename T> void AddVariable(const QString& name, T *var); void RemoveVariable(const QString& name); + void RemovePiece(quint32 id); void UpdateGObject(quint32 id, VGObject* obj); - void UpdateDetail(quint32 id, const VDetail &detail); + void UpdatePiece(quint32 id, const VPiece &detail); + void UpdatePiecePath(quint32 id, const VPiecePath &path); void Clear(); void ClearForFullParse(); void ClearGObjects(); void ClearCalculationGObjects(); void ClearVariables(const VarType &type = VarType::Unknown); - void ClearDetails(); static void ClearUniqueNames(); static void SetSize(qreal size); @@ -179,7 +185,7 @@ public: void RemoveIncrement(const QString& name); const QHash<quint32, QSharedPointer<VGObject> > *DataGObjects() const; - const QHash<quint32, VDetail> *DataDetails() const; + const QHash<quint32, VPiece> *DataPieces() const; const QHash<QString, QSharedPointer<VInternalVariable>> *DataVariables() const; const QMap<QString, QSharedPointer<VMeasurement> > DataMeasurements() const; @@ -240,9 +246,9 @@ template <typename T> const QSharedPointer<T> VContainer::GeometricObject(const quint32 &id) const { QSharedPointer<VGObject> gObj = QSharedPointer<VGObject>(); - if (d->gObjects.contains(id)) - { - gObj = d->gObjects.value(id); + if (d->gObjects.contains(id)) + { + gObj = d->gObjects.value(id); } else { @@ -253,11 +259,11 @@ const QSharedPointer<T> VContainer::GeometricObject(const quint32 &id) const QSharedPointer<T> obj = qSharedPointerDynamicCast<T>(gObj); SCASSERT(obj.isNull() == false) return obj; - } - catch (const std::bad_alloc &) - { + } + catch (const std::bad_alloc &) + { throw VExceptionBadId(tr("Can't cast object"), id); - } + } } diff --git a/src/libs/vpatterndb/vdetail.cpp b/src/libs/vpatterndb/vdetail.cpp deleted file mode 100644 index 230b4f3a0..000000000 --- a/src/libs/vpatterndb/vdetail.cpp +++ /dev/null @@ -1,814 +0,0 @@ -/************************************************************************ - ** - ** @file vdetail.cpp - ** @author Roman Telezhynskyi <dismine(at)gmail.com> - ** @date November 15, 2013 - ** - ** @brief - ** @copyright - ** This source code is part of the Valentine project, a pattern making - ** program, whose allow create and modeling patterns of clothing. - ** Copyright (C) 2013-2015 Valentina project - ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. - ** - ** Valentina is free software: you can redistribute it and/or modify - ** it under the terms of the GNU General Public License as published by - ** the Free Software Foundation, either version 3 of the License, or - ** (at your option) any later version. - ** - ** Valentina is distributed in the hope that it will be useful, - ** but WITHOUT ANY WARRANTY; without even the implied warranty of - ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - ** GNU General Public License for more details. - ** - ** You should have received a copy of the GNU General Public License - ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. - ** - *************************************************************************/ - -#include "vdetail.h" - -#include <QList> -#include <QMessageLogger> -#include <QPainterPath> -#include <QSet> -#include <QSharedPointer> -#include <QString> -#include <Qt> -#include <QtDebug> -#include <new> - -#include "../vmisc/def.h" -#include "../vgeometry/vabstractcurve.h" -#include "../vgeometry/vgobject.h" -#include "../vgeometry/vpointf.h" -#include "../vlayout/vlayoutdef.h" -#include "vcontainer.h" -#include "vdetail_p.h" -#include "vnodedetail.h" -#include "vpatternpiecedata.h" -#include "vgrainlinegeometry.h" - -class QPointF; - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief VDetail default contructor. Create empty detail. - */ -VDetail::VDetail() - :VAbstractDetail(), d(new VDetailData) -{} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief VDetail constructor. - * @param name detail name. - * @param nodes list of nodes. - */ -VDetail::VDetail(const QString &name, const QVector<VNodeDetail> &nodes) - :VAbstractDetail(name), d(new VDetailData(nodes)) -{} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief VDetail copy constructor. - * @param detail detail. - */ -VDetail::VDetail(const VDetail &detail) - :VAbstractDetail(detail), d (detail.d) -{} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief operator = assignment operator. - * @param detail detail. - * @return new detail. - */ -VDetail &VDetail::operator =(const VDetail &detail) -{ - if ( &detail == this ) - { - return *this; - } - VAbstractDetail::operator=(detail); - d = detail.d; - return *this; -} - -//--------------------------------------------------------------------------------------------------------------------- -VDetail::~VDetail() -{} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief Clear detail full clear. - */ -void VDetail::Clear() -{ - d->nodes.clear(); - d->mx = 0; - d->my = 0; - GetPatternPieceData().Clear(); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief ClearNodes clear list of nodes. - */ -void VDetail::ClearNodes() -{ - d->nodes.clear(); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief Containes check if detail containe this id. - * @param id object id. - * @return true if containe. - */ -bool VDetail::Containes(const quint32 &id) const -{ - for (int i = 0; i < d->nodes.size(); ++i) - { - VNodeDetail node = d->nodes.at(i); - if (node.getId() == id) - { - return true; - } - } - return false; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief operator [] find node by index in list. - * @param indx index node in list. - * @return node - */ -VNodeDetail &VDetail::operator [](int indx) -{ - return d->nodes[indx]; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief at find node by index in list. - * @param indx index node in list. - * @return const node. - */ -const VNodeDetail &VDetail::at(int indx) const -{ - return d->nodes.at(indx); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief indexOfNode return index in list node using id object. - * @param id object (arc, point, spline, splinePath) id. - * @return index in list or -1 id can't find. - */ -int VDetail::indexOfNode(const quint32 &id) const -{ - return indexOfNode(d->nodes, id); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief id return id detail in list data. - * @return id. - */ -quint32 VDetail::id() const -{ - return d->_id; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief setId set id detail in list data. - * @param id detail id. - */ -void VDetail::setId(const quint32 &id) -{ - d->_id = id; -} - -//--------------------------------------------------------------------------------------------------------------------- -bool VDetail::IsInLayout() const -{ - return d->inLayout; -} - -//--------------------------------------------------------------------------------------------------------------------- -void VDetail::SetInLayout(bool inLayout) -{ - d->inLayout = inLayout; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief OnEdge checks if two poins located on the edge. Edge is line between two points. If between two points - * located arcs or splines ignore this. - * @param p1 id first point. - * @param p2 id second point. - * @return true - on edge, false - no. - */ -bool VDetail::OnEdge(const quint32 &p1, const quint32 &p2) const -{ - QVector<VNodeDetail> list = listNodePoint(); - if (list.size() < 2) - { - qDebug()<<"Not enough points."; - return false; - } - int i = indexOfNode(list, p1); - int j1 = 0, j2 = 0; - - if (i == list.size() - 1) - { - j1 = i-1; - j2 = 0; - } - else if (i == 0) - { - j1 = list.size() - 1; - j2 = i + 1; - } - else - { - j1 = i - 1; - j2 = i + 1; - } - - if (list.at(j1).getId() == p2 || list.at(j2).getId() == p2) - { - return true; - } - else - { - return false; - } -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief Edge return edge index in detail. Edge is line between two points. If between two points - * located arcs or splines ignore this. - * @param p1 id first point. - * @param p2 id second point. - * @return edge index or -1 if points don't located on edge - */ -int VDetail::Edge(const quint32 &p1, const quint32 &p2) const -{ - if (OnEdge(p1, p2) == false) - { - qDebug()<<"Points don't on edge."; - return -1; - } - - QVector<VNodeDetail> list = listNodePoint(); - int i = indexOfNode(list, p1); - int j = indexOfNode(list, p2); - - int min = qMin(i, j); - - if (min == 0 && (i == list.size() - 1 || j == list.size() - 1)) - { - return list.size() - 1; - } - else - { - return min; - } -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief NodeOnEdge return nodes located on edge with index. - * @param index index of edge. - * @param p1 first node. - * @param p2 second node. - */ -void VDetail::NodeOnEdge(const quint32 &index, VNodeDetail &p1, VNodeDetail &p2) const -{ - QVector<VNodeDetail> list = listNodePoint(); - if (index > static_cast<quint32>(list.size())) - { - qDebug()<<"Wrong edge index index ="<<index; - return; - } - p1 = list.at(static_cast<int>(index)); - if (index + 1 > static_cast<quint32>(list.size()) - 1) - { - p2 = list.at(0); - } - else - { - p2 = list.at(static_cast<int>(index+1)); - } -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief RemoveEdge return detail without edge with index. - * @param index idex of edge. - * @return detail without edge with index. - */ -VDetail VDetail::RemoveEdge(const quint32 &index) const -{ - VDetail det(*this); - det.ClearNodes(); - - // Edge can be only segment. We ignore all curves inside segments. - const quint32 edges = static_cast<quint32>(listNodePoint().size()); - quint32 k = 0; - for (quint32 i=0; i<edges; ++i) - { - if (i == index) - { - det.append(this->at(static_cast<int>(k))); - ++k; - } - else - { - VNodeDetail p1; - VNodeDetail p2; - this->NodeOnEdge(i, p1, p2); - const int j1 = this->indexOfNode(p1.getId()); - int j2 = this->indexOfNode(p2.getId()); - if (j2 == 0) - { - j2 = this->CountNode(); - } - for (int j=j1; j<j2; ++j) - {// Add "segment" except last point. Inside can be curves too. - det.append(this->at(j)); - ++k; - } - } - } - return det; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief Missing find missing nodes in detail. When we deleted object in detail and return this detail need - * understand, what nodes need make invisible. - * @param det changed detail. - * @return list with missing nodes. - */ -QVector<VNodeDetail> VDetail::Missing(const VDetail &det) const -{ - if (d->nodes.size() == det.CountNode()) //-V807 - { - return QVector<VNodeDetail>(); - } - - QSet<quint32> set1; - for (qint32 i = 0; i < d->nodes.size(); ++i) - { - set1.insert(d->nodes.at(i).getId()); - } - - QSet<quint32> set2; - for (qint32 j = 0; j < det.CountNode(); ++j) - { - set2.insert(det.at(j).getId()); - } - - const QList<quint32> set3 = set1.subtract(set2).toList(); - QVector<VNodeDetail> nodes; - for (qint32 i = 0; i < set3.size(); ++i) - { - const int index = indexOfNode(d->nodes, set3.at(i)); - if (index != -1) - { - nodes.append(d->nodes.at(index)); - } - } - - return nodes; -} - -//--------------------------------------------------------------------------------------------------------------------- -QVector<QPointF> VDetail::ContourPoints(const VContainer *data) const -{ - QVector<QPointF> points; - for (int i = 0; i< CountNode(); ++i) - { - switch (at(i).getTypeTool()) - { - case (Tool::NodePoint): - { - const QSharedPointer<VPointF> point = data->GeometricObject<VPointF>(at(i).getId()); - points.append(*point); - } - break; - case (Tool::NodeArc): - case (Tool::NodeElArc): - case (Tool::NodeSpline): - case (Tool::NodeSplinePath): - { - const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(at(i).getId()); - - const QPointF begin = StartSegment(data, i, at(i).getReverse()); - const QPointF end = EndSegment(data, i, at(i).getReverse()); - - points << curve->GetSegmentPoints(begin, end, at(i).getReverse()); - } - break; - default: - qDebug()<<"Get wrong tool type. Ignore."<< static_cast<char>(at(i).getTypeTool()); - break; - } - } - - points = CheckLoops(CorrectEquidistantPoints(points));//A path can contains loops - return points; -} - -//--------------------------------------------------------------------------------------------------------------------- -QVector<QPointF> VDetail::SeamAllowancePoints(const VContainer *data) const -{ - QVector<QPointF> pointsEkv; - if (getSeamAllowance() == false) - { - return pointsEkv; - } - - for (int i = 0; i< CountNode(); ++i) - { - switch (at(i).getTypeTool()) - { - case (Tool::NodePoint): - { - const QSharedPointer<VPointF> point = data->GeometricObject<VPointF>(at(i).getId()); - QPointF pEkv = *point; - pEkv.setX(pEkv.x()+at(i).getMx()); - pEkv.setY(pEkv.y()+at(i).getMy()); - pointsEkv.append(pEkv); - } - break; - case (Tool::NodeArc): - case (Tool::NodeElArc): - case (Tool::NodeSpline): - case (Tool::NodeSplinePath): - { - const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(at(i).getId()); - - const QPointF begin = StartSegment(data, i, at(i).getReverse()); - const QPointF end = EndSegment(data, i, at(i).getReverse()); - - const QVector<QPointF> nodePoints = curve->GetSegmentPoints(begin, end, at(i).getReverse()); - pointsEkv << biasPoints(nodePoints, at(i).getMx(), at(i).getMy()); - } - break; - default: - qDebug()<<"Get wrong tool type. Ignore."<< static_cast<char>(at(i).getTypeTool()); - break; - } - } - - pointsEkv = CheckLoops(CorrectEquidistantPoints(pointsEkv));//A path can contains loops - - if (getClosed() == true) - { - pointsEkv = Equidistant(pointsEkv, EquidistantType::CloseEquidistant, ToPixel(getWidth(), - *data->GetPatternUnit())); - } - else - { - pointsEkv = Equidistant(pointsEkv, EquidistantType::OpenEquidistant, ToPixel(getWidth(), - *data->GetPatternUnit())); - } - return pointsEkv; -} - -//--------------------------------------------------------------------------------------------------------------------- -QPainterPath VDetail::ContourPath(const VContainer *data) const -{ - const QVector<QPointF> points = ContourPoints(data); - QPainterPath path; - - // contour - path.moveTo(points[0]); - for (qint32 i = 1; i < points.count(); ++i) - { - path.lineTo(points.at(i)); - } - path.lineTo(points.at(0)); - path.setFillRule(Qt::WindingFill); - - return path; -} - -//--------------------------------------------------------------------------------------------------------------------- -QPainterPath VDetail::SeamAllowancePath(const VContainer *data) const -{ - const QVector<QPointF> pointsEkv = SeamAllowancePoints(data); - QPainterPath ekv; - - // seam allowance - if (getSeamAllowance()) - { - if (not pointsEkv.isEmpty()) - { - ekv.moveTo(pointsEkv.at(0)); - for (qint32 i = 1; i < pointsEkv.count(); ++i) - { - ekv.lineTo(pointsEkv.at(i)); - } - - ekv.setFillRule(Qt::WindingFill); - } - } - - return ekv; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief listNodePoint return list nodes only with points. - * @return list points node. - */ -QVector<VNodeDetail> VDetail::listNodePoint() const -{ - QVector<VNodeDetail> list; - for (int i = 0; i < d->nodes.size(); ++i) //-V807 - { - if (d->nodes.at(i).getTypeTool() == Tool::NodePoint) - { - list.append(d->nodes.at(i)); - } - } - return list; -} - -//--------------------------------------------------------------------------------------------------------------------- -void VDetail::SetPatternPieceData(const VPatternPieceData &data) -{ - d->m_ppData = data; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief Returns full access to the pattern piece data object - * @return pattern piece data object - */ -VPatternPieceData& VDetail::GetPatternPieceData() -{ - return d->m_ppData; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief Returns the read only reference to the pattern piece data object - * @return pattern piece data object - */ -const VPatternPieceData& VDetail::GetPatternPieceData() const -{ - return d->m_ppData; -} - -//--------------------------------------------------------------------------------------------------------------------- -void VDetail::SetPatternInfo(const VPatternInfoGeometry &info) -{ - d->m_piPatternInfo = info; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief Returns full access to the pattern info geometry object - * @return pattern info geometry object - */ -VPatternInfoGeometry& VDetail::GetPatternInfo() -{ - return d->m_piPatternInfo; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief Returns the read only reference to the pattern info geometry object - * @return pattern info geometry object - */ -const VPatternInfoGeometry& VDetail::GetPatternInfo() const -{ - return d->m_piPatternInfo; -} - -//--------------------------------------------------------------------------------------------------------------------- - -/** - * @brief VDetail::GetGrainlineGeometry full access to the grainline geometry object - * @return reference to grainline geometry object - */ -VGrainlineGeometry& VDetail::GetGrainlineGeometry() -{ - return d->m_glGrainline; -} - -//--------------------------------------------------------------------------------------------------------------------- - -/** - * @brief VDetail::GetGrainlineGeometry returns the read-only reference to the grainline geometry object - * @return reference to grainline geometry object - */ -const VGrainlineGeometry& VDetail::GetGrainlineGeometry() const -{ - return d->m_glGrainline; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief indexOfNode return index in list node using id object. - * @param list list nodes detail. - * @param id object (arc, point, spline, splinePath) id. - * @return index in list or -1 id can't find. - */ -int VDetail::indexOfNode(const QVector<VNodeDetail> &list, const quint32 &id) -{ - for (int i = 0; i < list.size(); ++i) - { - if (list.at(i).getId() == id) - { - return i; - } - } - qDebug()<<"Can't find node."; - return -1; -} - -//--------------------------------------------------------------------------------------------------------------------- -QPointF VDetail::StartSegment(const VContainer *data, const int &i, bool reverse) const -{ - if (i < 0 && i > CountNode()-1) - { - return QPointF(); - } - - const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(at(i).getId()); - - QVector<QPointF> points = curve->GetPoints(); - if (reverse) - { - points = VGObject::GetReversePoints(points); - } - - QPointF begin = points.first(); - if (CountNode() > 1) - { - if (i == 0) - { - if (at(CountNode()-1).getTypeTool() == Tool::NodePoint) - { - begin = *data->GeometricObject<VPointF>(at(CountNode()-1).getId()); - } - } - else - { - if (at(i-1).getTypeTool() == Tool::NodePoint) - { - begin = *data->GeometricObject<VPointF>(at(i-1).getId()); - } - } - } - return begin; -} - -//--------------------------------------------------------------------------------------------------------------------- -QPointF VDetail::EndSegment(const VContainer *data, const int &i, bool reverse) const -{ - if (i < 0 && i > CountNode()-1) - { - return QPointF(); - } - - const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(at(i).getId()); - - QVector<QPointF> points = curve->GetPoints(); - if (reverse) - { - points = VGObject::GetReversePoints(points); - } - - QPointF end = points.last(); - if (CountNode() > 2) - { - if (i == CountNode() - 1) - { - if (at(0).getTypeTool() == Tool::NodePoint) - { - end = *data->GeometricObject<VPointF>(at(0).getId()); - } - } - else - { - if (at(i+1).getTypeTool() == Tool::NodePoint) - { - end = *data->GeometricObject<VPointF>(at(i+1).getId()); - } - } - } - return end; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief biasPoints bias point. - * @param points vector of points. - * @param mx offset respect to x. - * @param my offset respect to y. - * @return new vector biased points. - */ -QVector<QPointF> VDetail::biasPoints(const QVector<QPointF> &points, const qreal &mx, const qreal &my) -{ - QVector<QPointF> p; - for (qint32 i = 0; i < points.size(); ++i) - { - QPointF point = points.at(i); - point.setX(point.x() + mx); - point.setY(point.y() + my); - p.append(point); - } - return p; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief append append in the end of list node. - * @param node new node. - */ -void VDetail::append(const VNodeDetail &node) -{ - d->nodes.append(node); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief CountNode return count nodes. - * @return count. - */ -qint32 VDetail::CountNode() const -{ - return d->nodes.size(); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief getMx return bias for X axis. - * @return x bias. - */ -qreal VDetail::getMx() const -{ - return d->mx; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief setMx set bias for X axis. - * @param value new x bias. - */ -void VDetail::setMx(const qreal &value) -{ - d->mx = value; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief getMy get bias for y axis. - * @return y axis. - */ -qreal VDetail::getMy() const -{ - return d->my; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief setMy set bias for y axis. - * @param value new y bias. - */ -void VDetail::setMy(const qreal &value) -{ - d->my = value; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief getNodes return list of nodes. - * @return list of nodes. - */ -QVector<VNodeDetail> VDetail::getNodes() const -{ - return d->nodes; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief setNodes set list of nodes - * @param value list of nodes - */ -// cppcheck-suppress unusedFunction -void VDetail::setNodes(const QVector<VNodeDetail> &value) -{ - d->nodes = value; -} diff --git a/src/libs/vpatterndb/vdetail.h b/src/libs/vpatterndb/vdetail.h deleted file mode 100644 index 54eb0c958..000000000 --- a/src/libs/vpatterndb/vdetail.h +++ /dev/null @@ -1,125 +0,0 @@ -/************************************************************************ - ** - ** @file vdetail.h - ** @author Roman Telezhynskyi <dismine(at)gmail.com> - ** @date November 15, 2013 - ** - ** @brief - ** @copyright - ** This source code is part of the Valentine project, a pattern making - ** program, whose allow create and modeling patterns of clothing. - ** Copyright (C) 2013-2015 Valentina project - ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. - ** - ** Valentina is free software: you can redistribute it and/or modify - ** it under the terms of the GNU General Public License as published by - ** the Free Software Foundation, either version 3 of the License, or - ** (at your option) any later version. - ** - ** Valentina is distributed in the hope that it will be useful, - ** but WITHOUT ANY WARRANTY; without even the implied warranty of - ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - ** GNU General Public License for more details. - ** - ** You should have received a copy of the GNU General Public License - ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. - ** - *************************************************************************/ - -#ifndef VDETAIL_H -#define VDETAIL_H - -#include <qcompilerdetection.h> -#include <QPointF> -#include <QSharedDataPointer> -#include <QString> -#include <QTypeInfo> -#include <QVector> -#include <QtGlobal> - -#include "../vlayout/vabstractdetail.h" -#include "vnodedetail.h" - -class QPainterPath; -class QPointF; -class VContainer; -class VDetailData; -class VNodeDetail; -class VPatternInfoGeometry; -class VPatternPieceData; -class VGrainlineGeometry; - -/** - * @brief The VDetail class for path of object (points, arcs, splines). - */ -class VDetail :public VAbstractDetail -{ -public: - VDetail(); - VDetail(const QString &name, const QVector<VNodeDetail> &nodes); - VDetail(const VDetail &detail); - VDetail &operator=(const VDetail &detail); - virtual ~VDetail() Q_DECL_OVERRIDE; - - void append(const VNodeDetail &node); - void Clear(); - void ClearNodes(); - qint32 CountNode() const; - bool Containes(const quint32 &id)const; - VNodeDetail & operator[](int indx); - const VNodeDetail & at ( int indx ) const; - - qreal getMx() const; - void setMx(const qreal &value); - - qreal getMy() const; - void setMy(const qreal &value); - - quint32 id() const; - void setId(const quint32 &id); - - bool IsInLayout() const; - void SetInLayout(bool inLayout); - - QVector<VNodeDetail> getNodes() const; - void setNodes(const QVector<VNodeDetail> &value); - - int indexOfNode(const quint32 &id) const; - bool OnEdge(const quint32 &p1, const quint32 &p2)const; - int Edge(const quint32 &p1, const quint32 &p2)const; - void NodeOnEdge(const quint32 &index, VNodeDetail &p1, VNodeDetail &p2)const; - VDetail RemoveEdge(const quint32 &index) const; - - QVector<VNodeDetail> Missing(const VDetail &det) const; - - QVector<QPointF> ContourPoints(const VContainer *data) const; - QVector<QPointF> SeamAllowancePoints(const VContainer *data) const; - - QPainterPath ContourPath(const VContainer *data) const; - QPainterPath SeamAllowancePath(const VContainer *data) const; - QVector<VNodeDetail> listNodePoint()const; - - void SetPatternPieceData(const VPatternPieceData &data); - VPatternPieceData& GetPatternPieceData(); - const VPatternPieceData& GetPatternPieceData() const; - - void SetPatternInfo(const VPatternInfoGeometry &info); - VPatternInfoGeometry& GetPatternInfo(); - const VPatternInfoGeometry& GetPatternInfo() const; - VGrainlineGeometry& GetGrainlineGeometry(); - const VGrainlineGeometry& GetGrainlineGeometry() const; - -private: - QSharedDataPointer<VDetailData> d; - - static int indexOfNode(const QVector<VNodeDetail> &list, const quint32 &id); - - QPointF StartSegment(const VContainer *data, const int &i, bool reverse) const; - QPointF EndSegment(const VContainer *data, const int &i, bool reverse) const; - - static QVector<QPointF> biasPoints(const QVector<QPointF> &points, const qreal &mx, const qreal &my); -}; - -Q_DECLARE_TYPEINFO(VDetail, Q_MOVABLE_TYPE); - -#endif // VDETAIL_H diff --git a/src/libs/vpatterndb/vnodedetail.cpp b/src/libs/vpatterndb/vnodedetail.cpp index decba2343..489c2a257 100644 --- a/src/libs/vpatterndb/vnodedetail.cpp +++ b/src/libs/vpatterndb/vnodedetail.cpp @@ -28,6 +28,73 @@ #include "vnodedetail.h" #include "vnodedetail_p.h" +#include "vpiecenode.h" +#include "vpiecepath.h" +#include "../vgeometry/vpointf.h" +#include "../vpatterndb/vcontainer.h" + +#include <QLineF> +#include <QVector> + +namespace +{ +//--------------------------------------------------------------------------------------------------------------------- +bool IsOX(const QLineF &line) +{ + return VFuzzyComparePossibleNulls(line.angle(), 0) + || VFuzzyComparePossibleNulls(line.angle(), 360) + || VFuzzyComparePossibleNulls(line.angle(), 180); +} + +//--------------------------------------------------------------------------------------------------------------------- +bool IsOY(const QLineF &line) +{ + return VFuzzyComparePossibleNulls(line.angle(), 90) || VFuzzyComparePossibleNulls(line.angle(), 270); +} + +//--------------------------------------------------------------------------------------------------------------------- +QString LocalWidth(const QLineF &line, const QLineF &movedLine) +{ + if (VFuzzyComparePossibleNulls(line.angle(), movedLine.angle())) + { + return QString().setNum(movedLine.length()); + } + else + {// different direction means value is negative + return QString("0"); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void ConvertBefore(VPieceNode &node, const QLineF &line, qreal mX, qreal mY) +{ + if (not qFuzzyIsNull(mX) && IsOX(line)) + { + const QLineF movedLine(line.p1().x(), line.p1().y(), line.p2().x() + mX, line.p2().y()); + node.SetFormulaSABefore(LocalWidth(line, movedLine)); + } + else if (not qFuzzyIsNull(mY) && IsOY(line)) + { + const QLineF movedLine(line.p1().x(), line.p1().y(), line.p2().x(), line.p2().y() + mY); + node.SetFormulaSABefore(LocalWidth(line, movedLine)); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void ConvertAfter(VPieceNode &node, const QLineF &line, qreal mX, qreal mY) +{ + if (not qFuzzyIsNull(mX) && IsOX(line)) + { + const QLineF movedLine(line.p1().x(), line.p1().y(), line.p2().x() + mX, line.p2().y()); + node.SetFormulaSAAfter(LocalWidth(line, movedLine)); + } + else if (not qFuzzyIsNull(mY) && IsOY(line)) + { + const QLineF movedLine(line.p1().x(), line.p1().y(), line.p2().x(), line.p2().y() + mY); + node.SetFormulaSAAfter(LocalWidth(line, movedLine)); + } +} +}//static functions //--------------------------------------------------------------------------------------------------------------------- VNodeDetail::VNodeDetail() @@ -146,3 +213,58 @@ void VNodeDetail::setReverse(bool reverse) d->reverse = reverse; } } + +//--------------------------------------------------------------------------------------------------------------------- +QVector<VPieceNode> VNodeDetail::Convert(const VContainer *data, const QVector<VNodeDetail> &nodes, qreal width, + bool closed) +{ + if (width < 0) + { + width = 0; + } + + VPiecePath path; + for (int i = 0; i < nodes.size(); ++i) + { + const VNodeDetail &node = nodes.at(i); + path.Append(VPieceNode(node.getId(), node.getTypeTool(), node.getReverse())); + } + + if (path.PathPoints(data).size() > 2) + { + for (int i = 0; i < nodes.size(); ++i) + { + const VNodeDetail &node = nodes.at(i); + if (node.getTypeTool() == Tool::NodePoint) + { + if (not qFuzzyIsNull(node.getMx()) || not qFuzzyIsNull(node.getMy())) + { + const QPointF previosPoint = path.NodePreviousPoint(data, i); + const QPointF nextPoint = path.NodeNextPoint(data, i); + + const QPointF point = data->GeometricObject<VPointF>(node.getId())->toQPointF(); + + QLineF lineBefore(point, previosPoint); + lineBefore.setAngle(lineBefore.angle()-90); + lineBefore.setLength(width); + + ConvertBefore(path[i], lineBefore, node.getMx(), node.getMy()); + + QLineF lineAfter(point, nextPoint); + lineAfter.setAngle(lineAfter.angle()+90); + lineAfter.setLength(width); + + ConvertAfter(path[i], lineAfter, node.getMx(), node.getMy()); + } + } + } + } + + if (not closed && path.CountNodes() > 1) + { + path[0].SetFormulaSABefore("0"); + path[path.CountNodes()-1].SetFormulaSAAfter("0"); + } + + return path.GetNodes(); +} diff --git a/src/libs/vpatterndb/vnodedetail.h b/src/libs/vpatterndb/vnodedetail.h index d1c5ac152..a26056923 100644 --- a/src/libs/vpatterndb/vnodedetail.h +++ b/src/libs/vpatterndb/vnodedetail.h @@ -37,6 +37,8 @@ #include "../vmisc/def.h" class VNodeDetailData; +class VPieceNode; +class VContainer; /** * @brief The VNodeDetail class keep information about detail node. @@ -122,6 +124,9 @@ public: bool getReverse() const; void setReverse(bool reverse); + + static QVector<VPieceNode> Convert(const VContainer *data, const QVector<VNodeDetail> &nodes, qreal width, + bool closed); private: QSharedDataPointer<VNodeDetailData> d; }; diff --git a/src/libs/vpatterndb/vpatterndb.pri b/src/libs/vpatterndb/vpatterndb.pri index ead57870f..5a94d2ff8 100644 --- a/src/libs/vpatterndb/vpatterndb.pri +++ b/src/libs/vpatterndb/vpatterndb.pri @@ -1,62 +1,68 @@ -# ADD TO EACH PATH $$PWD VARIABLE!!!!!! -# This need for corect working file translations.pro - -SOURCES += \ - $$PWD/vcontainer.cpp \ - $$PWD/calculator.cpp \ - $$PWD/vdetail.cpp \ - $$PWD/vnodedetail.cpp \ - $$PWD/vtranslatevars.cpp \ - $$PWD/variables/varcradius.cpp \ - $$PWD/variables/vcurveangle.cpp \ - $$PWD/variables/vcurvelength.cpp \ - $$PWD/variables/vcurvevariable.cpp \ - $$PWD/variables/vincrement.cpp \ - $$PWD/variables/vinternalvariable.cpp \ - $$PWD/variables/vlineangle.cpp \ - $$PWD/variables/vlinelength.cpp \ - $$PWD/variables/vmeasurement.cpp \ - $$PWD/variables/vvariable.cpp \ - $$PWD/vformula.cpp \ - $$PWD/vpatternpiecedata.cpp \ - $$PWD/vpatterninfogeometry.cpp \ - $$PWD/vgrainlinegeometry.cpp \ - $$PWD/variables/vcurveclength.cpp \ - $$PWD/variables/vellipticalarcradius.cpp - -win32-msvc*:SOURCES += $$PWD/stable.cpp - -HEADERS += \ - $$PWD/vcontainer.h \ - $$PWD/stable.h \ - $$PWD/calculator.h \ - $$PWD/variables.h \ - $$PWD/vdetail.h \ - $$PWD/vdetail_p.h \ - $$PWD/vnodedetail.h \ - $$PWD/vnodedetail_p.h \ - $$PWD/vtranslatevars.h \ - $$PWD/variables/varcradius.h \ - $$PWD/variables/varcradius_p.h \ - $$PWD/variables/vcurveangle.h \ - $$PWD/variables/vcurvelength.h \ - $$PWD/variables/vcurvevariable.h \ - $$PWD/variables/vcurvevariable_p.h \ - $$PWD/variables/vincrement.h \ - $$PWD/variables/vincrement_p.h \ - $$PWD/variables/vinternalvariable.h \ - $$PWD/variables/vinternalvariable_p.h \ - $$PWD/variables/vlineangle.h \ - $$PWD/variables/vlineangle_p.h \ - $$PWD/variables/vlinelength.h \ - $$PWD/variables/vlinelength_p.h \ - $$PWD/variables/vmeasurement.h \ - $$PWD/variables/vmeasurement_p.h \ - $$PWD/variables/vvariable.h \ - $$PWD/variables/vvariable_p.h \ - $$PWD/vformula.h \ - $$PWD/vpatternpiecedata.h \ - $$PWD/vpatterninfogeometry.h \ - $$PWD/vgrainlinegeometry.h \ - $$PWD/variables/vcurveclength.h \ - $$PWD/variables/vellipticalarcradius.h +# ADD TO EACH PATH $$PWD VARIABLE!!!!!! +# This need for corect working file translations.pro + +SOURCES += \ + $$PWD/vcontainer.cpp \ + $$PWD/calculator.cpp \ + $$PWD/vnodedetail.cpp \ + $$PWD/vtranslatevars.cpp \ + $$PWD/variables/varcradius.cpp \ + $$PWD/variables/vcurveangle.cpp \ + $$PWD/variables/vcurvelength.cpp \ + $$PWD/variables/vcurvevariable.cpp \ + $$PWD/variables/vincrement.cpp \ + $$PWD/variables/vinternalvariable.cpp \ + $$PWD/variables/vlineangle.cpp \ + $$PWD/variables/vlinelength.cpp \ + $$PWD/variables/vmeasurement.cpp \ + $$PWD/variables/vvariable.cpp \ + $$PWD/vformula.cpp \ + $$PWD/vpatternpiecedata.cpp \ + $$PWD/vpatterninfogeometry.cpp \ + $$PWD/vgrainlinegeometry.cpp \ + $$PWD/variables/vcurveclength.cpp \ + $$PWD/variables/vellipticalarcradius.cpp \ + $$PWD/vpiece.cpp \ + $$PWD/vpiecenode.cpp \ + $$PWD/vpiecepath.cpp + +win32-msvc*:SOURCES += $$PWD/stable.cpp + +HEADERS += \ + $$PWD/vcontainer.h \ + $$PWD/stable.h \ + $$PWD/calculator.h \ + $$PWD/variables.h \ + $$PWD/vnodedetail.h \ + $$PWD/vnodedetail_p.h \ + $$PWD/vtranslatevars.h \ + $$PWD/variables/varcradius.h \ + $$PWD/variables/varcradius_p.h \ + $$PWD/variables/vcurveangle.h \ + $$PWD/variables/vcurvelength.h \ + $$PWD/variables/vcurvevariable.h \ + $$PWD/variables/vcurvevariable_p.h \ + $$PWD/variables/vincrement.h \ + $$PWD/variables/vincrement_p.h \ + $$PWD/variables/vinternalvariable.h \ + $$PWD/variables/vinternalvariable_p.h \ + $$PWD/variables/vlineangle.h \ + $$PWD/variables/vlineangle_p.h \ + $$PWD/variables/vlinelength.h \ + $$PWD/variables/vlinelength_p.h \ + $$PWD/variables/vmeasurement.h \ + $$PWD/variables/vmeasurement_p.h \ + $$PWD/variables/vvariable.h \ + $$PWD/variables/vvariable_p.h \ + $$PWD/vformula.h \ + $$PWD/vpatternpiecedata.h \ + $$PWD/vpatterninfogeometry.h \ + $$PWD/vgrainlinegeometry.h \ + $$PWD/variables/vcurveclength.h \ + $$PWD/variables/vellipticalarcradius.h \ + $$PWD/vpiece.h \ + $$PWD/vpiece_p.h \ + $$PWD/vpiecenode.h \ + $$PWD/vpiecenode_p.h \ + $$PWD/vpiecepath.h \ + $$PWD/vpiecepath_p.h diff --git a/src/libs/vpatterndb/vpiece.cpp b/src/libs/vpatterndb/vpiece.cpp new file mode 100644 index 000000000..704921167 --- /dev/null +++ b/src/libs/vpatterndb/vpiece.cpp @@ -0,0 +1,515 @@ +/************************************************************************ + ** + ** @file + ** @author Roman Telezhynskyi <dismine(at)gmail.com> + ** @date 3 11, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2016 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#include "vpiece.h" +#include "vpiece_p.h" +#include "../vgeometry/vpointf.h" +#include "../vgeometry/vabstractcurve.h" +#include "vcontainer.h" + +#include <QSharedPointer> +#include <QDebug> +#include <QPainterPath> + +//--------------------------------------------------------------------------------------------------------------------- +VPiece::VPiece() + : VAbstractPiece(), d(new VPieceData(PiecePathType::PiecePath)) +{} + +//--------------------------------------------------------------------------------------------------------------------- +VPiece::VPiece(const VPiece &piece) + : VAbstractPiece(piece), d (piece.d) +{} + +//--------------------------------------------------------------------------------------------------------------------- +VPiece &VPiece::operator=(const VPiece &piece) +{ + if ( &piece == this ) + { + return *this; + } + VAbstractPiece::operator=(piece); + d = piece.d; + return *this; +} + +//--------------------------------------------------------------------------------------------------------------------- +VPiece::~VPiece() +{} + +//--------------------------------------------------------------------------------------------------------------------- +VPiecePath VPiece::GetPath() const +{ + return d->m_path; +} + +//--------------------------------------------------------------------------------------------------------------------- +VPiecePath &VPiece::GetPath() +{ + return d->m_path; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPiece::SetPath(const VPiecePath &path) +{ + d->m_path = path; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<QPointF> VPiece::MainPathPoints(const VContainer *data) const +{ + QVector<QPointF> points = GetPath().PathPoints(data); + points = CheckLoops(CorrectEquidistantPoints(points));//A path can contains loops + return points; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<VPointF> VPiece::MainPathNodePoints(const VContainer *data) const +{ + return GetPath().PathNodePoints(data); +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<QPointF> VPiece::SeamAllowancePoints(const VContainer *data) const +{ + SCASSERT(data != nullptr); + + + if (not IsSeamAllowance()) + { + return QVector<QPointF>(); + } + + const QVector<CustomSARecord> records = GetValidRecords(); + int recordIndex = -1; + bool insertingCSA = false; + const qreal width = ToPixel(GetSAWidth(), *data->GetPatternUnit()); + + QVector<VSAPoint> pointsEkv; + for (int i = 0; i< d->m_path.CountNodes(); ++i) + { + const VPieceNode &node = d->m_path.at(i); + switch (node.GetTypeTool()) + { + case (Tool::NodePoint): + { + if (not insertingCSA) + { + pointsEkv.append(VPiecePath::PreparePointEkv(node, data)); + + recordIndex = IsCSAStart(records, node.GetId()); + if (recordIndex != -1) + { + insertingCSA = true; + + const VPiecePath path = data->GetPiecePath(records.at(recordIndex).path); + QVector<VSAPoint> r = path.SeamAllowancePoints(data, width, records.at(recordIndex).reverse); + + if (records.at(recordIndex).includeType == PiecePathIncludeType::AsCustomSA) + { + for (int j = 0; j < r.size(); ++j) + { + r[j].SetAngleType(PieceNodeAngle::ByLength); + r[j].SetSABefore(0); + r[j].SetSAAfter(0); + } + } + + pointsEkv += r; + } + } + else + { + if (records.at(recordIndex).endPoint == node.GetId()) + { + insertingCSA = false; + recordIndex = -1; + + pointsEkv.append(VPiecePath::PreparePointEkv(node, data)); + } + } + } + break; + case (Tool::NodeArc): + case (Tool::NodeSpline): + case (Tool::NodeSplinePath): + { + if (not insertingCSA) + { + const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(node.GetId()); + + pointsEkv += VPiecePath::CurveSeamAllowanceSegment(data, d->m_path.GetNodes(), curve, i, + node.GetReverse(), width); + } + } + break; + default: + qDebug()<<"Get wrong tool type. Ignore."<< static_cast<char>(node.GetTypeTool()); + break; + } + } + + return Equidistant(pointsEkv, width); +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<QVector<QPointF>> VPiece::GetInternalPathsPoints(const VContainer *data) const +{ + QVector<QVector<QPointF>> pathsPoints; + for (int i = 0; i < d->m_internalPaths.size(); ++i) + { + const VPiecePath path = data->GetPiecePath(d->m_internalPaths.at(i)); + if (path.GetType() == PiecePathType::InternalPath) + { + pathsPoints.append(path.PathPoints(data)); + } + } + return pathsPoints; +} + +//--------------------------------------------------------------------------------------------------------------------- +QPainterPath VPiece::MainPathPath(const VContainer *data) const +{ + const QVector<QPointF> points = MainPathPoints(data); + QPainterPath path; + + if (not points.isEmpty()) + { + path.moveTo(points[0]); + for (qint32 i = 1; i < points.count(); ++i) + { + path.lineTo(points.at(i)); + } + path.lineTo(points.at(0)); + path.setFillRule(Qt::WindingFill); + } + + return path; +} + +//--------------------------------------------------------------------------------------------------------------------- +QPainterPath VPiece::SeamAllowancePath(const VContainer *data) const +{ + const QVector<QPointF> pointsEkv = SeamAllowancePoints(data); + QPainterPath ekv; + + // seam allowence + if (IsSeamAllowance()) + { + if (not pointsEkv.isEmpty()) + { + ekv.moveTo(pointsEkv.at(0)); + for (qint32 i = 1; i < pointsEkv.count(); ++i) + { + ekv.lineTo(pointsEkv.at(i)); + } + + ekv.setFillRule(Qt::WindingFill); + } + } + + return ekv; +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal VPiece::GetMx() const +{ + return d->m_mx; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPiece::SetMx(qreal value) +{ + d->m_mx = value; +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal VPiece::GetMy() const +{ + return d->m_my; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPiece::SetMy(qreal value) +{ + d->m_my = value; +} + +//--------------------------------------------------------------------------------------------------------------------- +bool VPiece::IsInLayout() const +{ + return d->m_inLayout; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPiece::SetInLayout(bool inLayout) +{ + d->m_inLayout = inLayout; +} + +//--------------------------------------------------------------------------------------------------------------------- +bool VPiece::IsUnited() const +{ + return d->m_united; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPiece::SetUnited(bool united) +{ + d->m_united = united; +} + +//--------------------------------------------------------------------------------------------------------------------- +QString VPiece::GetFormulaSAWidth() const +{ + return d->m_formulaWidth; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPiece::SetFormulaSAWidth(const QString &formula, qreal value) +{ + SetSAWidth(value); + const qreal width = GetSAWidth(); + width >= 0 ? d->m_formulaWidth = formula : d->m_formulaWidth = QLatin1String("0"); +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<quint32> VPiece::GetInternalPaths() const +{ + return d->m_internalPaths; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPiece::SetInternalPaths(const QVector<quint32> &iPaths) +{ + d->m_internalPaths = iPaths; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPiece::AppendInternalPath(quint32 path) +{ + d->m_internalPaths.append(path); +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<CustomSARecord> VPiece::GetCustomSARecords() const +{ + return d->m_customSARecords; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPiece::SetCustomSARecords(const QVector<CustomSARecord> &records) +{ + d->m_customSARecords = records; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPiece::AppendCustomSARecord(const CustomSARecord &record) +{ + d->m_customSARecords.append(record); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief MissingNodes find missing nodes in detail. When we deleted object in detail and return this detail need + * understand, what nodes need make invisible. + * @param det changed detail. + * @return list with missing nodes. + */ +QVector<quint32> VPiece::MissingNodes(const VPiece &det) const +{ + return d->m_path.MissingNodes(det.GetPath()); +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<quint32> VPiece::MissingCSAPath(const VPiece &det) const +{ + const QVector<CustomSARecord> detRecords = det.GetCustomSARecords(); + if (d->m_customSARecords.size() == detRecords.size()) //-V807 + { + return QVector<quint32>(); + } + + QSet<quint32> set1; + for (qint32 i = 0; i < d->m_customSARecords.size(); ++i) + { + set1.insert(d->m_customSARecords.at(i).path); + } + + QSet<quint32> set2; + for (qint32 j = 0; j < detRecords.size(); ++j) + { + set2.insert(detRecords.at(j).path); + } + + const QList<quint32> set3 = set1.subtract(set2).toList(); + QVector<quint32> r; + for (qint32 i = 0; i < set3.size(); ++i) + { + r.append(set3.at(i)); + } + + return r; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<quint32> VPiece::MissingInternalPaths(const VPiece &det) const +{ + const QVector<quint32> detRecords = det.GetInternalPaths(); + if (d->m_internalPaths.size() == detRecords.size()) //-V807 + { + return QVector<quint32>(); + } + + QSet<quint32> set1; + for (qint32 i = 0; i < d->m_internalPaths.size(); ++i) + { + set1.insert(d->m_internalPaths.at(i)); + } + + QSet<quint32> set2; + for (qint32 j = 0; j < detRecords.size(); ++j) + { + set2.insert(detRecords.at(j)); + } + + const QList<quint32> set3 = set1.subtract(set2).toList(); + QVector<quint32> r; + for (qint32 i = 0; i < set3.size(); ++i) + { + r.append(set3.at(i)); + } + + return r; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPiece::SetPatternPieceData(const VPatternPieceData &data) +{ + d->m_ppData = data; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Returns full access to the pattern piece data object + * @return pattern piece data object + */ +VPatternPieceData &VPiece::GetPatternPieceData() +{ + return d->m_ppData; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Returns the read only reference to the pattern piece data object + * @return pattern piece data object + */ +const VPatternPieceData &VPiece::GetPatternPieceData() const +{ + return d->m_ppData; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPiece::SetPatternInfo(const VPatternInfoGeometry &info) +{ + d->m_piPatternInfo = info; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Returns full access to the pattern info geometry object + * @return pattern info geometry object + */ +VPatternInfoGeometry &VPiece::GetPatternInfo() +{ + return d->m_piPatternInfo; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Returns the read only reference to the pattern info geometry object + * @return pattern info geometry object + */ +const VPatternInfoGeometry &VPiece::GetPatternInfo() const +{ + return d->m_piPatternInfo; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VDetail::GetGrainlineGeometry full access to the grainline geometry object + * @return reference to grainline geometry object + */ +VGrainlineGeometry &VPiece::GetGrainlineGeometry() +{ + return d->m_glGrainline; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VDetail::GetGrainlineGeometry returns the read-only reference to the grainline geometry object + * @return reference to grainline geometry object + */ +const VGrainlineGeometry &VPiece::GetGrainlineGeometry() const +{ + return d->m_glGrainline; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<CustomSARecord> VPiece::GetValidRecords() const +{ + QVector<CustomSARecord> records; + for (int i = 0; i < d->m_customSARecords.size(); ++i) + { + const CustomSARecord &record = d->m_customSARecords.at(i); + + if (record.startPoint > NULL_ID + && record.path > NULL_ID + && record.endPoint > NULL_ID + && d->m_path.indexOfNode(record.startPoint) != -1 + && d->m_path.indexOfNode(record.endPoint) != -1) + { + records.append(record); + } + } + return records; +} + +//--------------------------------------------------------------------------------------------------------------------- +int VPiece::IsCSAStart(const QVector<CustomSARecord> &records, quint32 id) +{ + for (int i = 0; i < records.size(); ++i) + { + if (records.at(i).startPoint == id) + { + return i; + } + } + + return -1; +} diff --git a/src/libs/vpatterndb/vpiece.h b/src/libs/vpatterndb/vpiece.h new file mode 100644 index 000000000..111d368c7 --- /dev/null +++ b/src/libs/vpatterndb/vpiece.h @@ -0,0 +1,120 @@ +/************************************************************************ + ** + ** @file + ** @author Roman Telezhynskyi <dismine(at)gmail.com> + ** @date 3 11, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2016 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#ifndef VPIECE_H +#define VPIECE_H + +#include <QtGlobal> +#include <QSharedDataPointer> + +#include "../vlayout/vabstractpiece.h" + +class QPainterPath; +class VPieceData; +class VPieceNode; +class QPointF; +class VPointF; +class VContainer; +template <class T> class QVector; +template <class T>class QSharedPointer; +class VAbstractCurve; +class VPiecePath; +class VPatternInfoGeometry; +class VPatternPieceData; +class VGrainlineGeometry; + +class VPiece : public VAbstractPiece +{ +public: + VPiece(); + VPiece(const VPiece &piece); + VPiece &operator=(const VPiece &piece); + virtual ~VPiece(); + + VPiecePath GetPath() const; + VPiecePath &GetPath(); + void SetPath(const VPiecePath &path); + + QVector<QPointF> MainPathPoints(const VContainer *data) const; + QVector<VPointF> MainPathNodePoints(const VContainer *data) const; + QVector<QPointF> SeamAllowancePoints(const VContainer *data) const; + + QVector<QVector<QPointF>> GetInternalPathsPoints(const VContainer *data) const; + + QPainterPath MainPathPath(const VContainer *data) const; + QPainterPath SeamAllowancePath(const VContainer *data) const; + + qreal GetMx() const; + void SetMx(qreal value); + + qreal GetMy() const; + void SetMy(qreal value); + + bool IsInLayout() const; + void SetInLayout(bool inLayout); + + bool IsUnited() const; + void SetUnited(bool united); + + QString GetFormulaSAWidth() const; + void SetFormulaSAWidth(const QString &formula, qreal value); + + QVector<quint32> GetInternalPaths() const; + void SetInternalPaths(const QVector<quint32> &iPaths); + void AppendInternalPath(quint32 path); + + QVector<CustomSARecord> GetCustomSARecords() const; + void SetCustomSARecords(const QVector<CustomSARecord> &records); + void AppendCustomSARecord(const CustomSARecord &record); + + QVector<quint32> MissingNodes(const VPiece &det) const; + QVector<quint32> MissingCSAPath(const VPiece &det) const; + QVector<quint32> MissingInternalPaths(const VPiece &det) const; + + void SetPatternPieceData(const VPatternPieceData &data); + VPatternPieceData& GetPatternPieceData(); + const VPatternPieceData& GetPatternPieceData() const; + + void SetPatternInfo(const VPatternInfoGeometry &info); + VPatternInfoGeometry& GetPatternInfo(); + const VPatternInfoGeometry& GetPatternInfo() const; + + VGrainlineGeometry& GetGrainlineGeometry(); + const VGrainlineGeometry& GetGrainlineGeometry() const; + +private: + QSharedDataPointer<VPieceData> d; + + QVector<CustomSARecord> GetValidRecords() const; + + static int IsCSAStart(const QVector<CustomSARecord> &records, quint32 id); +}; + +Q_DECLARE_TYPEINFO(VPiece, Q_MOVABLE_TYPE); + +#endif // VPIECE_H diff --git a/src/libs/vpatterndb/vdetail_p.h b/src/libs/vpatterndb/vpiece_p.h similarity index 51% rename from src/libs/vpatterndb/vdetail_p.h rename to src/libs/vpatterndb/vpiece_p.h index d3692ca24..f937e8488 100644 --- a/src/libs/vpatterndb/vdetail_p.h +++ b/src/libs/vpatterndb/vpiece_p.h @@ -1,14 +1,14 @@ /************************************************************************ ** - ** @file vdetail_p.h + ** @file ** @author Roman Telezhynskyi <dismine(at)gmail.com> - ** @date 20 8, 2014 + ** @date 3 11, 2016 ** ** @brief ** @copyright ** This source code is part of the Valentine project, a pattern making ** program, whose allow create and modeling patterns of clothing. - ** Copyright (C) 2013-2015 Valentina project + ** Copyright (C) 2016 Valentina project ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. ** ** Valentina is free software: you can redistribute it and/or modify @@ -26,66 +26,88 @@ ** *************************************************************************/ -#ifndef VDETAIL_P_H -#define VDETAIL_P_H +#ifndef VPIECE_P_H +#define VPIECE_P_H #include <QSharedData> -#include "vnodedetail.h" +#include <QVector> + +#include "../vmisc/diagnostic.h" +#include "../vmisc/def.h" +#include "vpiecenode.h" +#include "vpiecepath.h" #include "vpatternpiecedata.h" #include "vpatterninfogeometry.h" #include "vgrainlinegeometry.h" -#include "../ifc/ifcdef.h" -#include "../vmisc/diagnostic.h" QT_WARNING_PUSH QT_WARNING_DISABLE_GCC("-Weffc++") -class VDetailData : public QSharedData +class VPieceData : public QSharedData { public: - VDetailData() - :_id(NULL_ID), nodes(QVector<VNodeDetail>()), mx(0), my(0), inLayout(true) + explicit VPieceData(PiecePathType type) + : m_path(type), + m_mx(0), + m_my(0), + m_inLayout(true), + m_united(false), + m_customSARecords(), + m_internalPaths(), + m_ppData(), + m_piPatternInfo(), + m_glGrainline(), + m_formulaWidth("0") {} - explicit VDetailData(const QVector<VNodeDetail> &nodes) - :_id(NULL_ID), nodes(nodes), mx(0), my(0), inLayout(true) + VPieceData(const VPieceData &detail) + : QSharedData(detail), + m_path(detail.m_path), + m_mx(detail.m_mx), + m_my(detail.m_my), + m_inLayout(detail.m_inLayout), + m_united(detail.m_united), + m_customSARecords(detail.m_customSARecords), + m_internalPaths(detail.m_internalPaths), + m_ppData(detail.m_ppData), + m_piPatternInfo(detail.m_piPatternInfo), + m_glGrainline(detail.m_glGrainline), + m_formulaWidth(detail.m_formulaWidth) {} - VDetailData(const VDetailData &detail) - :QSharedData(detail), _id(NULL_ID), nodes(detail.nodes), mx(detail.mx), my(detail.my), - m_ppData(detail.m_ppData), m_piPatternInfo(detail.m_piPatternInfo), - m_glGrainline(detail.m_glGrainline), inLayout(detail.inLayout) - {} - - ~VDetailData() {} - - /** @brief _id id detail. */ - quint32 _id; + ~VPieceData(); /** @brief nodes list detail nodes. */ - QVector<VNodeDetail> nodes; + VPiecePath m_path; - /** @brief mx bias x axis. */ - qreal mx; + qreal m_mx; + qreal m_my; - /** @brief my bias y axis. */ - qreal my; + bool m_inLayout; + bool m_united; + + QVector<CustomSARecord> m_customSARecords; + QVector<quint32> m_internalPaths; /** @brief Pattern piece data */ VPatternPieceData m_ppData; + /** @brief Pattern info coordinates */ VPatternInfoGeometry m_piPatternInfo; - /** - * @brief m_glGrainline grainline geometry object - */ + + /** @brief m_glGrainline grainline geometry object*/ VGrainlineGeometry m_glGrainline; - bool inLayout; + QString m_formulaWidth; private: - VDetailData &operator=(const VDetailData &) Q_DECL_EQ_DELETE; + VPieceData &operator=(const VPieceData &) Q_DECL_EQ_DELETE; }; +VPieceData::~VPieceData() +{} + QT_WARNING_POP -#endif // VDETAIL_P_H +#endif // VPIECE_P_H + diff --git a/src/libs/vpatterndb/vpiecenode.cpp b/src/libs/vpatterndb/vpiecenode.cpp new file mode 100644 index 000000000..2d74cd4a5 --- /dev/null +++ b/src/libs/vpatterndb/vpiecenode.cpp @@ -0,0 +1,237 @@ +/************************************************************************ + ** + ** @file + ** @author Roman Telezhynskyi <dismine(at)gmail.com> + ** @date 3 11, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2016 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#include "vpiecenode.h" +#include "vpiecenode_p.h" +#include "vcontainer.h" +#include "calculator.h" + +#include <QDataStream> +#include <QtNumeric> + +namespace +{ +//--------------------------------------------------------------------------------------------------------------------- +qreal EvalFormula(const VContainer *data, QString formula) +{ + if (formula.isEmpty()) + { + return -1; + } + else + { + try + { + // Replace line return character with spaces for calc if exist + formula.replace("\n", " "); + QScopedPointer<Calculator> cal(new Calculator()); + const qreal result = cal->EvalFormula(data->PlainVariables(), formula); + + if (qIsInf(result) || qIsNaN(result)) + { + return -1; + } + return result; + } + catch (qmu::QmuParserError &e) + { + Q_UNUSED(e) + return -1; + } + } +} +} + +//--------------------------------------------------------------------------------------------------------------------- +VPieceNode::VPieceNode() + : d(new VPieceNodeData) +{} + +//--------------------------------------------------------------------------------------------------------------------- +VPieceNode::VPieceNode(quint32 id, Tool typeTool, bool reverse) + : d(new VPieceNodeData(id, typeTool, reverse)) +{} + +//--------------------------------------------------------------------------------------------------------------------- +VPieceNode::VPieceNode(const VPieceNode &node) + : d (node.d) +{} + +//--------------------------------------------------------------------------------------------------------------------- +VPieceNode &VPieceNode::operator=(const VPieceNode &node) +{ + if ( &node == this ) + { + return *this; + } + d = node.d; + return *this; +} + +//--------------------------------------------------------------------------------------------------------------------- +VPieceNode::~VPieceNode() +{} + +//--------------------------------------------------------------------------------------------------------------------- +quint32 VPieceNode::GetId() const +{ + return d->m_id; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPieceNode::SetId(quint32 id) +{ + d->m_id = id; +} + +//--------------------------------------------------------------------------------------------------------------------- +Tool VPieceNode::GetTypeTool() const +{ + return d->m_typeTool; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPieceNode::SetTypeTool(Tool value) +{ + d->m_typeTool = value; +} + +//--------------------------------------------------------------------------------------------------------------------- +bool VPieceNode::GetReverse() const +{ + return d->m_reverse; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPieceNode::SetReverse(bool reverse) +{ + if (d->m_typeTool != Tool::NodePoint) + { + d->m_reverse = reverse; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal VPieceNode::GetSABefore(const VContainer *data) const +{ + return EvalFormula(data, d->m_formulaWidthBefore); +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal VPieceNode::GetSABefore(const VContainer *data, Unit unit) const +{ + qreal value = EvalFormula(data, d->m_formulaWidthBefore); + if (value >= 0) + { + value = ToPixel(value, unit); + } + return value; +} + +//--------------------------------------------------------------------------------------------------------------------- +QString VPieceNode::GetFormulaSABefore() const +{ + return d->m_formulaWidthBefore; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPieceNode::SetFormulaSABefore(const QString &formula) +{ + if (d->m_typeTool == Tool::NodePoint) + { + d->m_formulaWidthBefore = formula; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal VPieceNode::GetSAAfter(const VContainer *data) const +{ + return EvalFormula(data, d->m_formulaWidthAfter); +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal VPieceNode::GetSAAfter(const VContainer *data, Unit unit) const +{ + qreal value = EvalFormula(data, d->m_formulaWidthAfter); + if (value >= 0) + { + value = ToPixel(value, unit); + } + return value; +} + +//--------------------------------------------------------------------------------------------------------------------- +QString VPieceNode::GetFormulaSAAfter() const +{ + return d->m_formulaWidthAfter; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPieceNode::SetFormulaSAAfter(const QString &formula) +{ + if (d->m_typeTool == Tool::NodePoint) + { + d->m_formulaWidthAfter = formula; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +PieceNodeAngle VPieceNode::GetAngleType() const +{ + return d->m_angleType; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPieceNode::SetAngleType(PieceNodeAngle type) +{ + if (d->m_typeTool == Tool::NodePoint) + { + d->m_angleType = type; + } +} + +// Friend functions +//--------------------------------------------------------------------------------------------------------------------- +QDataStream& operator<<(QDataStream& out, const VPieceNode& p) +{ + out << p.d->m_id << static_cast<int>(p.d->m_typeTool) << p.d->m_reverse; + return out; +} + +//--------------------------------------------------------------------------------------------------------------------- +QDataStream& operator>>(QDataStream& in, VPieceNode& p) +{ + in >> p.d->m_id; + + int type = 0; + in >> type; + p.d->m_typeTool = static_cast<Tool>(type); + + in >> p.d->m_reverse; + return in; +} diff --git a/src/libs/vpatterndb/vpiecenode.h b/src/libs/vpatterndb/vpiecenode.h new file mode 100644 index 000000000..c2e7c9b1c --- /dev/null +++ b/src/libs/vpatterndb/vpiecenode.h @@ -0,0 +1,84 @@ +/************************************************************************ + ** + ** @file + ** @author Roman Telezhynskyi <dismine(at)gmail.com> + ** @date 3 11, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2016 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#ifndef VPIECENODE_H +#define VPIECENODE_H + +#include <QtGlobal> +#include <QSharedDataPointer> +#include <QMetaType> + +#include "../vmisc/def.h" + +class VPieceNodeData; +class QDataStream; +class VContainer; + +class VPieceNode +{ +public: + VPieceNode(); + VPieceNode(quint32 id, Tool typeTool, bool reverse = false); + VPieceNode(const VPieceNode &node); + VPieceNode &operator=(const VPieceNode &node); + ~VPieceNode(); + + friend QDataStream& operator<<(QDataStream& out, const VPieceNode& p); + friend QDataStream& operator>>(QDataStream& in, VPieceNode& p); + + quint32 GetId() const; + void SetId(quint32 id); + + Tool GetTypeTool() const; + void SetTypeTool(Tool value); + + bool GetReverse() const; + void SetReverse(bool reverse); + + qreal GetSABefore(const VContainer *data) const; + qreal GetSABefore(const VContainer *data, Unit unit) const; + + QString GetFormulaSABefore() const; + void SetFormulaSABefore(const QString &formula); + + qreal GetSAAfter(const VContainer *data) const; + qreal GetSAAfter(const VContainer *data, Unit unit) const; + + QString GetFormulaSAAfter() const; + void SetFormulaSAAfter(const QString &formula); + + PieceNodeAngle GetAngleType() const; + void SetAngleType(PieceNodeAngle type); +private: + QSharedDataPointer<VPieceNodeData> d; +}; + +Q_DECLARE_METATYPE(VPieceNode) +Q_DECLARE_TYPEINFO(VPieceNode, Q_MOVABLE_TYPE); + +#endif // VPIECENODE_H diff --git a/src/libs/vpatterndb/vpiecenode_p.h b/src/libs/vpatterndb/vpiecenode_p.h new file mode 100644 index 000000000..6defef952 --- /dev/null +++ b/src/libs/vpatterndb/vpiecenode_p.h @@ -0,0 +1,110 @@ +/************************************************************************ + ** + ** @file + ** @author Roman Telezhynskyi <dismine(at)gmail.com> + ** @date 3 11, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2016 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#ifndef VPIECENODE_P_H +#define VPIECENODE_P_H + +#include <QSharedData> +#include "../ifc/ifcdef.h" +#include "../vmisc/diagnostic.h" + +QT_WARNING_PUSH +QT_WARNING_DISABLE_GCC("-Weffc++") + +class VPieceNodeData : public QSharedData +{ +public: + VPieceNodeData() + : m_id(NULL_ID), + m_typeTool(Tool::NodePoint), + m_reverse(false), + m_saBefore(-1), + m_saAfter(-1), + m_formulaWidthBefore(currentSeamAllowance), + m_formulaWidthAfter(currentSeamAllowance), + m_angleType(PieceNodeAngle::ByLength) + {} + + VPieceNodeData(quint32 id, Tool typeTool, bool reverse) + : m_id(id), + m_typeTool(typeTool), + m_reverse(reverse), + m_saBefore(-1), + m_saAfter(-1), + m_formulaWidthBefore(currentSeamAllowance), + m_formulaWidthAfter(currentSeamAllowance), + m_angleType(PieceNodeAngle::ByLength) + { + if (m_typeTool == Tool::NodePoint) + { + m_reverse = false; + } + } + + VPieceNodeData (const VPieceNodeData& node) + : QSharedData(node), + m_id(node.m_id), + m_typeTool(node.m_typeTool), + m_reverse(node.m_reverse), + m_saBefore(node.m_saBefore), + m_saAfter(node.m_saAfter), + m_formulaWidthBefore(node.m_formulaWidthBefore), + m_formulaWidthAfter(node.m_formulaWidthAfter), + m_angleType(node.m_angleType) + {} + + ~VPieceNodeData(); + + /** @brief id object id. */ + quint32 m_id; + + /** @brief typeTool type of tool */ + Tool m_typeTool; + + /** @brief reverse true if need reverse points list for node. */ + bool m_reverse; + + qreal m_saBefore; + qreal m_saAfter; + + QString m_formulaWidthBefore; + QString m_formulaWidthAfter; + + PieceNodeAngle m_angleType; + +private: + VPieceNodeData &operator=(const VPieceNodeData &) Q_DECL_EQ_DELETE; +}; + +VPieceNodeData::~VPieceNodeData() +{} + +QT_WARNING_POP + +#endif // VPIECENODE_P_H + diff --git a/src/libs/vpatterndb/vpiecepath.cpp b/src/libs/vpatterndb/vpiecepath.cpp new file mode 100644 index 000000000..80c30906f --- /dev/null +++ b/src/libs/vpatterndb/vpiecepath.cpp @@ -0,0 +1,797 @@ +/************************************************************************ + ** + ** @file + ** @author Roman Telezhynskyi <dismine(at)gmail.com> + ** @date 22 11, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2016 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#include "vpiecepath.h" +#include "vpiecepath_p.h" +#include "vcontainer.h" +#include "../vgeometry/vpointf.h" +#include "../vlayout/vabstractpiece.h" + +#include <QPainterPath> + +namespace +{ +//--------------------------------------------------------------------------------------------------------------------- +VSAPoint CurvePoint(VSAPoint candidate, const VContainer *data, const VPieceNode &node, + const QVector<QPointF> &curvePoints) +{ + if (node.GetTypeTool() == Tool::NodePoint) + { + const QPointF p = *data->GeometricObject<VPointF>(node.GetId()); + if (VAbstractCurve::IsPointOnCurve(curvePoints, p)) + { + candidate = VSAPoint(p); + candidate.SetSAAfter(node.GetSAAfter(data, *data->GetPatternUnit())); + candidate.SetSABefore(node.GetSABefore(data, *data->GetPatternUnit())); + candidate.SetAngleType(node.GetAngleType()); + } + } + return candidate; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief indexOfNode return index in list node using id object. + * @param list list nodes detail. + * @param id object (arc, point, spline, splinePath) id. + * @return index in list or -1 id can't find. + */ +int IndexOfNode(const QVector<VPieceNode> &list, quint32 id) +{ + for (int i = 0; i < list.size(); ++i) + { + if (list.at(i).GetId() == id) + { + return i; + } + } + qDebug()<<"Can't find node."; + return -1; +} +} + +//--------------------------------------------------------------------------------------------------------------------- +VPiecePath::VPiecePath() + : d(new VPiecePathData) +{} + +//--------------------------------------------------------------------------------------------------------------------- +VPiecePath::VPiecePath(PiecePathType type) + : d(new VPiecePathData(type)) +{} + +//--------------------------------------------------------------------------------------------------------------------- +VPiecePath::VPiecePath(const VPiecePath &path) + : d (path.d) +{} + +//--------------------------------------------------------------------------------------------------------------------- +VPiecePath &VPiecePath::operator=(const VPiecePath &path) +{ + if ( &path == this ) + { + return *this; + } + d = path.d; + return *this; +} + +//--------------------------------------------------------------------------------------------------------------------- +VPiecePath::~VPiecePath() +{} + +//--------------------------------------------------------------------------------------------------------------------- +void VPiecePath::Append(const VPieceNode &node) +{ + d->m_nodes.append(node); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPiecePath::Clear() +{ + d->m_nodes.clear(); +} + +//--------------------------------------------------------------------------------------------------------------------- +qint32 VPiecePath::CountNodes() const +{ + return d->m_nodes.size(); +} + +//--------------------------------------------------------------------------------------------------------------------- +VPieceNode &VPiecePath::operator[](int indx) +{ + return d->m_nodes[indx]; +} + +//--------------------------------------------------------------------------------------------------------------------- +const VPieceNode &VPiecePath::at(int indx) const +{ + return d->m_nodes.at(indx); +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<VPieceNode> VPiecePath::GetNodes() const +{ + return d->m_nodes; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPiecePath::SetNodes(const QVector<VPieceNode> &nodes) +{ + d->m_nodes = nodes; +} + +//--------------------------------------------------------------------------------------------------------------------- +PiecePathType VPiecePath::GetType() const +{ + return d->m_type; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPiecePath::SetType(PiecePathType type) +{ + d->m_type = type; +} + +//--------------------------------------------------------------------------------------------------------------------- +QString VPiecePath::GetName() const +{ + return d->m_name; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPiecePath::SetName(const QString &name) +{ + d->m_name = name; +} + +//--------------------------------------------------------------------------------------------------------------------- +Qt::PenStyle VPiecePath::GetPenType() const +{ + return d->m_penType; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPiecePath::SetPenType(const Qt::PenStyle &type) +{ + d->m_penType = type; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<QPointF> VPiecePath::PathPoints(const VContainer *data) const +{ + QVector<QPointF> points; + for (int i = 0; i < CountNodes(); ++i) + { + switch (at(i).GetTypeTool()) + { + case (Tool::NodePoint): + { + const QSharedPointer<VPointF> point = data->GeometricObject<VPointF>(at(i).GetId()); + points.append(*point); + } + break; + case (Tool::NodeArc): + case (Tool::NodeSpline): + case (Tool::NodeSplinePath): + { + const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(at(i).GetId()); + + const QPointF begin = StartSegment(data, i, at(i).GetReverse()); + const QPointF end = EndSegment(data, i, at(i).GetReverse()); + + points << curve->GetSegmentPoints(begin, end, at(i).GetReverse()); + } + break; + default: + qDebug()<<"Get wrong tool type. Ignore."<< static_cast<char>(at(i).GetTypeTool()); + break; + } + } + + return points; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<VPointF> VPiecePath::PathNodePoints(const VContainer *data) const +{ + QVector<VPointF> points; + for (int i = 0; i < CountNodes(); ++i) + { + switch (at(i).GetTypeTool()) + { + case Tool::NodePoint: + { + const QSharedPointer<VPointF> point = data->GeometricObject<VPointF>(at(i).GetId()); + points.append(*point); + } + break; + case Tool::NodeArc: + case Tool::NodeSpline: + case Tool::NodeSplinePath: + default: + break; + } + } + + return points; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<VSAPoint> VPiecePath::SeamAllowancePoints(const VContainer *data, qreal width, bool reverse) const +{ + SCASSERT(data != nullptr); + + QVector<VSAPoint> pointsEkv; + for (int i = 0; i< d->m_nodes.size(); ++i) + { + const VPieceNode &node = d->m_nodes.at(i); + switch (node.GetTypeTool()) + { + case (Tool::NodePoint): + { + pointsEkv.append(PreparePointEkv(node, data)); + } + break; + case (Tool::NodeArc): + case (Tool::NodeSpline): + case (Tool::NodeSplinePath): + { + const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(node.GetId()); + pointsEkv += CurveSeamAllowanceSegment(data, d->m_nodes, curve, i, node.GetReverse(), width); + } + break; + default: + qDebug()<<"Get wrong tool type. Ignore."<< static_cast<char>(node.GetTypeTool()); + break; + } + } + + if (reverse) + { + pointsEkv = VGObject::GetReversePoints(pointsEkv); + } + + return pointsEkv; +} + +//--------------------------------------------------------------------------------------------------------------------- +QPainterPath VPiecePath::PainterPath(const VContainer *data) const +{ + const QVector<QPointF> points = PathPoints(data); + QPainterPath path; + + if (not points.isEmpty()) + { + path.moveTo(points[0]); + for (qint32 i = 1; i < points.count(); ++i) + { + path.lineTo(points.at(i)); + } + path.setFillRule(Qt::WindingFill); + } + + return path; +} + +//--------------------------------------------------------------------------------------------------------------------- +VSAPoint VPiecePath::StartSegment(const VContainer *data, const QVector<VPieceNode> &nodes, int i, bool reverse) +{ + if (i < 0 || i > nodes.size()-1) + { + return VSAPoint(); + } + + const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(nodes.at(i).GetId()); + + const QVector<QPointF> points = curve->GetPoints(); + if (points.isEmpty()) + { + return VSAPoint(); + } + + VSAPoint begin; + reverse ? begin = VSAPoint(points.last()) : begin = VSAPoint(points.first()); + + if (nodes.size() > 1) + { + int index = 0; + i == 0 ? index = nodes.size()-1 : index = i-1; + + begin = CurvePoint(begin, data, nodes.at(index), points); + } + return begin; +} + +//--------------------------------------------------------------------------------------------------------------------- +VSAPoint VPiecePath::EndSegment(const VContainer *data, const QVector<VPieceNode> &nodes, int i, bool reverse) +{ + if (i < 0 || i > nodes.size()-1) + { + return VSAPoint(); + } + + const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(nodes.at(i).GetId()); + + const QVector<QPointF> points = curve->GetPoints(); + if (points.isEmpty()) + { + return VSAPoint(); + } + + VSAPoint end; + reverse ? end = VSAPoint(points.first()) : end = VSAPoint(points.last()); + + if (nodes.size() > 2) + { + int index = 0; + i == nodes.size() - 1 ? index = 0 : index = i+1; + + end = CurvePoint(end, data, nodes.at(index), points); + } + return end; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<quint32> VPiecePath::MissingNodes(const VPiecePath &path) const +{ + if (d->m_nodes.size() == path.CountNodes()) //-V807 + { + return QVector<quint32>(); + } + + QSet<quint32> set1; + for (qint32 i = 0; i < d->m_nodes.size(); ++i) + { + set1.insert(d->m_nodes.at(i).GetId()); + } + + QSet<quint32> set2; + for (qint32 j = 0; j < path.CountNodes(); ++j) + { + set2.insert(path.at(j).GetId()); + } + + const QList<quint32> set3 = set1.subtract(set2).toList(); + QVector<quint32> nodes; + for (qint32 i = 0; i < set3.size(); ++i) + { + const int index = indexOfNode(set3.at(i)); + if (index != -1) + { + nodes.append(d->m_nodes.at(index).GetId()); + } + } + + return nodes; +} + +//--------------------------------------------------------------------------------------------------------------------- +int VPiecePath::indexOfNode(quint32 id) const +{ + for (int i = 0; i < d->m_nodes.size(); ++i) + { + if (d->m_nodes.at(i).GetId() == id) + { + return i; + } + } + qDebug()<<"Can't find node."; + return -1; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief NodeOnEdge return nodes located on edge with index. + * @param index index of edge. + * @param p1 first node. + * @param p2 second node. + */ +void VPiecePath::NodeOnEdge(quint32 index, VPieceNode &p1, VPieceNode &p2) const +{ + const QVector<VPieceNode> list = ListNodePoint(); + if (index > static_cast<quint32>(list.size())) + { + qDebug()<<"Wrong edge index index ="<<index; + return; + } + p1 = list.at(static_cast<int>(index)); + if (index + 1 > static_cast<quint32>(list.size()) - 1) + { + p2 = list.at(0); + } + else + { + p2 = list.at(static_cast<int>(index+1)); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +bool VPiecePath::Contains(quint32 id) const +{ + for (int i = 0; i < d->m_nodes.size(); ++i) + { + if (d->m_nodes.at(i).GetId() == id) + { + return true; + } + } + return false; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief OnEdge checks if two poins located on the edge. Edge is line between two points. If between two points + * located arcs or splines ignore this. + * @param p1 id first point. + * @param p2 id second point. + * @return true - on edge, false - no. + */ +bool VPiecePath::OnEdge(quint32 p1, quint32 p2) const +{ + const QVector<VPieceNode> list = ListNodePoint(); + if (list.size() < 2) + { + qDebug()<<"Not enough points."; + return false; + } + int i = IndexOfNode(list, p1); + int j1 = 0, j2 = 0; + + if (i == list.size() - 1) + { + j1 = i-1; + j2 = 0; + } + else if (i == 0) + { + j1 = list.size() - 1; + j2 = i + 1; + } + else + { + j1 = i - 1; + j2 = i + 1; + } + + if (list.at(j1).GetId() == p2 || list.at(j2).GetId() == p2) + { + return true; + } + else + { + return false; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Edge return edge index in detail. Edge is line between two points. If between two points + * located arcs or splines ignore this. + * @param p1 id first point. + * @param p2 id second point. + * @return edge index or -1 if points don't located on edge + */ +int VPiecePath::Edge(quint32 p1, quint32 p2) const +{ + if (OnEdge(p1, p2) == false) + { + qDebug()<<"Points don't on edge."; + return -1; + } + + const QVector<VPieceNode> list = ListNodePoint(); + int i = IndexOfNode(list, p1); + int j = IndexOfNode(list, p2); + + int min = qMin(i, j); + + if (min == 0 && (i == list.size() - 1 || j == list.size() - 1)) + { + return list.size() - 1; + } + else + { + return min; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief listNodePoint return list nodes only with points. + * @return list points node. + */ +QVector<VPieceNode> VPiecePath::ListNodePoint() const +{ + QVector<VPieceNode> list; + for (int i = 0; i < d->m_nodes.size(); ++i) //-V807 + { + if (d->m_nodes.at(i).GetTypeTool() == Tool::NodePoint) + { + list.append(d->m_nodes.at(i)); + } + } + return list; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief RemoveEdge return path without edge with index. + * @param index idex of edge. + * @return path without edge with index. + */ +VPiecePath VPiecePath::RemoveEdge(quint32 index) const +{ + VPiecePath path(*this); + path.Clear(); + + // Edge can be only segment. We ignore all curves inside segments. + const quint32 edges = static_cast<quint32>(ListNodePoint().size()); + quint32 k = 0; + for (quint32 i=0; i<edges; ++i) + { + if (i == index) + { + path.Append(this->at(static_cast<int>(k))); + ++k; + } + else + { + VPieceNode p1; + VPieceNode p2; + this->NodeOnEdge(i, p1, p2); + const int j1 = this->indexOfNode(p1.GetId()); + int j2 = this->indexOfNode(p2.GetId()); + if (j2 == 0) + { + j2 = this->CountNodes(); + } + for (int j=j1; j<j2; ++j) + {// Add "segment" except last point. Inside can be curves too. + path.Append(this->at(j)); + ++k; + } + } + } + return path; +} + +//--------------------------------------------------------------------------------------------------------------------- +VSAPoint VPiecePath::StartSegment(const VContainer *data, int i, bool reverse) const +{ + return StartSegment(data, d->m_nodes, i, reverse); +} + +//--------------------------------------------------------------------------------------------------------------------- +VSAPoint VPiecePath::EndSegment(const VContainer *data, int i, bool reverse) const +{ + return EndSegment(data, d->m_nodes, i, reverse); +} + +//--------------------------------------------------------------------------------------------------------------------- +QPointF VPiecePath::NodePreviousPoint(const VContainer *data, int i) const +{ + if (i < 0 || i > d->m_nodes.size()-1) + { + return QPointF(); + } + + if (d->m_nodes.size() > 1) + { + int index = 0; + if (i == 0) + { + index = d->m_nodes.size()-1; + } + else + { + index = i-1; + } + + const VPieceNode &node = d->m_nodes.at(index); + switch (node.GetTypeTool()) + { + case (Tool::NodePoint): + return *data->GeometricObject<VPointF>(node.GetId()); + case (Tool::NodeArc): + case (Tool::NodeSpline): + case (Tool::NodeSplinePath): + { + const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(node.GetId()); + + const VSAPoint begin = StartSegment(data, d->m_nodes, index, node.GetReverse()); + const VSAPoint end = EndSegment(data, d->m_nodes, index, node.GetReverse()); + + const QVector<QPointF> points = curve->GetSegmentPoints(begin, end, node.GetReverse()); + if (points.size() > 1) + { + return points.at(points.size()-2); + } + } + break; + default: + qDebug()<<"Get wrong tool type. Ignore."<< static_cast<char>(node.GetTypeTool()); + break; + } + } + + return QPointF(); +} + +//--------------------------------------------------------------------------------------------------------------------- +QPointF VPiecePath::NodeNextPoint(const VContainer *data, int i) const +{ + QPointF point; + if (i < 0 || i > d->m_nodes.size()-1) + { + return point; + } + + if (d->m_nodes.size() > 1) + { + int index = 0; + if (i == d->m_nodes.size() - 1) + { + index = 0; + } + else + { + index = i+1; + } + + const VPieceNode &node = d->m_nodes.at(index); + switch (node.GetTypeTool()) + { + case (Tool::NodePoint): + return *data->GeometricObject<VPointF>(node.GetId()); + case (Tool::NodeArc): + case (Tool::NodeSpline): + case (Tool::NodeSplinePath): + { + const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(node.GetId()); + + const VSAPoint begin = StartSegment(data, d->m_nodes, index, node.GetReverse()); + const VSAPoint end = EndSegment(data, d->m_nodes, index, node.GetReverse()); + + const QVector<QPointF> points = curve->GetSegmentPoints(begin, end, node.GetReverse()); + if (points.size() > 1) + { + return points.at(1); + } + } + break; + default: + qDebug()<<"Get wrong tool type. Ignore."<< static_cast<char>(node.GetTypeTool()); + break; + } + } + + return point; +} + +//--------------------------------------------------------------------------------------------------------------------- +VSAPoint VPiecePath::PreparePointEkv(const VPieceNode &node, const VContainer *data) +{ + const QSharedPointer<VPointF> point = data->GeometricObject<VPointF>(node.GetId()); + VSAPoint p(point->toQPointF()); + + p.SetSAAfter(node.GetSAAfter(data, *data->GetPatternUnit())); + p.SetSABefore(node.GetSABefore(data, *data->GetPatternUnit())); + p.SetAngleType(node.GetAngleType()); + + return p; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<VSAPoint> VPiecePath::CurveSeamAllowanceSegment(const VContainer *data, const QVector<VPieceNode> &nodes, + const QSharedPointer<VAbstractCurve> &curve, int i, + bool reverse, qreal width) +{ + QVector<VSAPoint> pointsEkv; + + const VSAPoint begin = StartSegment(data, nodes, i, reverse); + const VSAPoint end = EndSegment(data, nodes, i, reverse); + + const QVector<QPointF> points = curve->GetSegmentPoints(begin, end, reverse); + if (points.isEmpty()) + { + return pointsEkv; + } + + qreal w1 = begin.GetSAAfter(); + qreal w2 = end.GetSABefore(); + if (w1 < 0 && w2 < 0) + {// no local widths + for(int i = 0; i < points.size(); ++i) + { + VSAPoint p(points.at(i)); + if (i == 0) + { // first point + p.SetSAAfter(begin.GetSAAfter()); + p.SetSABefore(begin.GetSABefore()); + p.SetAngleType(begin.GetAngleType()); + } + else if (i == points.size() - 1) + { // last point + p.SetSAAfter(end.GetSAAfter()); + p.SetSABefore(end.GetSABefore()); + p.SetAngleType(end.GetAngleType()); + } + pointsEkv.append(p); + } + } + else + { + if (w1 < 0) + { + w1 = width; + } + + if (w2 < 0) + { + w2 = width; + } + + const qreal wDiff = w2 - w1;// Difference between to local widths + const qreal fullLength = VAbstractCurve::PathLength(points); + + VSAPoint p(points.at(0));//First point in the list + p.SetSAAfter(begin.GetSAAfter()); + p.SetSABefore(begin.GetSABefore()); + p.SetAngleType(begin.GetAngleType()); + pointsEkv.append(p); + + qreal length = 0; // how much we handle + + for(int i = 1; i < points.size(); ++i) + { + p = VSAPoint(points.at(i)); + + if (i == points.size() - 1) + {// last point + p.SetSAAfter(end.GetSAAfter()); + p.SetSABefore(end.GetSABefore()); + p.SetAngleType(end.GetAngleType()); + } + else + { + length += QLineF(points.at(i-1), points.at(i)).length(); + const qreal localWidth = w1 + wDiff*(length/fullLength); + + p.SetSAAfter(localWidth); + p.SetSABefore(localWidth); + // curve points have angle type by default + } + + pointsEkv.append(p); + } + } + + return pointsEkv; +} diff --git a/src/libs/vpatterndb/vpiecepath.h b/src/libs/vpatterndb/vpiecepath.h new file mode 100644 index 000000000..40852dd53 --- /dev/null +++ b/src/libs/vpatterndb/vpiecepath.h @@ -0,0 +1,113 @@ +/************************************************************************ + ** + ** @file + ** @author Roman Telezhynskyi <dismine(at)gmail.com> + ** @date 22 11, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2016 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#ifndef VPIECEPATH_H +#define VPIECEPATH_H + +#include <QtGlobal> +#include <QSharedDataPointer> + +#include "../vmisc/def.h" + +class VPiecePathData; +class VPieceNode; +class QPointF; +class VPointF; +class VContainer; +class VSAPoint; +class QPainterPath; +class VAbstractCurve; + +class VPiecePath +{ +public: + VPiecePath(); + explicit VPiecePath(PiecePathType type); + VPiecePath(const VPiecePath &path); + VPiecePath &operator=(const VPiecePath &path); + ~VPiecePath(); + + void Append(const VPieceNode &node); + void Clear(); + qint32 CountNodes() const; + + VPieceNode & operator[](int indx); + const VPieceNode & at ( int indx ) const; + + QVector<VPieceNode> GetNodes() const; + void SetNodes(const QVector<VPieceNode> &nodes); + + PiecePathType GetType() const; + void SetType(PiecePathType type); + + QString GetName() const; + void SetName(const QString &name); + + Qt::PenStyle GetPenType() const; + void SetPenType(const Qt::PenStyle &type); + + QVector<QPointF> PathPoints(const VContainer *data) const; + QVector<VPointF> PathNodePoints(const VContainer *data) const; + QVector<VSAPoint> SeamAllowancePoints(const VContainer *data, qreal width, bool reverse) const; + + QPainterPath PainterPath(const VContainer *data) const; + + QVector<quint32> MissingNodes(const VPiecePath &path) const; + + int indexOfNode(quint32 id) const; + void NodeOnEdge(quint32 index, VPieceNode &p1, VPieceNode &p2) const; + bool Contains(quint32 id) const; + bool OnEdge(quint32 p1, quint32 p2) const; + int Edge(quint32 p1, quint32 p2) const; + + QVector<VPieceNode> ListNodePoint() const; + + VPiecePath RemoveEdge(quint32 index) const; + + VSAPoint StartSegment(const VContainer *data, int i, bool reverse) const; + VSAPoint EndSegment(const VContainer *data, int i, bool reverse) const; + + QPointF NodePreviousPoint(const VContainer *data, int i) const; + QPointF NodeNextPoint(const VContainer *data, int i) const; + + static VSAPoint StartSegment(const VContainer *data, const QVector<VPieceNode> &nodes, int i, bool reverse); + static VSAPoint EndSegment(const VContainer *data, const QVector<VPieceNode> &nodes, int i, bool reverse); + + static VSAPoint PreparePointEkv(const VPieceNode &node, const VContainer *data); + + static QVector<VSAPoint> CurveSeamAllowanceSegment(const VContainer *data, const QVector<VPieceNode> &nodes, + const QSharedPointer<VAbstractCurve> &curve, + int i, bool reverse, qreal width); + +private: + QSharedDataPointer<VPiecePathData> d; +}; + +Q_DECLARE_TYPEINFO(VPiecePath, Q_MOVABLE_TYPE); + +#endif // VPIECEPATH_H diff --git a/src/libs/vpatterndb/vpiecepath_p.h b/src/libs/vpatterndb/vpiecepath_p.h new file mode 100644 index 000000000..1ad364ce9 --- /dev/null +++ b/src/libs/vpatterndb/vpiecepath_p.h @@ -0,0 +1,83 @@ +/************************************************************************ + ** + ** @file + ** @author Roman Telezhynskyi <dismine(at)gmail.com> + ** @date 22 11, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2016 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#ifndef VPIECEPATH_P_H +#define VPIECEPATH_P_H + +#include <QSharedData> +#include <QVector> + +#include "../vmisc/diagnostic.h" +#include "vpiecenode.h" + +QT_WARNING_PUSH +QT_WARNING_DISABLE_GCC("-Weffc++") + +class VPiecePathData : public QSharedData +{ +public: + VPiecePathData() + : m_nodes(), + m_type(PiecePathType::Unknown), + m_name(), + m_penType(Qt::SolidLine) + {} + + explicit VPiecePathData(PiecePathType type) + : m_nodes(), + m_type(type), + m_name(), + m_penType(Qt::SolidLine) + {} + + VPiecePathData(const VPiecePathData &path) + : QSharedData(path), + m_nodes(path.m_nodes), + m_type(path.m_type), + m_name(path.m_name), + m_penType(path.m_penType) + {} + + ~VPiecePathData(); + + QVector<VPieceNode> m_nodes; + PiecePathType m_type; + QString m_name; + Qt::PenStyle m_penType; + +private: + VPiecePathData &operator=(const VPiecePathData &) Q_DECL_EQ_DELETE; +}; + +VPiecePathData::~VPiecePathData() +{} + +QT_WARNING_POP + +#endif // VPIECEPATH_P_H + diff --git a/src/libs/vpatterndb/vtranslatevars.cpp b/src/libs/vpatterndb/vtranslatevars.cpp index e3b51c091..2fce248c3 100644 --- a/src/libs/vpatterndb/vtranslatevars.cpp +++ b/src/libs/vpatterndb/vtranslatevars.cpp @@ -388,6 +388,8 @@ void VTranslateVars::InitVariables() "Do not add symbol _ to the end of the name")); variables.insert(seg_, translate("VTranslateVars", "Seg_", "Segment. Left symbol _ in the name")); variables.insert(currentLength, translate("VTranslateVars", "CurrentLength", "Do not add space between words")); + variables.insert(currentSeamAllowance, translate("VTranslateVars", "CurrentSeamAllowance", + "Do not add space between words")); variables.insert(c1LengthSpl_, translate("VTranslateVars", "C1LengthSpl_", "Left symbol _ in the name")); variables.insert(c2LengthSpl_, translate("VTranslateVars", "C2LengthSpl_", "Left symbol _ in the name")); variables.insert(c1LengthSplPath, translate("VTranslateVars", "C1LengthSplPath", diff --git a/src/libs/vtools/dialogs/dialogs.pri b/src/libs/vtools/dialogs/dialogs.pri index 9b3ae9de4..d21b0a6ba 100644 --- a/src/libs/vtools/dialogs/dialogs.pri +++ b/src/libs/vtools/dialogs/dialogs.pri @@ -1,129 +1,131 @@ -# ADD TO EACH PATH $$PWD VARIABLE!!!!!! -# This need for corect working file translations.pro - -HEADERS += \ - $$PWD/tooldialogs.h \ - $$PWD/tools/dialogalongline.h \ - $$PWD/tools/dialogarc.h \ - $$PWD/tools/dialogarcwithlength.h \ - $$PWD/tools/dialogbisector.h \ - $$PWD/tools/dialogcurveintersectaxis.h \ - $$PWD/tools/dialogcutarc.h \ - $$PWD/tools/dialogcutspline.h \ - $$PWD/tools/dialogcutsplinepath.h \ - $$PWD/tools/dialogdetail.h \ - $$PWD/tools/dialogendline.h \ - $$PWD/tools/dialogheight.h \ - $$PWD/tools/dialogline.h \ - $$PWD/tools/dialoglineintersect.h \ - $$PWD/tools/dialoglineintersectaxis.h \ - $$PWD/tools/dialognormal.h \ - $$PWD/tools/dialogpointfromarcandtangent.h \ - $$PWD/tools/dialogpointfromcircleandtangent.h \ - $$PWD/tools/dialogpointofcontact.h \ - $$PWD/tools/dialogpointofintersection.h \ - $$PWD/tools/dialogpointofintersectionarcs.h \ - $$PWD/tools/dialogpointofintersectioncircles.h \ - $$PWD/tools/dialogshoulderpoint.h \ - $$PWD/tools/dialogsinglepoint.h \ - $$PWD/tools/dialogspline.h \ - $$PWD/tools/dialogsplinepath.h \ - $$PWD/tools/dialogtool.h \ - $$PWD/tools/dialogtriangle.h \ - $$PWD/tools/dialoguniondetails.h \ - $$PWD/support/dialogeditwrongformula.h \ - $$PWD/support/dialogundo.h \ - $$PWD/tools/dialogtruedarts.h \ - $$PWD/tools/dialogpointofintersectioncurves.h \ - $$PWD/tools/dialogcubicbezier.h \ - $$PWD/tools/dialogcubicbezierpath.h \ - $$PWD/tools/dialoggroup.h \ - $$PWD/tools/dialogrotation.h \ - $$PWD/tools/dialogflippingbyline.h \ - $$PWD/tools/dialogflippingbyaxis.h \ - $$PWD/tools/dialogmove.h \ - $$PWD/tools/dialogellipticalarc.h - - -SOURCES += \ - $$PWD/tools/dialogalongline.cpp \ - $$PWD/tools/dialogarc.cpp \ - $$PWD/tools/dialogarcwithlength.cpp \ - $$PWD/tools/dialogbisector.cpp \ - $$PWD/tools/dialogcurveintersectaxis.cpp \ - $$PWD/tools/dialogcutarc.cpp \ - $$PWD/tools/dialogcutspline.cpp \ - $$PWD/tools/dialogcutsplinepath.cpp \ - $$PWD/tools/dialogdetail.cpp \ - $$PWD/tools/dialogendline.cpp \ - $$PWD/tools/dialogheight.cpp \ - $$PWD/tools/dialogline.cpp \ - $$PWD/tools/dialoglineintersect.cpp \ - $$PWD/tools/dialoglineintersectaxis.cpp \ - $$PWD/tools/dialognormal.cpp \ - $$PWD/tools/dialogpointfromarcandtangent.cpp \ - $$PWD/tools/dialogpointfromcircleandtangent.cpp \ - $$PWD/tools/dialogpointofcontact.cpp \ - $$PWD/tools/dialogpointofintersection.cpp \ - $$PWD/tools/dialogpointofintersectionarcs.cpp \ - $$PWD/tools/dialogpointofintersectioncircles.cpp \ - $$PWD/tools/dialogshoulderpoint.cpp \ - $$PWD/tools/dialogsinglepoint.cpp \ - $$PWD/tools/dialogspline.cpp \ - $$PWD/tools/dialogsplinepath.cpp \ - $$PWD/tools/dialogtool.cpp \ - $$PWD/tools/dialogtriangle.cpp \ - $$PWD/tools/dialoguniondetails.cpp \ - $$PWD/support/dialogeditwrongformula.cpp \ - $$PWD/support/dialogundo.cpp \ - $$PWD/tools/dialogtruedarts.cpp \ - $$PWD/tools/dialogpointofintersectioncurves.cpp \ - $$PWD/tools/dialogcubicbezier.cpp \ - $$PWD/tools/dialogcubicbezierpath.cpp \ - $$PWD/tools/dialoggroup.cpp \ - $$PWD/tools/dialogrotation.cpp \ - $$PWD/tools/dialogflippingbyline.cpp \ - $$PWD/tools/dialogflippingbyaxis.cpp \ - $$PWD/tools/dialogmove.cpp \ - $$PWD/tools/dialogellipticalarc.cpp - -FORMS += \ - $$PWD/tools/dialogalongline.ui \ - $$PWD/tools/dialogarc.ui \ - $$PWD/tools/dialogarcwithlength.ui \ - $$PWD/tools/dialogbisector.ui \ - $$PWD/tools/dialogcurveintersectaxis.ui \ - $$PWD/tools/dialogcutarc.ui \ - $$PWD/tools/dialogcutspline.ui \ - $$PWD/tools/dialogcutsplinepath.ui \ - $$PWD/tools/dialogdetail.ui \ - $$PWD/tools/dialogendline.ui \ - $$PWD/tools/dialogheight.ui \ - $$PWD/tools/dialogline.ui \ - $$PWD/tools/dialoglineintersect.ui \ - $$PWD/tools/dialoglineintersectaxis.ui \ - $$PWD/tools/dialognormal.ui \ - $$PWD/tools/dialogpointfromarcandtangent.ui \ - $$PWD/tools/dialogpointfromcircleandtangent.ui \ - $$PWD/tools/dialogpointofcontact.ui \ - $$PWD/tools/dialogpointofintersection.ui \ - $$PWD/tools/dialogpointofintersectionarcs.ui \ - $$PWD/tools/dialogpointofintersectioncircles.ui \ - $$PWD/tools/dialogshoulderpoint.ui \ - $$PWD/tools/dialogsinglepoint.ui \ - $$PWD/tools/dialogspline.ui \ - $$PWD/tools/dialogsplinepath.ui \ - $$PWD/tools/dialogtriangle.ui \ - $$PWD/tools/dialoguniondetails.ui \ - $$PWD/support/dialogeditwrongformula.ui \ - $$PWD/support/dialogundo.ui \ - $$PWD/tools/dialogtruedarts.ui \ - $$PWD/tools/dialogpointofintersectioncurves.ui \ - $$PWD/tools/dialogcubicbezier.ui \ - $$PWD/tools/dialogcubicbezierpath.ui \ - $$PWD/tools/dialoggroup.ui \ - $$PWD/tools/dialogrotation.ui \ - $$PWD/tools/dialogflippingbyline.ui \ - $$PWD/tools/dialogflippingbyaxis.ui \ - $$PWD/tools/dialogmove.ui \ - $$PWD/tools/dialogellipticalarc.ui +# ADD TO EACH PATH $$PWD VARIABLE!!!!!! +# This need for corect working file translations.pro + +HEADERS += \ + $$PWD/tooldialogs.h \ + $$PWD/tools/dialogalongline.h \ + $$PWD/tools/dialogarc.h \ + $$PWD/tools/dialogarcwithlength.h \ + $$PWD/tools/dialogbisector.h \ + $$PWD/tools/dialogcurveintersectaxis.h \ + $$PWD/tools/dialogcutarc.h \ + $$PWD/tools/dialogcutspline.h \ + $$PWD/tools/dialogcutsplinepath.h \ + $$PWD/tools/dialogendline.h \ + $$PWD/tools/dialogheight.h \ + $$PWD/tools/dialogline.h \ + $$PWD/tools/dialoglineintersect.h \ + $$PWD/tools/dialoglineintersectaxis.h \ + $$PWD/tools/dialognormal.h \ + $$PWD/tools/dialogpointfromarcandtangent.h \ + $$PWD/tools/dialogpointfromcircleandtangent.h \ + $$PWD/tools/dialogpointofcontact.h \ + $$PWD/tools/dialogpointofintersection.h \ + $$PWD/tools/dialogpointofintersectionarcs.h \ + $$PWD/tools/dialogpointofintersectioncircles.h \ + $$PWD/tools/dialogshoulderpoint.h \ + $$PWD/tools/dialogsinglepoint.h \ + $$PWD/tools/dialogspline.h \ + $$PWD/tools/dialogsplinepath.h \ + $$PWD/tools/dialogtool.h \ + $$PWD/tools/dialogtriangle.h \ + $$PWD/tools/dialoguniondetails.h \ + $$PWD/support/dialogeditwrongformula.h \ + $$PWD/support/dialogundo.h \ + $$PWD/tools/dialogtruedarts.h \ + $$PWD/tools/dialogpointofintersectioncurves.h \ + $$PWD/tools/dialogcubicbezier.h \ + $$PWD/tools/dialogcubicbezierpath.h \ + $$PWD/tools/dialoggroup.h \ + $$PWD/tools/dialogrotation.h \ + $$PWD/tools/dialogflippingbyline.h \ + $$PWD/tools/dialogflippingbyaxis.h \ + $$PWD/tools/dialogmove.h \ + $$PWD/tools/dialogellipticalarc.h \ + $$PWD/tools/dialogseamallowance.h \ + $$PWD/tools/dialogpiecepath.h + +SOURCES += \ + $$PWD/tools/dialogalongline.cpp \ + $$PWD/tools/dialogarc.cpp \ + $$PWD/tools/dialogarcwithlength.cpp \ + $$PWD/tools/dialogbisector.cpp \ + $$PWD/tools/dialogcurveintersectaxis.cpp \ + $$PWD/tools/dialogcutarc.cpp \ + $$PWD/tools/dialogcutspline.cpp \ + $$PWD/tools/dialogcutsplinepath.cpp \ + $$PWD/tools/dialogendline.cpp \ + $$PWD/tools/dialogheight.cpp \ + $$PWD/tools/dialogline.cpp \ + $$PWD/tools/dialoglineintersect.cpp \ + $$PWD/tools/dialoglineintersectaxis.cpp \ + $$PWD/tools/dialognormal.cpp \ + $$PWD/tools/dialogpointfromarcandtangent.cpp \ + $$PWD/tools/dialogpointfromcircleandtangent.cpp \ + $$PWD/tools/dialogpointofcontact.cpp \ + $$PWD/tools/dialogpointofintersection.cpp \ + $$PWD/tools/dialogpointofintersectionarcs.cpp \ + $$PWD/tools/dialogpointofintersectioncircles.cpp \ + $$PWD/tools/dialogshoulderpoint.cpp \ + $$PWD/tools/dialogsinglepoint.cpp \ + $$PWD/tools/dialogspline.cpp \ + $$PWD/tools/dialogsplinepath.cpp \ + $$PWD/tools/dialogtool.cpp \ + $$PWD/tools/dialogtriangle.cpp \ + $$PWD/tools/dialoguniondetails.cpp \ + $$PWD/support/dialogeditwrongformula.cpp \ + $$PWD/support/dialogundo.cpp \ + $$PWD/tools/dialogtruedarts.cpp \ + $$PWD/tools/dialogpointofintersectioncurves.cpp \ + $$PWD/tools/dialogcubicbezier.cpp \ + $$PWD/tools/dialogcubicbezierpath.cpp \ + $$PWD/tools/dialoggroup.cpp \ + $$PWD/tools/dialogrotation.cpp \ + $$PWD/tools/dialogflippingbyline.cpp \ + $$PWD/tools/dialogflippingbyaxis.cpp \ + $$PWD/tools/dialogmove.cpp \ + $$PWD/tools/dialogellipticalarc.cpp \ + $$PWD/tools/dialogseamallowance.cpp \ + $$PWD/tools/dialogpiecepath.cpp + +FORMS += \ + $$PWD/tools/dialogalongline.ui \ + $$PWD/tools/dialogarc.ui \ + $$PWD/tools/dialogarcwithlength.ui \ + $$PWD/tools/dialogbisector.ui \ + $$PWD/tools/dialogcurveintersectaxis.ui \ + $$PWD/tools/dialogcutarc.ui \ + $$PWD/tools/dialogcutspline.ui \ + $$PWD/tools/dialogcutsplinepath.ui \ + $$PWD/tools/dialogendline.ui \ + $$PWD/tools/dialogheight.ui \ + $$PWD/tools/dialogline.ui \ + $$PWD/tools/dialoglineintersect.ui \ + $$PWD/tools/dialoglineintersectaxis.ui \ + $$PWD/tools/dialognormal.ui \ + $$PWD/tools/dialogpointfromarcandtangent.ui \ + $$PWD/tools/dialogpointfromcircleandtangent.ui \ + $$PWD/tools/dialogpointofcontact.ui \ + $$PWD/tools/dialogpointofintersection.ui \ + $$PWD/tools/dialogpointofintersectionarcs.ui \ + $$PWD/tools/dialogpointofintersectioncircles.ui \ + $$PWD/tools/dialogshoulderpoint.ui \ + $$PWD/tools/dialogsinglepoint.ui \ + $$PWD/tools/dialogspline.ui \ + $$PWD/tools/dialogsplinepath.ui \ + $$PWD/tools/dialogtriangle.ui \ + $$PWD/tools/dialoguniondetails.ui \ + $$PWD/support/dialogeditwrongformula.ui \ + $$PWD/support/dialogundo.ui \ + $$PWD/tools/dialogtruedarts.ui \ + $$PWD/tools/dialogpointofintersectioncurves.ui \ + $$PWD/tools/dialogcubicbezier.ui \ + $$PWD/tools/dialogcubicbezierpath.ui \ + $$PWD/tools/dialoggroup.ui \ + $$PWD/tools/dialogrotation.ui \ + $$PWD/tools/dialogflippingbyline.ui \ + $$PWD/tools/dialogflippingbyaxis.ui \ + $$PWD/tools/dialogmove.ui \ + $$PWD/tools/dialogellipticalarc.ui \ + $$PWD/tools/dialogseamallowance.ui \ + $$PWD/tools/dialogpiecepath.ui diff --git a/src/libs/vtools/dialogs/support/dialogeditwrongformula.cpp b/src/libs/vtools/dialogs/support/dialogeditwrongformula.cpp index 731b3d2ab..db8590590 100644 --- a/src/libs/vtools/dialogs/support/dialogeditwrongformula.cpp +++ b/src/libs/vtools/dialogs/support/dialogeditwrongformula.cpp @@ -77,7 +77,7 @@ enum {ColumnName = 0, ColumnFullName}; //--------------------------------------------------------------------------------------------------------------------- DialogEditWrongFormula::DialogEditWrongFormula(const VContainer *data, const quint32 &toolId, QWidget *parent) :DialogTool(data, toolId, parent), ui(new Ui::DialogEditWrongFormula), formula(QString()), formulaBaseHeight(0), - checkZero(false), postfix(QString()), restoreCursor(false) + checkZero(false), checkLessThanZero(false), postfix(QString()), restoreCursor(false) { ui->setupUi(this); InitVariables(); @@ -156,7 +156,8 @@ void DialogEditWrongFormula::EvalFormula() { SCASSERT(plainTextEditFormula != nullptr) SCASSERT(labelResultCalculation != nullptr) - Eval(plainTextEditFormula->toPlainText(), flagFormula, labelResultCalculation, postfix, checkZero); + Eval(plainTextEditFormula->toPlainText(), flagFormula, labelResultCalculation, postfix, checkZero, + checkLessThanZero); } //--------------------------------------------------------------------------------------------------------------------- @@ -383,6 +384,12 @@ void DialogEditWrongFormula::setCheckZero(bool value) checkZero = value; } +//--------------------------------------------------------------------------------------------------------------------- +void DialogEditWrongFormula::setCheckLessThanZero(bool value) +{ + +} + //--------------------------------------------------------------------------------------------------------------------- void DialogEditWrongFormula::setPostfix(const QString &value) { diff --git a/src/libs/vtools/dialogs/support/dialogeditwrongformula.h b/src/libs/vtools/dialogs/support/dialogeditwrongformula.h index 247aeb33c..41b623bdd 100644 --- a/src/libs/vtools/dialogs/support/dialogeditwrongformula.h +++ b/src/libs/vtools/dialogs/support/dialogeditwrongformula.h @@ -70,6 +70,7 @@ public: QString GetFormula() const; void SetFormula(const QString &value); void setCheckZero(bool value); + void setCheckLessThanZero(bool value); void setPostfix(const QString &value); public slots: virtual void DialogAccepted() Q_DECL_OVERRIDE; @@ -109,6 +110,7 @@ private: int formulaBaseHeight; bool checkZero; + bool checkLessThanZero; QString postfix; bool restoreCursor; diff --git a/src/libs/vtools/dialogs/tooldialogs.h b/src/libs/vtools/dialogs/tooldialogs.h index 1090e905d..b42272af1 100644 --- a/src/libs/vtools/dialogs/tooldialogs.h +++ b/src/libs/vtools/dialogs/tooldialogs.h @@ -33,7 +33,7 @@ #include "tools/dialogarc.h" #include "tools/dialogarcwithlength.h" #include "tools/dialogbisector.h" -#include "tools/dialogdetail.h" +#include "tools/dialogseamallowance.h" #include "tools/dialogendline.h" #include "tools/dialogline.h" #include "tools/dialoglineintersect.h" @@ -66,6 +66,7 @@ #include "tools/dialogflippingbyaxis.h" #include "tools/dialogmove.h" #include "tools/dialogellipticalarc.h" +#include "tools/dialogpiecepath.h" #include "support/dialogeditwrongformula.h" #include "support/dialogundo.h" diff --git a/src/libs/vtools/dialogs/tools/dialogdetail.cpp b/src/libs/vtools/dialogs/tools/dialogdetail.cpp deleted file mode 100644 index 75561d9a6..000000000 --- a/src/libs/vtools/dialogs/tools/dialogdetail.cpp +++ /dev/null @@ -1,1046 +0,0 @@ -/************************************************************************ - ** - ** @file dialogdetail.cpp - ** @author Roman Telezhynskyi <dismine(at)gmail.com> - ** @date November 15, 2013 - ** - ** @brief - ** @copyright - ** This source code is part of the Valentine project, a pattern making - ** program, whose allow create and modeling patterns of clothing. - ** Copyright (C) 2013-2015 Valentina project - ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. - ** - ** Valentina is free software: you can redistribute it and/or modify - ** it under the terms of the GNU General Public License as published by - ** the Free Software Foundation, either version 3 of the License, or - ** (at your option) any later version. - ** - ** Valentina is distributed in the hope that it will be useful, - ** but WITHOUT ANY WARRANTY; without even the implied warranty of - ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - ** GNU General Public License for more details. - ** - ** You should have received a copy of the GNU General Public License - ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. - ** - *************************************************************************/ - -#include "dialogdetail.h" - -#include <QtNumeric> -#include <QBuffer> -#include <QByteArray> -#include <QCheckBox> -#include <QComboBox> -#include <QDialogButtonBox> -#include <QDoubleSpinBox> -#include <QFlags> -#include <QFont> -#include <QIcon> -#include <QLabel> -#include <QLatin1String> -#include <QLineEdit> -#include <QList> -#include <QListWidget> -#include <QListWidgetItem> -#include <QMessageLogger> -#include <QPixmap> -#include <QPointF> -#include <QPushButton> -#include <QSharedPointer> -#include <QSize> -#include <QSpinBox> -#include <QTabWidget> -#include <QToolButton> -#include <QVariant> -#include <QVector> -#include <Qt> -#include <QtDebug> -#include <new> - -#include "../ifc/xml/vdomdocument.h" -#include "../vpatterndb/vcontainer.h" -#include "../vpatterndb/calculator.h" -#include "../vgeometry/vgobject.h" -#include "../vmisc/vabstractapplication.h" -#include "dialogtool.h" -#include "vnodedetail.h" -#include "../support/dialogeditwrongformula.h" - -class QPointF; -class QWidget; - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief DialogDetail create dialog - * @param data container with data - * @param parent parent widget - */ -DialogDetail::DialogDetail(const VContainer *data, const quint32 &toolId, QWidget *parent) - :DialogTool(data, toolId, parent), ui(), detail(VDetail()), supplement(true), closed(true), flagWidth(true), - m_bAddMode(true), m_qslMaterials(), m_qslPlacements(), m_conMCP(), m_oldData(), m_oldGeom(), m_oldGrainline(), - m_iRotBaseHeight(0), m_iLenBaseHeight(0) -{ - ui.setupUi(this); - -#if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0) - ui.lineEditName->setClearButtonEnabled(true); - ui.lineEditLetter->setClearButtonEnabled(true); -#endif - - ui.checkBoxForbidFlipping->setChecked(qApp->Settings()->GetForbidWorkpieceFlipping()); - - labelEditNamePoint = ui.labelEditName; - ui.labelUnit->setText( VDomDocument::UnitsToStr(qApp->patternUnit(), true)); - ui.labelUnitX->setText(VDomDocument::UnitsToStr(qApp->patternUnit(), true)); - ui.labelUnitY->setText(VDomDocument::UnitsToStr(qApp->patternUnit(), true)); - - if(qApp->patternUnit() == Unit::Inch) - { - ui.doubleSpinBoxSeams->setDecimals(5); - } - // Default value for seam allowance is 1 cm. But pattern have different units, so just set 1 in dialog not enough. - ui.doubleSpinBoxSeams->setValue(UnitConvertor(1, Unit::Cm, qApp->patternUnit())); - - bOk = ui.buttonBox->button(QDialogButtonBox::Ok); - SCASSERT(bOk != nullptr) - connect(bOk, &QPushButton::clicked, this, &DialogTool::DialogAccepted); - QPushButton *bCancel = ui.buttonBox->button(QDialogButtonBox::Cancel); - SCASSERT(bCancel != nullptr) - connect(bCancel, &QPushButton::clicked, this, &DialogTool::DialogRejected); - - flagName = true;//We have default name of detail. - ChangeColor(labelEditNamePoint, okColor); - CheckState(); - - connect(ui.listWidget, &QListWidget::currentRowChanged, this, &DialogDetail::ObjectChanged); - connect(ui.doubleSpinBoxBiasX, static_cast<void (QDoubleSpinBox::*)(qreal)>(&QDoubleSpinBox::valueChanged), - this, &DialogDetail::BiasXChanged); - connect(ui.doubleSpinBoxBiasY, static_cast<void (QDoubleSpinBox::*)(qreal)>(&QDoubleSpinBox::valueChanged), - this, &DialogDetail::BiasYChanged); - connect(ui.doubleSpinBoxSeams, static_cast<void (QDoubleSpinBox::*)(qreal)>(&QDoubleSpinBox::valueChanged), - this, &DialogDetail::AlowenceChanged); - connect(ui.checkBoxSeams, &QCheckBox::clicked, this, &DialogDetail::ClickedSeams); - connect(ui.checkBoxClosed, &QCheckBox::clicked, this, &DialogDetail::ClickedClosed); - connect(ui.checkBoxReverse, &QCheckBox::clicked, this, &DialogDetail::ClickedReverse); - connect(ui.lineEditName, &QLineEdit::textChanged, this, &DialogDetail::NameDetailChanged); - - connect(ui.toolButtonDelete, &QToolButton::clicked, this, &DialogDetail::DeleteItem); - connect(ui.toolButtonUp, &QToolButton::clicked, this, &DialogDetail::ScrollUp); - connect(ui.toolButtonDown, &QToolButton::clicked, this, &DialogDetail::ScrollDown); - - m_qslMaterials << QApplication::translate("Detail", "Fabric", 0) - << QApplication::translate("Detail", "Lining", 0) - << QApplication::translate("Detail", "Interfacing", 0) - << QApplication::translate("Detail", "Interlining", 0); - - for (int i = 0; i < m_qslMaterials.count(); ++i) - { - ui.comboBoxMaterial->addItem(m_qslMaterials[i], i); - } - - QStringList qsl = qApp->Settings()->GetUserDefinedMaterials(); - for (int i = 0; i < qsl.count(); ++i) - { - ui.comboBoxMaterial->addItem(qsl[i], int(MaterialType::mtUserDefined)); - } - - m_qslPlacements << tr("None") << tr("Cut on fold"); - ui.comboBoxPlacement->addItems(m_qslPlacements); - ui.pushButtonRot->setIcon(QIcon("://icon/16x16/fx.png")); - ui.pushButtonLen->setIcon(QIcon("://icon/16x16/fx.png")); - - connect(ui.pushButtonAdd, &QPushButton::clicked, this, &DialogDetail::AddUpdate); - connect(ui.pushButtonCancel, &QPushButton::clicked, this, &DialogDetail::Cancel); - connect(ui.pushButtonRemove, &QPushButton::clicked, this, &DialogDetail::Remove); - connect(ui.listWidgetMCP, &QListWidget::itemClicked, this, &DialogDetail::SetEditMode); - connect(ui.comboBoxMaterial, &QComboBox::currentTextChanged, this, &DialogDetail::MaterialChanged); - connect(ui.checkBoxGrainline, &QCheckBox::toggled, this, &DialogDetail::EnableGrainlineRotation); - connect(ui.pushButtonRot, &QPushButton::clicked, this, &DialogDetail::EditFormula); - connect(ui.pushButtonLen, &QPushButton::clicked, this, &DialogDetail::EditFormula); - connect(ui.lineEditLenFormula, &QPlainTextEdit::textChanged, this, &DialogDetail::UpdateValues); - connect(ui.lineEditRotFormula, &QPlainTextEdit::textChanged, this, &DialogDetail::UpdateValues); - - connect(ui.pushButtonShowRot, &QPushButton::clicked, this, &DialogDetail::DeployRotation); - connect(ui.pushButtonShowLen, &QPushButton::clicked, this, &DialogDetail::DeployLength); - - SetAddMode(); - EnableGrainlineRotation(); - - ui.comboBoxArrow->addItem(tr("Both")); - ui.comboBoxArrow->addItem(tr("Just front")); - ui.comboBoxArrow->addItem(tr("Just rear")); - - ui.tabWidget->setCurrentIndex(0); - - m_iRotBaseHeight = ui.lineEditRotFormula->height(); - m_iLenBaseHeight = ui.lineEditLenFormula->height(); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief ChoosedObject gets id and type of selected object. Save right data and ignore wrong. - * @param id id of objects (points, arcs, splines, spline paths) - * @param type type of object - */ -void DialogDetail::ChosenObject(quint32 id, const SceneObject &type) -{ - if (type != SceneObject::Line && type != SceneObject::Detail) - { - switch (type) - { - case (SceneObject::Arc): - NewItem(id, Tool::NodeArc, NodeDetail::Contour); - break; - case (SceneObject::ElArc): - NewItem(id, Tool::NodeElArc, NodeDetail::Contour); - break; - case (SceneObject::Point): - NewItem(id, Tool::NodePoint, NodeDetail::Contour); - break; - case (SceneObject::Spline): - NewItem(id, Tool::NodeSpline, NodeDetail::Contour); - break; - case (SceneObject::SplinePath): - NewItem(id, Tool::NodeSplinePath, NodeDetail::Contour); - break; - case (SceneObject::Line): - case (SceneObject::Detail): - case (SceneObject::Unknown): - default: - qDebug()<<tr("Got wrong scene object. Ignore."); - break; - } - - if (ui.listWidget->count() > 0) - { - EnableObjectGUI(true); - } - - ValidObjects(DetailIsValid()); - // Fix issue #526. Dialog Detail is not on top after selection second object on Mac. - setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); - this->show(); - } -} - -//--------------------------------------------------------------------------------------------------------------------- -void DialogDetail::SaveData() -{ - detail.Clear(); - detail = CreateDetail(); -} - -//--------------------------------------------------------------------------------------------------------------------- -void DialogDetail::CheckState() -{ - SCASSERT(bOk != nullptr) - bOk->setEnabled(flagFormula && flagName && flagError && flagWidth); - // In case dialog hasn't apply button - if ( bApply != nullptr) - { - bApply->setEnabled(bOk->isEnabled()); - } -} - -//--------------------------------------------------------------------------------------------------------------------- -void DialogDetail::UpdateList() -{ - ui.listWidgetMCP->clear(); - for (int i = 0; i < m_conMCP.count(); ++i) - { - MaterialCutPlacement mcp = m_conMCP.at(i); - QString qsText = tr("Cut %1 of %2%3").arg(mcp.m_iCutNumber); - if (mcp.m_eMaterial < MaterialType::mtUserDefined) - { - qsText = qsText.arg(m_qslMaterials[int(mcp.m_eMaterial)]); - } - else - { - qsText = qsText.arg(mcp.m_qsMaterialUserDef); - } - if (mcp.m_ePlacement == PlacementType::ptCutOnFold) - { - qsText = qsText.arg(QLatin1String(" ") + tr("on Fold")); - } - else - { - qsText = qsText.arg(""); - } - - ui.listWidgetMCP->addItem(qsText); - } -} - -//--------------------------------------------------------------------------------------------------------------------- -void DialogDetail::AddUpdate() -{ - MaterialCutPlacement mcp; - QStringList qslUserMaterials = qApp->Settings()->GetUserDefinedMaterials(); - -#if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) - int i = ui.comboBoxMaterial->itemData(ui.comboBoxMaterial->currentIndex()).toInt(); -#else - int i = ui.comboBoxMaterial->currentData().toInt(); -#endif - QString qsMat = ui.comboBoxMaterial->currentText(); - if (i < m_qslMaterials.count() && qsMat == m_qslMaterials[i]) - { - mcp.m_eMaterial = MaterialType(i); - mcp.m_qsMaterialUserDef.clear(); - } - else - { - mcp.m_eMaterial = MaterialType::mtUserDefined; - mcp.m_qsMaterialUserDef = qsMat; - // check if we have new user defined material - bool bFound = false; - for (int i = 0; i < qslUserMaterials.count() && bFound == false; ++i) - { - if (mcp.m_qsMaterialUserDef == qslUserMaterials[i]) - { - bFound = true; - } - } - if (bFound == false) - { - qApp->Settings()->AddUserDefinedMaterial(mcp.m_qsMaterialUserDef); - qApp->Settings()->sync(); - ui.comboBoxMaterial->addItem(mcp.m_qsMaterialUserDef, int(MaterialType::mtUserDefined)); - } - } - - mcp.m_iCutNumber = ui.spinBoxCutNumber->value(); - mcp.m_ePlacement = PlacementType(ui.comboBoxPlacement->currentIndex()); - - if (m_bAddMode == true) - { - m_conMCP << mcp; - } - else - { - int iR = ui.listWidgetMCP->currentRow(); - SCASSERT(iR >= 0) - m_conMCP[iR] = mcp; - SetAddMode(); - } - UpdateList(); - ClearFields(); -} - -//--------------------------------------------------------------------------------------------------------------------- -void DialogDetail::Cancel() -{ - ClearFields(); - SetAddMode(); -} - -//--------------------------------------------------------------------------------------------------------------------- -void DialogDetail::Remove() -{ - int iR = ui.listWidgetMCP->currentRow(); - SCASSERT(iR >= 0) - m_conMCP.removeAt(iR); - UpdateList(); - ClearFields(); - SetAddMode(); -} - -//--------------------------------------------------------------------------------------------------------------------- -void DialogDetail::NameDetailChanged() -{ - SCASSERT(labelEditNamePoint != nullptr) - QLineEdit* edit = qobject_cast<QLineEdit*>(sender()); - if (edit) - { - if (edit->text().isEmpty()) - { - flagName = false; - ChangeColor(labelEditNamePoint, Qt::red); - QIcon icon(":/icons/win.icon.theme/16x16/status/dialog-warning.png"); - ui.tabWidget->setTabIcon(1, icon); - } - else - { - flagName = true; - ChangeColor(labelEditNamePoint, okColor); - QIcon icon; - ui.tabWidget->setTabIcon(1, icon); - } - } - CheckState(); -} - -//--------------------------------------------------------------------------------------------------------------------- -void DialogDetail::MaterialChanged() -{ - ui.pushButtonAdd->setEnabled(ui.comboBoxMaterial->currentText().isEmpty() == false); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief NewItem add new object (point, arc, spline or spline path) to list - * @param id id of object - * @param typeTool type of tool - * @param typeNode type of node in detail - * @param mx offset respect to x - * @param my offset respect to y - * @param reverse reverse list of points - */ -void DialogDetail::NewItem(quint32 id, const Tool &typeTool, const NodeDetail &typeNode, - qreal mx, qreal my, bool reverse) -{ - SCASSERT(id > NULL_ID) - QString name; - switch (typeTool) - { - case (Tool::NodePoint): - case (Tool::NodeArc): - case (Tool::NodeElArc): - case (Tool::NodeSpline): - case (Tool::NodeSplinePath): - { - const QSharedPointer<VGObject> obj = data->GeometricObject<VGObject>(id); - name = obj->name(); - break; - } - default: - qDebug()<<"Got wrong tools. Ignore."; - return; - } - - bool canAddNewPoint = false; - - if(ui.listWidget->count() == 0) - { - canAddNewPoint = true; - ui.toolButtonUp->setEnabled(false); - ui.toolButtonDown->setEnabled(false); - } - else - { - if(RowId(ui.listWidget->count()-1) != id) - { - canAddNewPoint = true; - } - ui.toolButtonUp->setEnabled(true); - ui.toolButtonDown->setEnabled(true); - } - - if(canAddNewPoint) - { - QListWidgetItem *item = new QListWidgetItem(name); - item->setFont(QFont("Times", 12, QFont::Bold)); - VNodeDetail node(id, typeTool, typeNode, mx, my, reverse); - item->setData(Qt::UserRole, QVariant::fromValue(node)); - ui.listWidget->addItem(item); - ui.listWidget->setCurrentRow(ui.listWidget->count()-1); - - ui.doubleSpinBoxBiasX->blockSignals(true); - ui.doubleSpinBoxBiasY->blockSignals(true); - - ui.doubleSpinBoxBiasX->setValue(qApp->fromPixel(node.getMx())); - ui.doubleSpinBoxBiasY->setValue(qApp->fromPixel(node.getMy())); - if (node.getTypeTool() == Tool::NodePoint) - { - ui.checkBoxReverse->setChecked(false); - ui.checkBoxReverse->setEnabled(false); - } - else - { - ui.checkBoxReverse->setEnabled(true); - ui.checkBoxReverse->setChecked(node.getReverse()); - } - - ui.doubleSpinBoxBiasX->blockSignals(false); - ui.doubleSpinBoxBiasY->blockSignals(false); - } -} - -//--------------------------------------------------------------------------------------------------------------------- -VDetail DialogDetail::CreateDetail() const -{ - VDetail detail; - for (qint32 i = 0; i < ui.listWidget->count(); ++i) - { - QListWidgetItem *item = ui.listWidget->item(i); - detail.append( qvariant_cast<VNodeDetail>(item->data(Qt::UserRole))); - } - detail.setWidth(ui.doubleSpinBoxSeams->value()); - detail.setName(ui.lineEditName->text()); - detail.setSeamAllowance(supplement); - detail.setClosed(closed); - detail.setForbidFlipping(ui.checkBoxForbidFlipping->isChecked()); - - detail.GetPatternPieceData().SetLetter(ui.lineEditLetter->text()); - - for (int i = 0; i < m_conMCP.count(); ++i) - { - detail.GetPatternPieceData().Append(m_conMCP[i]); - } - - detail.GetPatternPieceData().SetPos(m_oldData.GetPos()); - detail.GetPatternPieceData().SetLabelWidth(m_oldData.GetLabelWidth()); - detail.GetPatternPieceData().SetLabelHeight(m_oldData.GetLabelHeight()); - detail.GetPatternPieceData().SetFontSize(m_oldData.GetFontSize()); - detail.GetPatternPieceData().SetRotation(m_oldData.GetRotation()); - detail.GetPatternPieceData().SetVisible(ui.checkBoxDetail->isChecked()); - - detail.GetPatternInfo() = m_oldGeom; - detail.GetPatternInfo().SetVisible(ui.checkBoxPattern->isChecked()); - - detail.GetGrainlineGeometry() = m_oldGrainline; - detail.GetGrainlineGeometry().SetVisible(ui.checkBoxGrainline->isChecked()); - detail.GetGrainlineGeometry().SetRotation(ui.lineEditRotFormula->toPlainText()); - detail.GetGrainlineGeometry().SetLength(ui.lineEditLenFormula->toPlainText()); - VGrainlineGeometry::ArrowType eAT = VGrainlineGeometry::ArrowType(ui.comboBoxArrow->currentIndex()); - detail.GetGrainlineGeometry().SetArrowType(eAT); - - return detail; -} - -//--------------------------------------------------------------------------------------------------------------------- -void DialogDetail::ValidObjects(bool value) -{ - flagError = value; - CheckState(); -} - -//--------------------------------------------------------------------------------------------------------------------- -void DialogDetail::EnableObjectGUI(bool value) -{ - ui.toolButtonDelete->setEnabled(value); - ui.doubleSpinBoxBiasX->setEnabled(value); - ui.doubleSpinBoxBiasY->setEnabled(value); - - if (value == false) - { - ui.checkBoxReverse->setEnabled(value); - } -} - -//--------------------------------------------------------------------------------------------------------------------- -quint32 DialogDetail::RowId(int i) const -{ - const QListWidgetItem *rowItem = ui.listWidget->item(i); - SCASSERT(rowItem != nullptr) - const VNodeDetail rowNode = qvariant_cast<VNodeDetail>(rowItem->data(Qt::UserRole)); - return rowNode.getId(); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief setDetails set detail - * @param value detail - */ -void DialogDetail::setDetail(const VDetail &value) -{ - detail = value; - ui.listWidget->clear(); - for (int i = 0; i < detail.CountNode(); ++i) - { - const VNodeDetail &node = detail.at(i); - NewItem(node.getId(), node.getTypeTool(), node.getTypeNode(), node.getMx(), - node.getMy(), node.getReverse()); - } - ui.lineEditName->setText(detail.getName()); - ui.checkBoxSeams->setChecked(detail.getSeamAllowance()); - ui.checkBoxClosed->setChecked(detail.getClosed()); - ui.checkBoxForbidFlipping->setChecked(detail.getForbidFlipping()); - ClickedClosed(detail.getClosed()); - ClickedSeams(detail.getSeamAllowance()); - ui.doubleSpinBoxSeams->setValue(detail.getWidth()); - ui.listWidget->setCurrentRow(0); - ui.listWidget->setFocus(Qt::OtherFocusReason); - ui.toolButtonDelete->setEnabled(true); - - ui.lineEditLetter->setText(detail.GetPatternPieceData().GetLetter()); - ui.checkBoxDetail->setChecked(detail.GetPatternPieceData().IsVisible()); - ui.checkBoxPattern->setChecked(detail.GetPatternInfo().IsVisible()); - - m_conMCP.clear(); - for (int i = 0; i < detail.GetPatternPieceData().GetMCPCount(); ++i) - { - m_conMCP << detail.GetPatternPieceData().GetMCP(i); - } - - UpdateList(); - - ui.checkBoxGrainline->setChecked(detail.GetGrainlineGeometry().IsVisible()); - ui.lineEditRotFormula->setPlainText(detail.GetGrainlineGeometry().GetRotation()); - ui.lineEditLenFormula->setPlainText(detail.GetGrainlineGeometry().GetLength()); - ui.comboBoxArrow->setCurrentIndex(int(detail.GetGrainlineGeometry().GetArrowType())); - - m_oldData = detail.GetPatternPieceData(); - m_oldGeom = detail.GetPatternInfo(); - m_oldGrainline = detail.GetGrainlineGeometry(); - - ValidObjects(DetailIsValid()); - EnableGrainlineRotation(); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief BiasXChanged changed value of offset for object respect to x - * @param d value in mm - */ -void DialogDetail::BiasXChanged(qreal d) -{ - qint32 row = ui.listWidget->currentRow(); - QListWidgetItem *item = ui.listWidget->item( row ); - SCASSERT(item != nullptr) - VNodeDetail node = qvariant_cast<VNodeDetail>(item->data(Qt::UserRole)); - node.setMx(qApp->toPixel(d)); - item->setData(Qt::UserRole, QVariant::fromValue(node)); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief BiasYChanged changed value of offset for object respect to y - * @param d value in mm - */ -void DialogDetail::BiasYChanged(qreal d) -{ - qint32 row = ui.listWidget->currentRow(); - QListWidgetItem *item = ui.listWidget->item( row ); - SCASSERT(item != nullptr) - VNodeDetail node = qvariant_cast<VNodeDetail>(item->data(Qt::UserRole)); - node.setMy(qApp->toPixel(d)); - item->setData(Qt::UserRole, QVariant::fromValue(node)); -} - -//--------------------------------------------------------------------------------------------------------------------- -void DialogDetail::AlowenceChanged(qreal d) -{ - if (ui.doubleSpinBoxSeams->isEnabled()) - { - if (d <= 0) - { - flagWidth = false; - ChangeColor(ui.labelEditWidth, errorColor); - } - else - { - flagWidth = true; - ChangeColor(ui.labelEditWidth, okColor); - } - CheckState(); - } -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief ClickedSeams save supplement of seams for detail - * @param checked 1 - need supplement, 0 - don't need supplement - */ -void DialogDetail::ClickedSeams(bool checked) -{ - supplement = checked; - ui.checkBoxClosed->setEnabled(checked); - ui.doubleSpinBoxSeams->setEnabled(checked); - - if (checked && ui.doubleSpinBoxSeams->value() <= 0) - { - flagWidth = false; - ChangeColor(ui.labelEditWidth, errorColor); - } - else - { - flagWidth = true; - ChangeColor(ui.labelEditWidth, okColor); - } - CheckState(); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief ClickedClosed save closed equdistant or not - * @param checked 1 - closed, 0 - don't closed - */ -void DialogDetail::ClickedClosed(bool checked) -{ - closed = checked; -} - -//--------------------------------------------------------------------------------------------------------------------- -void DialogDetail::ClickedReverse(bool checked) -{ - qint32 row = ui.listWidget->currentRow(); - QListWidgetItem *item = ui.listWidget->item( row ); - SCASSERT(item != nullptr) - VNodeDetail node = qvariant_cast<VNodeDetail>(item->data(Qt::UserRole)); - node.setReverse(checked); - item->setData(Qt::UserRole, QVariant::fromValue(node)); - ValidObjects(DetailIsValid()); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief ObjectChanged changed new object (point, arc, spline or spline path) form list - * @param row number of row - */ -void DialogDetail::ObjectChanged(int row) -{ - if (ui.listWidget->count() == 0 || row == -1 || row >= ui.listWidget->count()) - { - return; - } - const QListWidgetItem *item = ui.listWidget->item( row ); - SCASSERT(item != nullptr) - const VNodeDetail node = qvariant_cast<VNodeDetail>(item->data(Qt::UserRole)); - ui.doubleSpinBoxBiasX->setValue(qApp->fromPixel(node.getMx())); - ui.doubleSpinBoxBiasY->setValue(qApp->fromPixel(node.getMy())); - if (node.getTypeTool() == Tool::NodePoint) - { - ui.checkBoxReverse->setChecked(false); - ui.checkBoxReverse->setEnabled(false); - } - else - { - ui.checkBoxReverse->setEnabled(true); - ui.checkBoxReverse->setChecked(node.getReverse()); - } -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief DeleteItem delete item from list - */ -void DialogDetail::DeleteItem() -{ - if (ui.listWidget->count() == 1) - { - EnableObjectGUI(false); - } - - delete ui.listWidget->item(ui.listWidget->currentRow()); - ValidObjects(DetailIsValid()); - - if(ui.listWidget->count() < 2) - { - ui.toolButtonUp->setEnabled(false); - ui.toolButtonDown->setEnabled(false); - } - else - { - ui.toolButtonUp->setEnabled(true); - ui.toolButtonDown->setEnabled(true); - } -} - -//--------------------------------------------------------------------------------------------------------------------- -void DialogDetail::ScrollUp() -{ - if (ui.listWidget->count() > 1) - { - QListWidgetItem *item = ui.listWidget->takeItem(0); - ui.listWidget->addItem(item); - ValidObjects(DetailIsValid()); - } -} - -//--------------------------------------------------------------------------------------------------------------------- -void DialogDetail::ScrollDown() -{ - if (ui.listWidget->count() > 1) - { - QListWidgetItem *item = ui.listWidget->takeItem(ui.listWidget->count()-1); - ui.listWidget->insertItem(0, item); - ValidObjects(DetailIsValid()); - } -} - -//--------------------------------------------------------------------------------------------------------------------- -bool DialogDetail::DetailIsValid() const -{ - const QIcon icon = QIcon::fromTheme("dialog-warning", - QIcon(":/icons/win.icon.theme/16x16/status/dialog-warning.png")); - - const QPixmap pixmap = icon.pixmap(QSize(16, 16)); - QByteArray byteArray; - QBuffer buffer(&byteArray); - pixmap.save(&buffer, "PNG"); - QString url = QString("<img src=\"data:image/png;base64,") + byteArray.toBase64() + QLatin1String("\"/> "); - - if(CreateDetail().ContourPoints(data).count() < 3) - { - url += tr("You need more points!"); - ui.helpLabel->setText(url); - return false; - } - else - { - if(not DetailIsClockwise()) - { - url += tr("You have to choose points in a clockwise direction!"); - ui.helpLabel->setText(url); - return false; - } - if (FirstPointEqualLast()) - { - url += tr("First point cannot be equal to the last point!"); - ui.helpLabel->setText(url); - return false; - } - else - { - for (int i=0, sz = ui.listWidget->count()-1; i<sz; ++i) - { - if (RowId(i) == RowId(i+1)) - { - url += tr("You have double points!"); - ui.helpLabel->setText(url); - return false; - } - } - } - } - ui.helpLabel->setText(tr("Ready!")); - return true; -} - -//--------------------------------------------------------------------------------------------------------------------- -bool DialogDetail::FirstPointEqualLast() const -{ - if (ui.listWidget->count() > 1) - { - if (RowId(0) == RowId(ui.listWidget->count()-1)) - { - return true; - } - else - { - return false; - } - } - return false; -} - -//--------------------------------------------------------------------------------------------------------------------- -bool DialogDetail::DetailIsClockwise() const -{ - const QVector<QPointF> points = CreateDetail().ContourPoints(data); - - if(points.count() < 3) - { - return false; - } - - const qreal res = VDetail::SumTrapezoids(points); - if (res < 0) - { - return true; - } - return false; -} - -//--------------------------------------------------------------------------------------------------------------------- -void DialogDetail::ClearFields() -{ - ui.comboBoxMaterial->setCurrentIndex(0); - ui.spinBoxCutNumber->setValue(0); - ui.comboBoxPlacement->setCurrentIndex(0); -} - -//--------------------------------------------------------------------------------------------------------------------- -void DialogDetail::UpdateValues() -{ - QPlainTextEdit* apleSender[2]; - apleSender[0] = ui.lineEditRotFormula; - apleSender[1] = ui.lineEditLenFormula; - bool bFormulasOK = true; - - for (int i = 0; i < 2; ++i) - { - QLabel* plbVal; - QLabel* plbText; - QString qsUnit; - if (i == 0) - { - plbVal = ui.labelRot; - plbText = ui.labelEditRot; - QChar ch(0x00b0); - qsUnit = ch; - } - else - { - plbVal = ui.labelLen; - plbText = ui.labelEditLen; - qsUnit = " " + VDomDocument::UnitsToStr(qApp->patternUnit()); - } - - QString qsFormula = apleSender[i]->toPlainText().simplified(); - Calculator cal; - QString qsVal; - try - { - qsFormula.replace("\n", " "); - qsFormula = qApp->TrVars()->FormulaFromUser(qsFormula, qApp->Settings()->GetOsSeparator()); - qreal dVal; - dVal = cal.EvalFormula(data->PlainVariables(), qsFormula); - if (qIsInf(dVal) == true || qIsNaN(dVal) == true) - { - throw qmu::QmuParserError(tr("Infinite/undefined result")); - } - else if (i == 1 && dVal <= 0.0) - { - throw qmu::QmuParserError(tr("Length should be positive")); - } - else - { - qsVal.setNum(dVal, 'f', 2); - ChangeColor(plbText, okColor); - } - } - catch (...) - { - qsVal.clear(); - ChangeColor(plbText, Qt::red); - bFormulasOK = false; - } - - if (qsVal.isEmpty() == false) - { - qsVal += qsUnit; - } - plbVal->setText(qsVal); - } - - bOk->setEnabled(bFormulasOK); - if (bFormulasOK == false) - { - QIcon icon(":/icons/win.icon.theme/16x16/status/dialog-warning.png"); - ui.tabWidget->setTabIcon(2, icon); - } - else - { - ResetWarning(); - } -} - -//--------------------------------------------------------------------------------------------------------------------- -void DialogDetail::SetAddMode() -{ - ui.pushButtonAdd->setText(tr("Add")); - ui.pushButtonCancel->hide(); - ui.pushButtonRemove->hide(); - ui.listWidgetMCP->setCurrentRow(-1); - m_bAddMode = true; -} - -//--------------------------------------------------------------------------------------------------------------------- -void DialogDetail::SetEditMode() -{ - int iR = ui.listWidgetMCP->currentRow(); - // this method can be called by clicking on item or by update. In the latter case there is nothing else to do! - if (iR < 0 || iR >= m_conMCP.count()) - { - return; - } - - ui.pushButtonAdd->setText(tr("Update")); - ui.pushButtonCancel->show(); - ui.pushButtonRemove->show(); - - MaterialCutPlacement mcp = m_conMCP.at(iR); - if (mcp.m_eMaterial == MaterialType::mtUserDefined) - { - int iRow = qApp->Settings()->GetUserDefinedMaterials().indexOf(mcp.m_qsMaterialUserDef); - if (iRow >= 0) - { - ui.comboBoxMaterial->setCurrentIndex(iRow + m_qslMaterials.count()); - } - else - { - ui.comboBoxMaterial->setCurrentText(mcp.m_qsMaterialUserDef); - } - } - else - { - ui.comboBoxMaterial->setCurrentIndex(int(mcp.m_eMaterial)); - } - ui.spinBoxCutNumber->setValue(mcp.m_iCutNumber); - ui.comboBoxPlacement->setCurrentIndex(int(mcp.m_ePlacement)); - - m_bAddMode = false; -} - -//--------------------------------------------------------------------------------------------------------------------- -void DialogDetail::EnableGrainlineRotation() -{ - ui.lineEditRotFormula->setEnabled(ui.checkBoxGrainline->isChecked()); - ui.lineEditLenFormula->setEnabled(ui.checkBoxGrainline->isChecked()); - ui.pushButtonRot->setEnabled(ui.checkBoxGrainline->isChecked()); - ui.pushButtonLen->setEnabled(ui.checkBoxGrainline->isChecked()); - ui.pushButtonShowLen->setEnabled(ui.checkBoxGrainline->isChecked()); - ui.pushButtonShowRot->setEnabled(ui.checkBoxGrainline->isChecked()); - - if (ui.checkBoxGrainline->isChecked() == true) - { - UpdateValues(); - } - else - { - ChangeColor(ui.labelEditLen, okColor); - ChangeColor(ui.labelEditRot, okColor); - bOk->setEnabled(true); - ResetWarning(); - } -} - -//--------------------------------------------------------------------------------------------------------------------- -void DialogDetail::EditFormula() -{ - QPlainTextEdit* pleFormula; - bool bCheckZero; - - if (sender() == ui.pushButtonLen) - { - pleFormula = ui.lineEditLenFormula; - bCheckZero = true; - } - else if (sender() == ui.pushButtonRot) - { - pleFormula = ui.lineEditRotFormula; - bCheckZero = false; - } - else - { - // should not get here! - return; - } - - DialogEditWrongFormula dlg(data, NULL_ID, this); - dlg.SetFormula(pleFormula->toPlainText()); - dlg.setCheckZero(bCheckZero); - if (dlg.exec() == QDialog::Accepted) - { - QString qsFormula = dlg.GetFormula(); - qsFormula.replace("\n", " "); - pleFormula->setPlainText(qsFormula); - UpdateValues(); - } -} - -//--------------------------------------------------------------------------------------------------------------------- -void DialogDetail::DeployRotation() -{ - DeployFormula(ui.lineEditRotFormula, ui.pushButtonShowRot, m_iRotBaseHeight); -} - -//--------------------------------------------------------------------------------------------------------------------- -void DialogDetail::DeployLength() -{ - DeployFormula(ui.lineEditLenFormula, ui.pushButtonShowLen, m_iLenBaseHeight); -} - -//--------------------------------------------------------------------------------------------------------------------- -void DialogDetail::ResetWarning() -{ - QIcon icon; - ui.tabWidget->setTabIcon(2, icon); -} - -//--------------------------------------------------------------------------------------------------------------------- - diff --git a/src/libs/vtools/dialogs/tools/dialogdetail.h b/src/libs/vtools/dialogs/tools/dialogdetail.h deleted file mode 100644 index cecc051d7..000000000 --- a/src/libs/vtools/dialogs/tools/dialogdetail.h +++ /dev/null @@ -1,151 +0,0 @@ -/************************************************************************ - ** - ** @file dialogdetail.h - ** @author Roman Telezhynskyi <dismine(at)gmail.com> - ** @date November 15, 2013 - ** - ** @brief - ** @copyright - ** This source code is part of the Valentine project, a pattern making - ** program, whose allow create and modeling patterns of clothing. - ** Copyright (C) 2013-2015 Valentina project - ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. - ** - ** Valentina is free software: you can redistribute it and/or modify - ** it under the terms of the GNU General Public License as published by - ** the Free Software Foundation, either version 3 of the License, or - ** (at your option) any later version. - ** - ** Valentina is distributed in the hope that it will be useful, - ** but WITHOUT ANY WARRANTY; without even the implied warranty of - ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - ** GNU General Public License for more details. - ** - ** You should have received a copy of the GNU General Public License - ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. - ** - *************************************************************************/ - -#ifndef DIALOGDETAIL_H -#define DIALOGDETAIL_H - -#include <qcompilerdetection.h> -#include <QMetaObject> -#include <QObject> -#include <QString> -#include <QStringList> -#include <QtGlobal> - -#include "../vmisc/def.h" -#include "../vpatterndb/vdetail.h" -#include "../vpatterndb/vpatterninfogeometry.h" -#include "../vpatterndb/vpatternpiecedata.h" -#include "../vpatterndb/vgrainlinegeometry.h" -#include "dialogtool.h" -#include "ui_dialogdetail.h" - -class QWidget; -class VContainer; - -/** - * @brief The DialogDetail class dialog for ToolDetai. Help create detail and edit option. - */ -class DialogDetail : public DialogTool -{ - Q_OBJECT -public: - DialogDetail(const VContainer *data, const quint32 &toolId, QWidget *parent = nullptr); - - VDetail getDetail() const; - void setDetail(const VDetail &value); -public slots: - virtual void ChosenObject(quint32 id, const SceneObject &type) Q_DECL_OVERRIDE; - void BiasXChanged(qreal d); - void BiasYChanged(qreal d); - void AlowenceChanged(qreal d); - void ClickedSeams(bool checked); - void ClickedClosed(bool checked); - void ClickedReverse(bool checked); - void ObjectChanged(int row); - void DeleteItem(); - void ScrollUp(); - void ScrollDown(); -protected: - /** - * @brief SaveData Put dialog data in local variables - */ - virtual void SaveData() Q_DECL_OVERRIDE; - virtual void CheckState() Q_DECL_OVERRIDE; - -protected slots: - void UpdateList(); - void AddUpdate(); - void Cancel(); - void Remove(); - -private slots: - void NameDetailChanged(); - void MaterialChanged(); -private: - - /** @brief ui keeps information about user interface */ - Ui::DialogDetail ui; - - /** @brief detail detail */ - VDetail detail; - - /** @brief supplement keep option supplement of seams */ - bool supplement; - - /** @brief closed keep option about equdistant (closed or not) */ - bool closed; - bool flagWidth; - bool m_bAddMode; - - QStringList m_qslMaterials; - QStringList m_qslPlacements; - // temporary container for Material/Cut/Placement 3-tuples - MCPContainer m_conMCP; - VPatternPieceData m_oldData; - VPatternInfoGeometry m_oldGeom; - VGrainlineGeometry m_oldGrainline; - int m_iRotBaseHeight; - int m_iLenBaseHeight; - - - bool DetailIsValid() const; - bool FirstPointEqualLast() const; - bool DetailIsClockwise() const; - - void NewItem(quint32 id, const Tool &typeTool, const NodeDetail &typeNode, - qreal mx = 0, qreal my = 0, bool reverse = false); - VDetail CreateDetail() const; - void ValidObjects(bool value); - void EnableObjectGUI(bool value); - - void ClearFields(); - - quint32 RowId(int i) const; - -private slots: - void UpdateValues(); - void SetAddMode(); - void SetEditMode(); - void EnableGrainlineRotation(); - void EditFormula(); - void DeployRotation(); - void DeployLength(); - void ResetWarning(); -}; - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief getDetails return detail - * @return detail - */ -inline VDetail DialogDetail::getDetail() const -{ - return detail; -} - -#endif // DIALOGDETAIL_H diff --git a/src/libs/vtools/dialogs/tools/dialogdetail.ui b/src/libs/vtools/dialogs/tools/dialogdetail.ui deleted file mode 100644 index 7198fcea0..000000000 --- a/src/libs/vtools/dialogs/tools/dialogdetail.ui +++ /dev/null @@ -1,1122 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>DialogDetail</class> - <widget class="QDialog" name="DialogDetail"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>581</width> - <height>478</height> - </rect> - </property> - <property name="windowTitle"> - <string>Seam allowance tool</string> - </property> - <property name="windowIcon"> - <iconset resource="../../../vmisc/share/resources/icon.qrc"> - <normaloff>:/icon/64x64/icon64x64.png</normaloff>:/icon/64x64/icon64x64.png</iconset> - </property> - <property name="locale"> - <locale language="English" country="UnitedStates"/> - </property> - <layout class="QVBoxLayout" name="verticalLayout_7"> - <item> - <widget class="QTabWidget" name="tabWidget"> - <property name="currentIndex"> - <number>2</number> - </property> - <widget class="QWidget" name="tab"> - <attribute name="title"> - <string>General</string> - </attribute> - <layout class="QVBoxLayout" name="verticalLayout_3"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_8"> - <item> - <widget class="QLabel" name="label_3"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string/> - </property> - <property name="pixmap"> - <pixmap resource="../../../vmisc/share/resources/icon.qrc">:/icon/32x32/clockwise.png</pixmap> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label_4"> - <property name="text"> - <string>All objects in path should follow in clockwise direction.</string> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QSplitter" name="splitter_2"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <widget class="QWidget" name="layoutWidget"> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_3"> - <property name="spacing"> - <number>6</number> - </property> - <property name="sizeConstraint"> - <enum>QLayout::SetDefaultConstraint</enum> - </property> - <property name="leftMargin"> - <number>0</number> - </property> - <property name="topMargin"> - <number>0</number> - </property> - <item> - <widget class="QLabel" name="label"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>1</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Bias X:</string> - </property> - </widget> - </item> - <item> - <widget class="QDoubleSpinBox" name="doubleSpinBoxBiasX"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> - <horstretch>1</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimum"> - <double>-900.990000000000009</double> - </property> - <property name="maximum"> - <double>900.990000000000009</double> - </property> - <property name="singleStep"> - <double>0.100000000000000</double> - </property> - <property name="value"> - <double>0.000000000000000</double> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="labelUnitX"> - <property name="text"> - <string>cm</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_4"> - <item> - <widget class="QLabel" name="label_2"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>1</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Bias Y:</string> - </property> - </widget> - </item> - <item> - <widget class="QDoubleSpinBox" name="doubleSpinBoxBiasY"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> - <horstretch>1</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimum"> - <double>-900.990000000000009</double> - </property> - <property name="maximum"> - <double>900.990000000000009</double> - </property> - <property name="singleStep"> - <double>0.100000000000000</double> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="labelUnitY"> - <property name="text"> - <string>cm</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_6"> - <item> - <widget class="QCheckBox" name="checkBoxReverse"> - <property name="text"> - <string>Reverse</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QGroupBox" name="groupBox"> - <property name="title"> - <string>Options</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QCheckBox" name="checkBoxForbidFlipping"> - <property name="toolTip"> - <string>Forbid piece be mirrored in a layout.</string> - </property> - <property name="text"> - <string>Forbid flipping</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="checkBoxSeams"> - <property name="text"> - <string>Seam allowance</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_2"> - <item> - <widget class="QLabel" name="labelEditWidth"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>1</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="locale"> - <locale language="English" country="UnitedStates"/> - </property> - <property name="text"> - <string>Width:</string> - </property> - </widget> - </item> - <item> - <widget class="QDoubleSpinBox" name="doubleSpinBoxSeams"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> - <horstretch>1</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="maximum"> - <double>900.990000000000009</double> - </property> - <property name="singleStep"> - <double>0.100000000000000</double> - </property> - <property name="value"> - <double>1.000000000000000</double> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="labelUnit"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>cm</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QCheckBox" name="checkBoxClosed"> - <property name="text"> - <string>Closed</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_16"> - <property name="sizeConstraint"> - <enum>QLayout::SetFixedSize</enum> - </property> - <property name="leftMargin"> - <number>10</number> - </property> - <property name="topMargin"> - <number>10</number> - </property> - <property name="rightMargin"> - <number>10</number> - </property> - <property name="bottomMargin"> - <number>10</number> - </property> - <item alignment="Qt::AlignLeft"> - <widget class="QToolButton" name="toolButtonDelete"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="text"> - <string>Delete</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item alignment="Qt::AlignRight"> - <widget class="QToolButton" name="toolButtonDown"> - <property name="toolTip"> - <string>Scroll down the list</string> - </property> - <property name="text"> - <string notr="true">...</string> - </property> - <property name="icon"> - <iconset theme="go-down"> - <normaloff/> - </iconset> - </property> - </widget> - </item> - <item alignment="Qt::AlignRight"> - <widget class="QToolButton" name="toolButtonUp"> - <property name="toolTip"> - <string>Scroll up the list</string> - </property> - <property name="text"> - <string notr="true">...</string> - </property> - <property name="icon"> - <iconset theme="go-up"> - <normaloff/> - </iconset> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - </item> - </layout> - </widget> - <widget class="QListWidget" name="listWidget"/> - </widget> - </item> - <item> - <widget class="QLabel" name="helpLabel"> - <property name="text"> - <string>Ready!</string> - </property> - <property name="textFormat"> - <enum>Qt::RichText</enum> - </property> - <property name="scaledContents"> - <bool>false</bool> - </property> - </widget> - </item> - </layout> - </widget> - <widget class="QWidget" name="tab_2"> - <attribute name="title"> - <string>Pattern piece data</string> - </attribute> - <layout class="QVBoxLayout" name="verticalLayout_5"> - <item> - <widget class="QSplitter" name="splitter"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <widget class="QWidget" name="layoutWidget1"> - <layout class="QVBoxLayout" name="verticalLayout_4"> - <item> - <layout class="QFormLayout" name="formLayout"> - <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> - </property> - <item row="0" column="0"> - <widget class="QLabel" name="label_5"> - <property name="text"> - <string>Letter:</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QLineEdit" name="lineEditLetter"> - <property name="maxLength"> - <number>3</number> - </property> - <property name="placeholderText"> - <string>Letter of pattern piece</string> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="labelEditName"> - <property name="text"> - <string>Name of detail:</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QLineEdit" name="lineEditName"> - <property name="text"> - <string>Detail</string> - </property> - <property name="maxLength"> - <number>30</number> - </property> - <property name="placeholderText"> - <string>Name can't be empty</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QGroupBox" name="groupBox_2"> - <property name="title"> - <string>Material/Cut number/Placement</string> - </property> - <layout class="QGridLayout" name="gridLayout_3"> - <item row="1" column="0"> - <widget class="QLabel" name="label_8"> - <property name="text"> - <string>Cut number:</string> - </property> - </widget> - </item> - <item row="0" column="0" colspan="2"> - <widget class="QLabel" name="label_7"> - <property name="text"> - <string>Material type:</string> - </property> - </widget> - </item> - <item row="0" column="2" colspan="2"> - <widget class="QComboBox" name="comboBoxMaterial"> - <property name="toolTip"> - <string>You can choose one of the predefined materials or enter a new one</string> - </property> - <property name="editable"> - <bool>true</bool> - </property> - </widget> - </item> - <item row="1" column="2" colspan="2"> - <widget class="QSpinBox" name="spinBoxCutNumber"> - <property name="minimum"> - <number>1</number> - </property> - <property name="maximum"> - <number>1000</number> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QLabel" name="label_9"> - <property name="text"> - <string>Placement:</string> - </property> - </widget> - </item> - <item row="2" column="2" colspan="2"> - <widget class="QComboBox" name="comboBoxPlacement"/> - </item> - <item row="3" column="0"> - <widget class="QPushButton" name="pushButtonAdd"> - <property name="text"> - <string>Add</string> - </property> - </widget> - </item> - <item row="3" column="1" colspan="2"> - <widget class="QPushButton" name="pushButtonCancel"> - <property name="text"> - <string>Cancel</string> - </property> - </widget> - </item> - <item row="3" column="3"> - <widget class="QPushButton" name="pushButtonRemove"> - <property name="text"> - <string>Remove</string> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item> - <layout class="QVBoxLayout" name="verticalLayout_6"> - <item> - <widget class="QCheckBox" name="checkBoxDetail"> - <property name="text"> - <string>Detail label visible</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="checkBoxPattern"> - <property name="text"> - <string>Pattern label visible</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - <widget class="QListWidget" name="listWidgetMCP"> - <property name="minimumSize"> - <size> - <width>180</width> - <height>0</height> - </size> - </property> - <property name="focusPolicy"> - <enum>Qt::ClickFocus</enum> - </property> - </widget> - </widget> - </item> - </layout> - </widget> - <widget class="QWidget" name="tab_3"> - <property name="cursor"> - <cursorShape>ArrowCursor</cursorShape> - </property> - <attribute name="title"> - <string>Grainline</string> - </attribute> - <widget class="QWidget" name="horizontalLayoutWidget"> - <property name="geometry"> - <rect> - <x>10</x> - <y>10</y> - <width>541</width> - <height>41</height> - </rect> - </property> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QCheckBox" name="checkBoxGrainline"> - <property name="text"> - <string>Grainline visible</string> - </property> - </widget> - </item> - </layout> - </widget> - <widget class="QWidget" name="layoutWidget_2"> - <property name="geometry"> - <rect> - <x>10</x> - <y>60</y> - <width>541</width> - <height>41</height> - </rect> - </property> - <layout class="QHBoxLayout" name="horizontalLayout_11"> - <item alignment="Qt::AlignLeft"> - <widget class="QLabel" name="labelEditRot"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="palette"> - <palette> - <active> - <colorrole role="WindowText"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>255</red> - <green>0</green> - <blue>0</blue> - </color> - </brush> - </colorrole> - </active> - <inactive> - <colorrole role="WindowText"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>255</red> - <green>0</green> - <blue>0</blue> - </color> - </brush> - </colorrole> - </inactive> - <disabled> - <colorrole role="WindowText"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>159</red> - <green>158</green> - <blue>158</blue> - </color> - </brush> - </colorrole> - </disabled> - </palette> - </property> - <property name="text"> - <string>Rotation:</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_4"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item alignment="Qt::AlignRight"> - <widget class="QToolButton" name="pushButtonRot"> - <property name="toolTip"> - <string>Formula wizard</string> - </property> - <property name="text"> - <string notr="true">...</string> - </property> - <property name="icon"> - <iconset resource="../../../vmisc/share/resources/icon.qrc"> - <normaloff>:/icon/24x24/fx.png</normaloff>:/icon/24x24/fx.png</iconset> - </property> - <property name="iconSize"> - <size> - <width>24</width> - <height>24</height> - </size> - </property> - </widget> - </item> - <item alignment="Qt::AlignRight"> - <widget class="QLabel" name="labelEqual"> - <property name="text"> - <string/> - </property> - <property name="pixmap"> - <pixmap resource="../../../vmisc/share/resources/icon.qrc">:/icon/24x24/equal.png</pixmap> - </property> - </widget> - </item> - <item alignment="Qt::AlignRight"> - <widget class="QLabel" name="labelRot"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>87</width> - <height>0</height> - </size> - </property> - <property name="baseSize"> - <size> - <width>0</width> - <height>0</height> - </size> - </property> - <property name="toolTip"> - <string>Value</string> - </property> - <property name="text"> - <string notr="true">_</string> - </property> - </widget> - </item> - </layout> - </widget> - <widget class="QWidget" name="layoutWidget_3"> - <property name="geometry"> - <rect> - <x>10</x> - <y>110</y> - <width>541</width> - <height>41</height> - </rect> - </property> - <layout class="QHBoxLayout" name="horizontalLayout_12"> - <item> - <widget class="QPlainTextEdit" name="lineEditRotFormula"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="maximumSize"> - <size> - <width>16777215</width> - <height>28</height> - </size> - </property> - <property name="toolTip"> - <string>Calculation</string> - </property> - <property name="tabChangesFocus"> - <bool>true</bool> - </property> - <property name="plainText"> - <string notr="true"/> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="pushButtonShowRot"> - <property name="maximumSize"> - <size> - <width>18</width> - <height>18</height> - </size> - </property> - <property name="sizeIncrement"> - <size> - <width>0</width> - <height>0</height> - </size> - </property> - <property name="toolTip"> - <string><html><head/><body><p>Show full calculation in message box</p></body></html></string> - </property> - <property name="text"> - <string notr="true"/> - </property> - <property name="icon"> - <iconset theme="go-down"> - <normaloff/> - </iconset> - </property> - <property name="iconSize"> - <size> - <width>16</width> - <height>16</height> - </size> - </property> - <property name="flat"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </widget> - <widget class="QWidget" name="layoutWidget_4"> - <property name="geometry"> - <rect> - <x>10</x> - <y>160</y> - <width>541</width> - <height>41</height> - </rect> - </property> - <layout class="QHBoxLayout" name="horizontalLayout_13"> - <item alignment="Qt::AlignLeft"> - <widget class="QLabel" name="labelEditLen"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="palette"> - <palette> - <active> - <colorrole role="WindowText"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>255</red> - <green>0</green> - <blue>0</blue> - </color> - </brush> - </colorrole> - </active> - <inactive> - <colorrole role="WindowText"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>255</red> - <green>0</green> - <blue>0</blue> - </color> - </brush> - </colorrole> - </inactive> - <disabled> - <colorrole role="WindowText"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>159</red> - <green>158</green> - <blue>158</blue> - </color> - </brush> - </colorrole> - </disabled> - </palette> - </property> - <property name="text"> - <string>Length:</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_5"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item alignment="Qt::AlignRight"> - <widget class="QToolButton" name="pushButtonLen"> - <property name="toolTip"> - <string>Formula wizard</string> - </property> - <property name="text"> - <string notr="true">...</string> - </property> - <property name="icon"> - <iconset resource="../../../vmisc/share/resources/icon.qrc"> - <normaloff>:/icon/24x24/fx.png</normaloff>:/icon/24x24/fx.png</iconset> - </property> - <property name="iconSize"> - <size> - <width>24</width> - <height>24</height> - </size> - </property> - </widget> - </item> - <item alignment="Qt::AlignRight"> - <widget class="QLabel" name="labelEqual_2"> - <property name="text"> - <string/> - </property> - <property name="pixmap"> - <pixmap resource="../../../vmisc/share/resources/icon.qrc">:/icon/24x24/equal.png</pixmap> - </property> - </widget> - </item> - <item alignment="Qt::AlignRight"> - <widget class="QLabel" name="labelLen"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>87</width> - <height>0</height> - </size> - </property> - <property name="baseSize"> - <size> - <width>0</width> - <height>0</height> - </size> - </property> - <property name="toolTip"> - <string>Value</string> - </property> - <property name="text"> - <string notr="true">_</string> - </property> - </widget> - </item> - </layout> - </widget> - <widget class="QWidget" name="layoutWidget_5"> - <property name="geometry"> - <rect> - <x>10</x> - <y>210</y> - <width>541</width> - <height>41</height> - </rect> - </property> - <layout class="QHBoxLayout" name="horizontalLayout_14"> - <item> - <widget class="QPlainTextEdit" name="lineEditLenFormula"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="maximumSize"> - <size> - <width>16777215</width> - <height>28</height> - </size> - </property> - <property name="toolTip"> - <string>Calculation</string> - </property> - <property name="tabChangesFocus"> - <bool>true</bool> - </property> - <property name="plainText"> - <string notr="true"/> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="pushButtonShowLen"> - <property name="maximumSize"> - <size> - <width>18</width> - <height>18</height> - </size> - </property> - <property name="sizeIncrement"> - <size> - <width>0</width> - <height>0</height> - </size> - </property> - <property name="toolTip"> - <string><html><head/><body><p>Show full calculation in message box</p></body></html></string> - </property> - <property name="text"> - <string notr="true"/> - </property> - <property name="icon"> - <iconset theme="go-down"> - <normaloff/> - </iconset> - </property> - <property name="iconSize"> - <size> - <width>16</width> - <height>16</height> - </size> - </property> - <property name="flat"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </widget> - <widget class="QWidget" name="horizontalLayoutWidget_2"> - <property name="geometry"> - <rect> - <x>10</x> - <y>260</y> - <width>541</width> - <height>41</height> - </rect> - </property> - <layout class="QHBoxLayout" name="horizontalLayout_5"> - <item> - <widget class="QLabel" name="labelEditLen_2"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="palette"> - <palette> - <active> - <colorrole role="WindowText"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>0</red> - <green>0</green> - <blue>0</blue> - </color> - </brush> - </colorrole> - </active> - <inactive> - <colorrole role="WindowText"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>0</red> - <green>0</green> - <blue>0</blue> - </color> - </brush> - </colorrole> - </inactive> - <disabled> - <colorrole role="WindowText"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>159</red> - <green>158</green> - <blue>158</blue> - </color> - </brush> - </colorrole> - </disabled> - </palette> - </property> - <property name="text"> - <string>Arrows:</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="comboBoxArrow"/> - </item> - <item> - <spacer name="horizontalSpacer_2"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </widget> - </widget> - </widget> - </item> - <item> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons"> - <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> - </property> - </widget> - </item> - </layout> - </widget> - <tabstops> - <tabstop>lineEditName</tabstop> - <tabstop>comboBoxMaterial</tabstop> - <tabstop>spinBoxCutNumber</tabstop> - <tabstop>comboBoxPlacement</tabstop> - <tabstop>pushButtonAdd</tabstop> - <tabstop>pushButtonCancel</tabstop> - <tabstop>pushButtonRemove</tabstop> - <tabstop>toolButtonUp</tabstop> - <tabstop>listWidget</tabstop> - <tabstop>checkBoxClosed</tabstop> - <tabstop>toolButtonDelete</tabstop> - <tabstop>doubleSpinBoxBiasX</tabstop> - <tabstop>doubleSpinBoxBiasY</tabstop> - <tabstop>checkBoxReverse</tabstop> - <tabstop>checkBoxSeams</tabstop> - <tabstop>doubleSpinBoxSeams</tabstop> - <tabstop>toolButtonDown</tabstop> - <tabstop>checkBoxForbidFlipping</tabstop> - <tabstop>checkBoxDetail</tabstop> - <tabstop>checkBoxPattern</tabstop> - <tabstop>lineEditLetter</tabstop> - </tabstops> - <resources> - <include location="../../../vmisc/share/resources/icon.qrc"/> - </resources> - <connections> - <connection> - <sender>buttonBox</sender> - <signal>accepted()</signal> - <receiver>DialogDetail</receiver> - <slot>accept()</slot> - <hints> - <hint type="sourcelabel"> - <x>248</x> - <y>254</y> - </hint> - <hint type="destinationlabel"> - <x>157</x> - <y>274</y> - </hint> - </hints> - </connection> - <connection> - <sender>buttonBox</sender> - <signal>rejected()</signal> - <receiver>DialogDetail</receiver> - <slot>reject()</slot> - <hints> - <hint type="sourcelabel"> - <x>316</x> - <y>260</y> - </hint> - <hint type="destinationlabel"> - <x>286</x> - <y>274</y> - </hint> - </hints> - </connection> - </connections> -</ui> diff --git a/src/libs/vtools/dialogs/tools/dialogpiecepath.cpp b/src/libs/vtools/dialogs/tools/dialogpiecepath.cpp new file mode 100644 index 000000000..c4ca47744 --- /dev/null +++ b/src/libs/vtools/dialogs/tools/dialogpiecepath.cpp @@ -0,0 +1,970 @@ +/************************************************************************ + ** + ** @file dialogpiecepath.cpp + ** @author Roman Telezhynskyi <dismine(at)gmail.com> + ** @date 22 11, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2016 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#include "dialogpiecepath.h" +#include "ui_dialogpiecepath.h" +#include "../vpatterndb/vpiecenode.h" +#include "visualization/path/vistoolpiecepath.h" +#include "../../tools/vabstracttool.h" +#include "../../tools/vtoolseamallowance.h" +#include "../support/dialogeditwrongformula.h" + +#include <QMenu> +#include <QTimer> + +//--------------------------------------------------------------------------------------------------------------------- +DialogPiecePath::DialogPiecePath(const VContainer *data, quint32 toolId, QWidget *parent) + : DialogTool(data, toolId, parent), + ui(new Ui::DialogPiecePath), + m_showMode(false), + m_saWidth(0), + m_timerWidth(nullptr), + m_timerWidthBefore(nullptr), + m_timerWidthAfter(nullptr), + m_formulaBaseWidth(0), + m_formulaBaseWidthBefore(0), + m_formulaBaseWidthAfter(0) +{ + ui->setupUi(this); + InitOkCancel(ui); + + InitPathTab(); + InitSeamAllowanceTab(); + + flagName = true;//We have default name of piece. + flagError = PathIsValid(); + CheckState(); + + vis = new VisToolPiecePath(data); + + ui->tabWidget->removeTab(1); +} + +//--------------------------------------------------------------------------------------------------------------------- +DialogPiecePath::~DialogPiecePath() +{ + delete ui; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::EnbleShowMode(bool disable) +{ + m_showMode = disable; + ui->comboBoxType->setDisabled(m_showMode); + ui->comboBoxPiece->setDisabled(m_showMode); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::ChosenObject(quint32 id, const SceneObject &type) +{ + if (not prepare) + { + bool reverse = false; + if (QGuiApplication::keyboardModifiers() == Qt::ShiftModifier) + { + reverse = true; + } + if (id != GetLastId()) + { + switch (type) + { + case SceneObject::Arc: + NewItem(VPieceNode(id, Tool::NodeArc, reverse)); + break; + case SceneObject::Point: + NewItem(VPieceNode(id, Tool::NodePoint)); + break; + case SceneObject::Spline: + NewItem(VPieceNode(id, Tool::NodeSpline, reverse)); + break; + case SceneObject::SplinePath: + NewItem(VPieceNode(id, Tool::NodeSplinePath, reverse)); + break; + case (SceneObject::Line): + case (SceneObject::Detail): + case (SceneObject::Unknown): + default: + qDebug() << "Got wrong scene object. Ignore."; + break; + } + } + else + { + if (ui->listWidget->count() > 1) + { + delete GetItemById(id); + } + } + + ValidObjects(PathIsValid()); + + if (not m_showMode) + { + auto visPath = qobject_cast<VisToolPiecePath *>(vis); + SCASSERT(visPath != nullptr); + const VPiecePath p = CreatePath(); + visPath->SetPath(p); + + if (p.CountNodes() == 1) + { + emit ToolTip(tr("Select main path objects, <b>Shift</b> - reverse direction curve, " + "<b>Enter</b> - finish creation")); + + if (not qApp->getCurrentScene()->items().contains(visPath)) + { + visPath->VisualMode(NULL_ID); + } + else + { + visPath->RefreshGeometry(); + } + } + else + { + visPath->RefreshGeometry(); + } + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::ShowDialog(bool click) +{ + if (click == false) + { + if (CreatePath().CountNodes() > 0) + { + emit ToolTip(""); + prepare = true; + + if (not m_showMode) + { + auto visPath = qobject_cast<VisToolPiecePath *>(vis); + SCASSERT(visPath != nullptr); + visPath->SetMode(Mode::Show); + visPath->RefreshGeometry(); + } + setModal(true); + show(); + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::SaveData() +{} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::CheckState() +{ + SCASSERT(bOk != nullptr); + bOk->setEnabled(flagName && flagError); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::ShowVisualization() +{ + AddVisualization<VisToolPiecePath>(); + + if (m_showMode) + { + VToolSeamAllowance *tool = qobject_cast<VToolSeamAllowance*>(VAbstractPattern::getTool(GetPieceId())); + SCASSERT(tool != nullptr); + auto visPath = qobject_cast<VisToolPiecePath *>(vis); + SCASSERT(visPath != nullptr); + visPath->setParentItem(tool); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::ShowContextMenu(const QPoint &pos) +{ + const int row = ui->listWidget->currentRow(); + if (ui->listWidget->count() == 0 || row == -1 || row >= ui->listWidget->count()) + { + return; + } + + QMenu *menu = new QMenu(this); + + QListWidgetItem *rowItem = ui->listWidget->item(row); + SCASSERT(rowItem != nullptr); + VPieceNode rowNode = qvariant_cast<VPieceNode>(rowItem->data(Qt::UserRole)); + + QAction *actionReverse = nullptr; + if (rowNode.GetTypeTool() != Tool::NodePoint) + { + actionReverse = menu->addAction(tr("Reverse")); + actionReverse->setCheckable(true); + actionReverse->setChecked(rowNode.GetReverse()); + } + + QAction *actionDelete = menu->addAction(QIcon::fromTheme("edit-delete"), tr("Delete")); + + QAction *selectedAction = menu->exec(ui->listWidget->viewport()->mapToGlobal(pos)); + if (selectedAction == actionDelete) + { + delete ui->listWidget->item(row); + ValidObjects(PathIsValid()); + } + else if (rowNode.GetTypeTool() != Tool::NodePoint && selectedAction == actionReverse) + { + rowNode.SetReverse(not rowNode.GetReverse()); + rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode)); + rowItem->setText(GetNodeName(rowNode)); + ValidObjects(PathIsValid()); + } + + ListChanged(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::ListChanged() +{ + if (not m_showMode) + { + auto visPath = qobject_cast<VisToolPiecePath *>(vis); + SCASSERT(visPath != nullptr); + visPath->SetPath(CreatePath()); + visPath->RefreshGeometry(); + } + + InitNodesList(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::NameChanged() +{ + if (ui->lineEditName->text().isEmpty()) + { + flagName = false; + ChangeColor(ui->labelName, Qt::red); + } + else + { + flagName = true; + ChangeColor(ui->labelName, okColor); + } + CheckState(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::NodeChanged(int index) +{ + ui->plainTextEditFormulaWidthBefore->setDisabled(true); + ui->toolButtonExprBefore->setDisabled(true); + ui->pushButtonDefBefore->setDisabled(true); + + ui->plainTextEditFormulaWidthAfter->setDisabled(true); + ui->toolButtonExprAfter->setDisabled(true); + ui->pushButtonDefAfter->setDisabled(true); + + ui->comboBoxAngle->setDisabled(true); + + ui->comboBoxAngle->blockSignals(true); + + if (index != -1) + { + #if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) + const quint32 id = ui->comboBoxNodes->itemData(index).toUInt(); + #else + const quint32 id = ui->comboBoxNodes->currentData().toUInt(); + #endif + const VPiecePath path = CreatePath(); + const int nodeIndex = path.indexOfNode(id); + if (nodeIndex != -1) + { + const VPieceNode &node = path.at(nodeIndex); + + // Seam alowance before + ui->plainTextEditFormulaWidthBefore->setEnabled(true); + ui->toolButtonExprBefore->setEnabled(true); + + QString w1Formula = node.GetFormulaSABefore(); + if (w1Formula != currentSeamAllowance) + { + ui->pushButtonDefBefore->setEnabled(true); + } + if (w1Formula.length() > 80)// increase height if needed. + { + this->DeployWidthBeforeFormulaTextEdit(); + } + w1Formula = qApp->TrVars()->FormulaToUser(w1Formula, qApp->Settings()->GetOsSeparator()); + ui->plainTextEditFormulaWidthBefore->setPlainText(w1Formula); + MoveCursorToEnd(ui->plainTextEditFormulaWidthBefore); + + // Seam alowance after + ui->plainTextEditFormulaWidthAfter->setEnabled(true); + ui->toolButtonExprAfter->setEnabled(true); + + QString w2Formula = node.GetFormulaSAAfter(); + if (w2Formula != currentSeamAllowance) + { + ui->pushButtonDefBefore->setEnabled(true); + } + if (w2Formula.length() > 80)// increase height if needed. + { + this->DeployWidthAfterFormulaTextEdit(); + } + w2Formula = qApp->TrVars()->FormulaToUser(w2Formula, qApp->Settings()->GetOsSeparator()); + ui->plainTextEditFormulaWidthAfter->setPlainText(w2Formula); + MoveCursorToEnd(ui->plainTextEditFormulaWidthAfter); + + // Angle type + ui->comboBoxAngle->setEnabled(true); + const int index = ui->comboBoxAngle->findData(static_cast<unsigned char>(node.GetAngleType())); + if (index != -1) + { + ui->comboBoxAngle->setCurrentIndex(index); + } + } + } + else + { + ui->plainTextEditFormulaWidthBefore->setPlainText(""); + ui->plainTextEditFormulaWidthAfter->setPlainText(""); + ui->comboBoxAngle->setCurrentIndex(-1); + } + + ui->comboBoxAngle->blockSignals(false); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::ReturnDefBefore() +{ + ui->plainTextEditFormulaWidthBefore->setPlainText(currentSeamAllowance); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::ReturnDefAfter() +{ + ui->plainTextEditFormulaWidthAfter->setPlainText(currentSeamAllowance); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::EvalWidth() +{ + labelEditFormula = ui->labelEditWidth; + const QString postfix = VDomDocument::UnitsToStr(qApp->patternUnit(), true); + const QString formula = ui->plainTextEditFormulaWidth->toPlainText(); + m_saWidth = Eval(formula, flagFormula, ui->labelResultWidth, postfix, false, true); + + if (m_saWidth >= 0) + { + VContainer *locData = const_cast<VContainer *> (data); + locData->AddVariable(currentSeamAllowance, new VIncrement(locData, currentSeamAllowance, 0, m_saWidth, + QString().setNum(m_saWidth), true, + tr("Current seam aloowance"))); + + EvalWidthBefore(); + EvalWidthAfter(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::EvalWidthBefore() +{ + labelEditFormula = ui->labelEditBefore; + const QString postfix = VDomDocument::UnitsToStr(qApp->patternUnit(), true); + const QString formula = ui->plainTextEditFormulaWidthBefore->toPlainText(); + bool flagFormula = false; // fake flag + Eval(formula, flagFormula, ui->labelResultBefore, postfix, false, true); + + UpdateNodeSABefore(GetFormulaSAWidthBefore()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::EvalWidthAfter() +{ + labelEditFormula = ui->labelEditAfter; + const QString postfix = VDomDocument::UnitsToStr(qApp->patternUnit(), true); + const QString formula = ui->plainTextEditFormulaWidthAfter->toPlainText(); + bool flagFormula = false; // fake flag + Eval(formula, flagFormula, ui->labelResultAfter, postfix, false, true); + + UpdateNodeSABefore(GetFormulaSAWidthAfter()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::FXWidth() +{ + DialogEditWrongFormula *dialog = new DialogEditWrongFormula(data, toolId, this); + dialog->setWindowTitle(tr("Edit seam allowance width")); + dialog->SetFormula(GetFormulaSAWidth()); + dialog->setCheckLessThanZero(true); + dialog->setPostfix(VDomDocument::UnitsToStr(qApp->patternUnit(), true)); + if (dialog->exec() == QDialog::Accepted) + { + SetFormulaSAWidth(dialog->GetFormula()); + } + delete dialog; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::FXWidthBefore() +{ + DialogEditWrongFormula *dialog = new DialogEditWrongFormula(data, toolId, this); + dialog->setWindowTitle(tr("Edit seam allowance width before")); + dialog->SetFormula(GetFormulaSAWidthBefore()); + dialog->setCheckLessThanZero(true); + dialog->setPostfix(VDomDocument::UnitsToStr(qApp->patternUnit(), true)); + if (dialog->exec() == QDialog::Accepted) + { + SetCurrentSABefore(dialog->GetFormula()); + } + delete dialog; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::FXWidthAfter() +{ + DialogEditWrongFormula *dialog = new DialogEditWrongFormula(data, toolId, this); + dialog->setWindowTitle(tr("Edit seam allowance width after")); + dialog->SetFormula(GetFormulaSAWidthAfter()); + dialog->setCheckLessThanZero(true); + dialog->setPostfix(VDomDocument::UnitsToStr(qApp->patternUnit(), true)); + if (dialog->exec() == QDialog::Accepted) + { + SetCurrentSAAfter(dialog->GetFormula()); + } + delete dialog; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::WidthChanged() +{ + labelEditFormula = ui->labelEditWidth; + labelResultCalculation = ui->labelResultWidth; + const QString postfix = VDomDocument::UnitsToStr(qApp->patternUnit(), true); + ValFormulaChanged(flagFormula, ui->plainTextEditFormulaWidth, m_timerWidth, postfix); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::WidthBeforeChanged() +{ + labelEditFormula = ui->labelEditBefore; + labelResultCalculation = ui->labelResultBefore; + const QString postfix = VDomDocument::UnitsToStr(qApp->patternUnit(), true); + bool flagFormula = false; + ValFormulaChanged(flagFormula, ui->plainTextEditFormulaWidthBefore, m_timerWidthBefore, postfix); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::WidthAfterChanged() +{ + labelEditFormula = ui->labelEditAfter; + labelResultCalculation = ui->labelResultAfter; + const QString postfix = VDomDocument::UnitsToStr(qApp->patternUnit(), true); + bool flagFormula = false; + ValFormulaChanged(flagFormula, ui->plainTextEditFormulaWidthAfter, m_timerWidthAfter, postfix); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::DeployWidthFormulaTextEdit() +{ + DeployFormula(ui->plainTextEditFormulaWidth, ui->pushButtonGrowWidth, m_formulaBaseWidth); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::DeployWidthBeforeFormulaTextEdit() +{ + DeployFormula(ui->plainTextEditFormulaWidthBefore, ui->pushButtonGrowWidthBefore, m_formulaBaseWidthBefore); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::DeployWidthAfterFormulaTextEdit() +{ + DeployFormula(ui->plainTextEditFormulaWidthAfter, ui->pushButtonGrowWidthAfter, m_formulaBaseWidthAfter); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::InitPathTab() +{ +#if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0) + ui->lineEditName->setClearButtonEnabled(true); +#endif + + FillComboBoxTypeLine(ui->comboBoxPenType, VAbstractTool::LineStylesPics()); + + connect(ui->lineEditName, &QLineEdit::textChanged, this, &DialogPiecePath::NameChanged); + + InitPathTypes(); + connect(ui->comboBoxType, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), + [this]() + { + ui->comboBoxPenType->setEnabled(GetType() == PiecePathType::InternalPath); + ValidObjects(PathIsValid()); + }); + + ui->listWidget->setContextMenuPolicy(Qt::CustomContextMenu); + connect(ui->listWidget, &QListWidget::customContextMenuRequested, this, &DialogPiecePath::ShowContextMenu); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::InitSeamAllowanceTab() +{ + plainTextEditFormula = ui->plainTextEditFormulaWidth; + this->m_formulaBaseWidth = ui->plainTextEditFormulaWidth->height(); + this->m_formulaBaseWidthBefore = ui->plainTextEditFormulaWidthBefore->height(); + this->m_formulaBaseWidthAfter = ui->plainTextEditFormulaWidthAfter->height(); + + ui->plainTextEditFormulaWidth->installEventFilter(this); + ui->plainTextEditFormulaWidthBefore->installEventFilter(this); + ui->plainTextEditFormulaWidthAfter->installEventFilter(this); + + m_timerWidth = new QTimer(this); + connect(m_timerWidth, &QTimer::timeout, this, &DialogPiecePath::EvalWidth); + + m_timerWidthBefore = new QTimer(this); + connect(m_timerWidthBefore, &QTimer::timeout, this, &DialogPiecePath::EvalWidthBefore); + + m_timerWidthAfter = new QTimer(this); + connect(m_timerWidthAfter, &QTimer::timeout, this, &DialogPiecePath::EvalWidthAfter); + + // Default value for seam allowence is 1 cm. But pattern have different units, so just set 1 in dialog not enough. + m_saWidth = UnitConvertor(1, Unit::Cm, qApp->patternUnit()); + ui->plainTextEditFormulaWidth->setPlainText(qApp->LocaleToString(m_saWidth)); + + InitNodesList(); + connect(ui->comboBoxNodes, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, + &DialogPiecePath::NodeChanged); + + connect(ui->pushButtonDefBefore, &QPushButton::clicked, this, &DialogPiecePath::ReturnDefBefore); + connect(ui->pushButtonDefAfter, &QPushButton::clicked, this, &DialogPiecePath::ReturnDefAfter); + + InitNodeAngles(ui->comboBoxAngle); + connect(ui->comboBoxAngle, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, + &DialogPiecePath::NodeAngleChanged); + + connect(ui->toolButtonExprWidth, &QPushButton::clicked, this, &DialogPiecePath::FXWidth); + connect(ui->toolButtonExprBefore, &QPushButton::clicked, this, &DialogPiecePath::FXWidthBefore); + connect(ui->toolButtonExprAfter, &QPushButton::clicked, this, &DialogPiecePath::FXWidthAfter); + + connect(ui->plainTextEditFormulaWidth, &QPlainTextEdit::textChanged, this, &DialogPiecePath::WidthChanged); + connect(ui->plainTextEditFormulaWidthBefore, &QPlainTextEdit::textChanged, this, + &DialogPiecePath::WidthBeforeChanged); + connect(ui->plainTextEditFormulaWidthAfter, &QPlainTextEdit::textChanged, this, + &DialogPiecePath::WidthAfterChanged); + + connect(ui->pushButtonGrowWidth, &QPushButton::clicked, this, &DialogPiecePath::DeployWidthFormulaTextEdit); + connect(ui->pushButtonGrowWidthBefore, &QPushButton::clicked, + this, &DialogPiecePath::DeployWidthBeforeFormulaTextEdit); + connect(ui->pushButtonGrowWidthAfter, &QPushButton::clicked, this, + &DialogPiecePath::DeployWidthAfterFormulaTextEdit); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::InitPathTypes() +{ + ui->comboBoxType->addItem(tr("Internal path"), static_cast<int>(PiecePathType::InternalPath)); + ui->comboBoxType->addItem(tr("Custom seam allowance"), static_cast<int>(PiecePathType::CustomSeamAllowance)); + + ui->comboBoxPenType->setEnabled(GetType() == PiecePathType::InternalPath); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::InitNodesList() +{ +#if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) + const quint32 id = ui->comboBoxNodes->itemData(ui->comboBoxNodes->currentIndex()).toUInt(); +#else + const quint32 id = ui->comboBoxNodes->currentData().toUInt(); +#endif + + ui->comboBoxNodes->blockSignals(true); + ui->comboBoxNodes->clear(); + + const VPiecePath path = CreatePath(); + + for (int i = 0; i < path.CountNodes(); ++i) + { + const VPieceNode node = path.at(i); + if (node.GetTypeTool() == Tool::NodePoint) + { + const QString name = GetNodeName(node); + + ui->comboBoxNodes->addItem(name, node.GetId()); + } + } + ui->comboBoxNodes->blockSignals(false); + + const int index = ui->comboBoxNodes->findData(id); + if (index != -1) + { + ui->comboBoxNodes->setCurrentIndex(index); + NodeChanged(index);// Need in case combox index was not changed + } + else + { + ui->comboBoxNodes->count() > 0 ? NodeChanged(0) : NodeChanged(-1); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::NodeAngleChanged(int index) +{ + const int i = ui->comboBoxNodes->currentIndex(); + if (i != -1 && index != -1) + { + #if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) + const quint32 id = ui->comboBoxNodes->itemData(i).toUInt(); + #else + const quint32 id = ui->comboBoxNodes->currentData().toUInt(); + #endif + + QListWidgetItem *rowItem = GetItemById(id); + if (rowItem) + { + #if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) + const PieceNodeAngle angle = static_cast<PieceNodeAngle>(ui->comboBoxAngle->itemData(index).toUInt()); + #else + const PieceNodeAngle angle = static_cast<PieceNodeAngle>(ui->comboBoxAngle->currentData().toUInt()); + #endif + + VPieceNode rowNode = qvariant_cast<VPieceNode>(rowItem->data(Qt::UserRole)); + rowNode.SetAngleType(angle); + rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode)); + + ListChanged(); + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +VPiecePath DialogPiecePath::GetPiecePath() const +{ + return CreatePath(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::SetPiecePath(const VPiecePath &path) +{ + ui->listWidget->clear(); + for (int i = 0; i < path.CountNodes(); ++i) + { + NewItem(path.at(i)); + } + + SetType(path.GetType()); + ui->lineEditName->setText(path.GetName()); + + VisToolPiecePath *visPath = qobject_cast<VisToolPiecePath *>(vis); + SCASSERT(visPath != nullptr); + visPath->SetPath(path); + SetPenType(path.GetPenType()); + + ValidObjects(PathIsValid()); + + ListChanged(); +} + +//--------------------------------------------------------------------------------------------------------------------- +PiecePathType DialogPiecePath::GetType() const +{ +#if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) + const PiecePathType type = + static_cast<PiecePathType>(ui->comboBoxType->itemData(ui->comboBoxType->currentIndex()).toInt()); +#else + const PiecePathType type = static_cast<PiecePathType>(ui->comboBoxType->currentData().toInt()); +#endif + + return type; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::SetType(PiecePathType type) +{ + const qint32 index = ui->comboBoxType->findData(static_cast<int>(type)); + if (index != -1) + { + ui->comboBoxType->setCurrentIndex(index); + } + + ui->comboBoxPenType->setEnabled(type == PiecePathType::InternalPath); +} + +//--------------------------------------------------------------------------------------------------------------------- +Qt::PenStyle DialogPiecePath::GetPenType() const +{ + return VAbstractTool::LineStyleToPenStyle(GetComboBoxCurrentData(ui->comboBoxPenType, TypeLineLine)); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::SetPenType(const Qt::PenStyle &type) +{ + ChangeCurrentData(ui->comboBoxPenType, VAbstractTool::PenStyleToLineStyle(type)); + vis->setLineStyle(type); +} + +//--------------------------------------------------------------------------------------------------------------------- +QListWidgetItem *DialogPiecePath::GetItemById(quint32 id) +{ + for (qint32 i = 0; i < ui->listWidget->count(); ++i) + { + QListWidgetItem *item = ui->listWidget->item(i); + const VPieceNode node = qvariant_cast<VPieceNode>(item->data(Qt::UserRole)); + + if (node.GetId() == id) + { + return item; + } + } + return nullptr; +} + +//--------------------------------------------------------------------------------------------------------------------- +quint32 DialogPiecePath::GetLastId() const +{ + const int count = ui->listWidget->count(); + if (count > 0) + { + QListWidgetItem *item = ui->listWidget->item(count-1); + const VPieceNode node = qvariant_cast<VPieceNode>(item->data(Qt::UserRole)); + return node.GetId(); + } + else + { + return NULL_ID; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::SetCurrentSABefore(const QString &formula) +{ + UpdateNodeSABefore(formula); + ListChanged(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::SetCurrentSAAfter(const QString &formula) +{ + UpdateNodeSAAfter(formula); + ListChanged(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::UpdateNodeSABefore(const QString &formula) +{ + const int index = ui->comboBoxNodes->currentIndex(); + if (index != -1) + { + #if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) + const quint32 id = ui->comboBoxNodes->itemData(index).toUInt(); + #else + const quint32 id = ui->comboBoxNodes->currentData().toUInt(); + #endif + + QListWidgetItem *rowItem = GetItemById(id); + if (rowItem) + { + VPieceNode rowNode = qvariant_cast<VPieceNode>(rowItem->data(Qt::UserRole)); + rowNode.SetFormulaSABefore(formula); + rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode)); + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::UpdateNodeSAAfter(const QString &formula) +{ + const int index = ui->comboBoxNodes->currentIndex(); + if (index != -1) + { + #if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) + const quint32 id = ui->comboBoxNodes->itemData(index).toUInt(); + #else + const quint32 id = ui->comboBoxNodes->currentData().toUInt(); + #endif + + QListWidgetItem *rowItem = GetItemById(id); + if (rowItem) + { + VPieceNode rowNode = qvariant_cast<VPieceNode>(rowItem->data(Qt::UserRole)); + rowNode.SetFormulaSAAfter(formula); + rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode)); + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::SetFormulaSAWidth(const QString &formula) +{ + const QString width = qApp->TrVars()->FormulaToUser(formula, qApp->Settings()->GetOsSeparator()); + // increase height if needed. + if (width.length() > 80) + { + this->DeployWidthFormulaTextEdit(); + } + ui->plainTextEditFormulaWidth->setPlainText(width); + + VisToolPiecePath *path = qobject_cast<VisToolPiecePath *>(vis); + SCASSERT(path != nullptr) + path->SetPath(CreatePath()); + + MoveCursorToEnd(ui->plainTextEditFormulaWidth); +} + +//--------------------------------------------------------------------------------------------------------------------- +quint32 DialogPiecePath::GetPieceId() const +{ + quint32 id = NULL_ID; + + if (ui->comboBoxPiece->count() > 0) + { +#if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) + id = ui->comboBoxPiece->itemData(ui->comboBoxPiece->currentIndex()).toUInt(); +#else + id = ui->comboBoxPiece->currentData().toUInt(); +#endif + } + + return id; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::SetPieceId(quint32 id) +{ + if (ui->comboBoxPiece->count() <= 0) + { + const VPiece piece = data->GetPiece(id); + ui->comboBoxPiece->addItem(piece.GetName(), id); + } + else + { + const qint32 index = ui->comboBoxPiece->findData(id); + if (index != -1) + { + ui->comboBoxType->setCurrentIndex(index); + } + } + + ValidObjects(PathIsValid()); +} + +//--------------------------------------------------------------------------------------------------------------------- +QString DialogPiecePath::GetFormulaSAWidth() const +{ + QString width = ui->plainTextEditFormulaWidth->toPlainText(); + width.replace("\n", " "); + return qApp->TrVars()->TryFormulaFromUser(width, qApp->Settings()->GetOsSeparator()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::SetPiecesList(const QVector<quint32> &list) +{ + for (int i=0; i < list.size(); ++i) + { + const VPiece piece = data->GetPiece(list.at(i)); + ui->comboBoxPiece->addItem(piece.GetName(), list.at(i)); + } + ValidObjects(PathIsValid()); +} + +//--------------------------------------------------------------------------------------------------------------------- +VPiecePath DialogPiecePath::CreatePath() const +{ + VPiecePath path; + for (qint32 i = 0; i < ui->listWidget->count(); ++i) + { + QListWidgetItem *item = ui->listWidget->item(i); + path.Append(qvariant_cast<VPieceNode>(item->data(Qt::UserRole))); + } + + path.SetType(GetType()); + path.SetName(ui->lineEditName->text()); + path.SetPenType(GetType() == PiecePathType::InternalPath ? GetPenType() : Qt::SolidLine); + + return path; +} + +//--------------------------------------------------------------------------------------------------------------------- +bool DialogPiecePath::PathIsValid() const +{ + QString url = DialogWarningIcon(); + + if(CreatePath().PathPoints(data).count() < 2) + { + url += tr("You need more points!"); + ui->helpLabel->setText(url); + return false; + } + else + { + if (GetType() == PiecePathType::CustomSeamAllowance && FirstPointEqualLast(ui->listWidget)) + { + url += tr("First point of <b>custom seam allowance</b> cannot be equal to the last point!"); + ui->helpLabel->setText(url); + return false; + } + else if (DoublePoints(ui->listWidget)) + { + url += tr("You have double points!"); + ui->helpLabel->setText(url); + return false; + } + } + + if (not m_showMode && ui->comboBoxPiece->count() <= 0) + { + url += tr("List of objects is empty!"); + ui->helpLabel->setText(url); + return false; + } + + ui->helpLabel->setText(tr("Ready!")); + return true; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::ValidObjects(bool value) +{ + flagError = value; + CheckState(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::NewItem(const VPieceNode &node) +{ + NewNodeItem(ui->listWidget, node); +} + +//--------------------------------------------------------------------------------------------------------------------- +QString DialogPiecePath::GetFormulaSAWidthBefore() const +{ + QString width = ui->plainTextEditFormulaWidthBefore->toPlainText(); + width.replace("\n", " "); + return qApp->TrVars()->TryFormulaFromUser(width, qApp->Settings()->GetOsSeparator()); +} + +//--------------------------------------------------------------------------------------------------------------------- +QString DialogPiecePath::GetFormulaSAWidthAfter() const +{ + QString width = ui->plainTextEditFormulaWidthAfter->toPlainText(); + width.replace("\n", " "); + return qApp->TrVars()->TryFormulaFromUser(width, qApp->Settings()->GetOsSeparator()); +} diff --git a/src/libs/vtools/dialogs/tools/dialogpiecepath.h b/src/libs/vtools/dialogs/tools/dialogpiecepath.h new file mode 100644 index 000000000..4739d8ea3 --- /dev/null +++ b/src/libs/vtools/dialogs/tools/dialogpiecepath.h @@ -0,0 +1,140 @@ +/************************************************************************ + ** + ** @file dialogpiecepath.h + ** @author Roman Telezhynskyi <dismine(at)gmail.com> + ** @date 22 11, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2016 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#ifndef DIALOGPIECEPATH_H +#define DIALOGPIECEPATH_H + +#include "dialogtool.h" + +namespace Ui +{ + class DialogPiecePath; +} + +class DialogPiecePath : public DialogTool +{ + Q_OBJECT +public: + explicit DialogPiecePath(const VContainer *data, quint32 toolId, QWidget *parent = nullptr); + virtual ~DialogPiecePath(); + + void EnbleShowMode(bool disable); + + VPiecePath GetPiecePath() const; + void SetPiecePath(const VPiecePath &path); + + quint32 GetPieceId() const; + void SetPieceId(quint32 id); + + QString GetFormulaSAWidth() const; + void SetFormulaSAWidth(const QString &formula); + + virtual void SetPiecesList(const QVector<quint32> &list) Q_DECL_OVERRIDE; + +public slots: + virtual void ChosenObject(quint32 id, const SceneObject &type) Q_DECL_OVERRIDE; + virtual void ShowDialog(bool click) Q_DECL_OVERRIDE; + +protected: + /** @brief SaveData Put dialog data in local variables */ + virtual void SaveData() Q_DECL_OVERRIDE; + virtual void CheckState() Q_DECL_OVERRIDE; + virtual void ShowVisualization() Q_DECL_OVERRIDE; + +private slots: + void ShowContextMenu(const QPoint &pos); + void ListChanged(); + void NameChanged(); + void NodeChanged(int index); + void ReturnDefBefore(); + void ReturnDefAfter(); + + void EvalWidth(); + void EvalWidthBefore(); + void EvalWidthAfter(); + + void FXWidth(); + void FXWidthBefore(); + void FXWidthAfter(); + + void WidthChanged(); + void WidthBeforeChanged(); + void WidthAfterChanged(); + + void DeployWidthFormulaTextEdit(); + void DeployWidthBeforeFormulaTextEdit(); + void DeployWidthAfterFormulaTextEdit(); + +private: + Q_DISABLE_COPY(DialogPiecePath) + Ui::DialogPiecePath *ui; + bool m_showMode; + qreal m_saWidth; + + QTimer *m_timerWidth; + QTimer *m_timerWidthBefore; + QTimer *m_timerWidthAfter; + + int m_formulaBaseWidth; + int m_formulaBaseWidthBefore; + int m_formulaBaseWidthAfter; + + void InitPathTab(); + void InitSeamAllowanceTab(); + void InitPathTypes(); + void InitListPieces(); + void InitNodesList(); + void NodeAngleChanged(int index); + + VPiecePath CreatePath() const; + + bool PathIsValid() const; + void ValidObjects(bool value); + void NewItem(const VPieceNode &node); + + PiecePathType GetType() const; + void SetType(PiecePathType type); + + Qt::PenStyle GetPenType() const; + void SetPenType(const Qt::PenStyle &type); + + QListWidgetItem *GetItemById(quint32 id); + + quint32 GetLastId() const; + + void SetCurrentSABefore(const QString &formula); + void SetCurrentSAAfter(const QString &formula); + + void UpdateNodeSABefore(const QString &formula); + void UpdateNodeSAAfter(const QString &formula); + + QString GetFormulaSAWidthBefore() const; + QString GetFormulaSAWidthAfter() const; +}; + +#endif // DIALOGPIECEPATH_H diff --git a/src/libs/vtools/dialogs/tools/dialogpiecepath.ui b/src/libs/vtools/dialogs/tools/dialogpiecepath.ui new file mode 100644 index 000000000..10d360ffd --- /dev/null +++ b/src/libs/vtools/dialogs/tools/dialogpiecepath.ui @@ -0,0 +1,846 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>DialogPiecePath</class> + <widget class="QDialog" name="DialogPiecePath"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>480</width> + <height>437</height> + </rect> + </property> + <property name="windowTitle"> + <string>Piece path tool</string> + </property> + <property name="windowIcon"> + <iconset resource="../../../vmisc/share/resources/icon.qrc"> + <normaloff>:/icon/64x64/icon64x64.png</normaloff>:/icon/64x64/icon64x64.png</iconset> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QTabWidget" name="tabWidget"> + <property name="currentIndex"> + <number>0</number> + </property> + <widget class="QWidget" name="tabPath"> + <attribute name="title"> + <string>Path</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QFormLayout" name="formLayout"> + <property name="fieldGrowthPolicy"> + <enum>QFormLayout::ExpandingFieldsGrow</enum> + </property> + <item row="0" column="0"> + <widget class="QLabel" name="labelName"> + <property name="text"> + <string>Name:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="lineEditName"> + <property name="text"> + <string>Unnamed path</string> + </property> + <property name="placeholderText"> + <string>Create name for your path</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="labelType"> + <property name="text"> + <string>Type:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QComboBox" name="comboBoxType"/> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="labelPiece"> + <property name="text"> + <string>Piece:</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QComboBox" name="comboBoxPiece"/> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="labelPenType"> + <property name="text"> + <string>Type of pen:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QComboBox" name="comboBoxPenType"> + <property name="minimumSize"> + <size> + <width>80</width> + <height>0</height> + </size> + </property> + <property name="iconSize"> + <size> + <width>80</width> + <height>14</height> + </size> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QListWidget" name="listWidget"> + <property name="dragDropMode"> + <enum>QAbstractItemView::InternalMove</enum> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="helpLabel"> + <property name="text"> + <string>Ready!</string> + </property> + <property name="textFormat"> + <enum>Qt::RichText</enum> + </property> + <property name="scaledContents"> + <bool>false</bool> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="tabSeamAllowance"> + <attribute name="title"> + <string>Seam allowance</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_4"> + <item alignment="Qt::AlignLeft"> + <widget class="QLabel" name="labelEditWidth"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="palette"> + <palette> + <active> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </active> + <inactive> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </inactive> + <disabled> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>159</red> + <green>158</green> + <blue>158</blue> + </color> + </brush> + </colorrole> + </disabled> + </palette> + </property> + <property name="text"> + <string>Width:</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item alignment="Qt::AlignRight"> + <widget class="QToolButton" name="toolButtonExprWidth"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Formula wizard</string> + </property> + <property name="text"> + <string notr="true">...</string> + </property> + <property name="icon"> + <iconset resource="../../../vmisc/share/resources/icon.qrc"> + <normaloff>:/icon/24x24/fx.png</normaloff>:/icon/24x24/fx.png</iconset> + </property> + <property name="iconSize"> + <size> + <width>24</width> + <height>24</height> + </size> + </property> + </widget> + </item> + <item alignment="Qt::AlignRight"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string/> + </property> + <property name="pixmap"> + <pixmap resource="../../../vmisc/share/resources/icon.qrc">:/icon/24x24/equal.png</pixmap> + </property> + </widget> + </item> + <item alignment="Qt::AlignRight"> + <widget class="QLabel" name="labelResultWidth"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>87</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string>Value</string> + </property> + <property name="text"> + <string notr="true">_</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_6"> + <item> + <widget class="QPlainTextEdit" name="plainTextEditFormulaWidth"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>28</height> + </size> + </property> + <property name="toolTip"> + <string>Calculation</string> + </property> + <property name="tabChangesFocus"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButtonGrowWidth"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="maximumSize"> + <size> + <width>18</width> + <height>18</height> + </size> + </property> + <property name="sizeIncrement"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string><html><head/><body><p>Show full calculation in message box</p></body></html></string> + </property> + <property name="text"> + <string notr="true"/> + </property> + <property name="icon"> + <iconset theme="go-down"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="iconSize"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Nodes</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_5"> + <item> + <widget class="QLabel" name="labelNode"> + <property name="text"> + <string>Node:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="comboBoxNodes"> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_9"> + <item alignment="Qt::AlignLeft"> + <widget class="QLabel" name="labelEditBefore"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="palette"> + <palette> + <active> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </active> + <inactive> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </inactive> + <disabled> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>159</red> + <green>158</green> + <blue>158</blue> + </color> + </brush> + </colorrole> + </disabled> + </palette> + </property> + <property name="text"> + <string>Before:</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="pushButtonDefBefore"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Return to default width</string> + </property> + <property name="text"> + <string>Default</string> + </property> + </widget> + </item> + <item alignment="Qt::AlignRight"> + <widget class="QToolButton" name="toolButtonExprBefore"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Formula wizard</string> + </property> + <property name="text"> + <string notr="true">...</string> + </property> + <property name="icon"> + <iconset resource="../../../vmisc/share/resources/icon.qrc"> + <normaloff>:/icon/24x24/fx.png</normaloff>:/icon/24x24/fx.png</iconset> + </property> + <property name="iconSize"> + <size> + <width>24</width> + <height>24</height> + </size> + </property> + </widget> + </item> + <item alignment="Qt::AlignRight"> + <widget class="QLabel" name="label_6"> + <property name="text"> + <string/> + </property> + <property name="pixmap"> + <pixmap resource="../../../vmisc/share/resources/icon.qrc">:/icon/24x24/equal.png</pixmap> + </property> + </widget> + </item> + <item alignment="Qt::AlignRight"> + <widget class="QLabel" name="labelResultBefore"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>87</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string>Value</string> + </property> + <property name="text"> + <string notr="true">_</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_7"> + <item> + <widget class="QPlainTextEdit" name="plainTextEditFormulaWidthBefore"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>28</height> + </size> + </property> + <property name="toolTip"> + <string>Calculation</string> + </property> + <property name="tabChangesFocus"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButtonGrowWidthBefore"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="maximumSize"> + <size> + <width>18</width> + <height>18</height> + </size> + </property> + <property name="sizeIncrement"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string><html><head/><body><p>Show full calculation in message box</p></body></html></string> + </property> + <property name="text"> + <string notr="true"/> + </property> + <property name="icon"> + <iconset theme="go-down"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="iconSize"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_16"> + <item alignment="Qt::AlignLeft"> + <widget class="QLabel" name="labelEditAfter"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="palette"> + <palette> + <active> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </active> + <inactive> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </inactive> + <disabled> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>159</red> + <green>158</green> + <blue>158</blue> + </color> + </brush> + </colorrole> + </disabled> + </palette> + </property> + <property name="text"> + <string>After:</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_6"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="pushButtonDefAfter"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Return to default width</string> + </property> + <property name="text"> + <string>Default</string> + </property> + </widget> + </item> + <item alignment="Qt::AlignRight"> + <widget class="QToolButton" name="toolButtonExprAfter"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Formula wizard</string> + </property> + <property name="text"> + <string notr="true">...</string> + </property> + <property name="icon"> + <iconset resource="../../../vmisc/share/resources/icon.qrc"> + <normaloff>:/icon/24x24/fx.png</normaloff>:/icon/24x24/fx.png</iconset> + </property> + <property name="iconSize"> + <size> + <width>24</width> + <height>24</height> + </size> + </property> + </widget> + </item> + <item alignment="Qt::AlignRight"> + <widget class="QLabel" name="label_10"> + <property name="text"> + <string/> + </property> + <property name="pixmap"> + <pixmap resource="../../../vmisc/share/resources/icon.qrc">:/icon/24x24/equal.png</pixmap> + </property> + </widget> + </item> + <item alignment="Qt::AlignRight"> + <widget class="QLabel" name="labelResultAfter"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>87</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string>Value</string> + </property> + <property name="text"> + <string notr="true">_</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_17"> + <item> + <widget class="QPlainTextEdit" name="plainTextEditFormulaWidthAfter"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>28</height> + </size> + </property> + <property name="toolTip"> + <string>Calculation</string> + </property> + <property name="tabChangesFocus"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButtonGrowWidthAfter"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="maximumSize"> + <size> + <width>18</width> + <height>18</height> + </size> + </property> + <property name="sizeIncrement"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string><html><head/><body><p>Show full calculation in message box</p></body></html></string> + </property> + <property name="text"> + <string notr="true"/> + </property> + <property name="icon"> + <iconset theme="go-down"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="iconSize"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QLabel" name="labelAngle"> + <property name="text"> + <string>Angle:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="comboBoxAngle"> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_4"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources> + <include location="../../../vmisc/share/resources/icon.qrc"/> + </resources> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>DialogPiecePath</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>DialogPiecePath</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/libs/vtools/dialogs/tools/dialogseamallowance.cpp b/src/libs/vtools/dialogs/tools/dialogseamallowance.cpp new file mode 100644 index 000000000..7ebc6f922 --- /dev/null +++ b/src/libs/vtools/dialogs/tools/dialogseamallowance.cpp @@ -0,0 +1,1769 @@ +/************************************************************************ + ** + ** @file dialogseamallowance.cpp + ** @author Roman Telezhynskyi <dismine(at)gmail.com> + ** @date 3 11, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2016 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#include "dialogseamallowance.h" +#include "ui_dialogseamallowance.h" +#include "../vpatterndb/vpiecenode.h" +#include "../vpatterndb/vpiecepath.h" +#include "../vpatterndb/calculator.h" +#include "visualization/path/vistoolpiece.h" +#include "dialogpiecepath.h" +#include "../../undocommands/savepiecepathoptions.h" +#include "../support/dialogeditwrongformula.h" + +#include <QMenu> +#include <QTimer> +#include <QtNumeric> + +//--------------------------------------------------------------------------------------------------------------------- +DialogSeamAllowance::DialogSeamAllowance(const VContainer *data, const quint32 &toolId, QWidget *parent) + : DialogTool(data, toolId, parent), + ui(new Ui::DialogSeamAllowance), + applyAllowed(false),// By default disabled + m_bAddMode(true), + m_mx(0), + m_my(0), + m_dialog(), + m_qslMaterials(), + m_qslPlacements(), + m_conMCP(), + m_oldData(), + m_oldGeom(), + m_oldGrainline(), + m_iRotBaseHeight(0), + m_iLenBaseHeight(0), + m_formulaBaseWidth(0), + m_formulaBaseWidthBefore(0), + m_formulaBaseWidthAfter(0), + m_timerWidth(nullptr), + m_timerWidthBefore(nullptr), + m_timerWidthAfter(nullptr), + m_saWidth(0) +{ + ui->setupUi(this); + + InitOkCancelApply(ui); + EnableApply(applyAllowed); + + InitMainPathTab(); + InitSeamAllowanceTab(); + InitInternalPathsTab(); + InitPatternPieceDataTab(); + InitGrainlineTab(); + + flagName = true;//We have default name of piece. + ChangeColor(ui->labelEditName, okColor); + flagError = MainPathIsValid(); + CheckState(); + + if (not applyAllowed) + { + vis = new VisToolPiece(data); + } + + ui->tabWidget->setCurrentIndex(0);// Show always first tab active on start. +} + +//--------------------------------------------------------------------------------------------------------------------- +DialogSeamAllowance::~DialogSeamAllowance() +{ + VContainer *locData = const_cast<VContainer *> (data); + locData->RemoveVariable(currentSeamAllowance); + + delete ui; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::EnableApply(bool enable) +{ + SCASSERT(bApply != nullptr); + bApply->setEnabled(enable); + applyAllowed = enable; + ui->tabSeamAllowance->setEnabled(applyAllowed); + ui->tabInternalPaths->setEnabled(applyAllowed); + ui->tabPatternPieceData->setEnabled(applyAllowed); + ui->tabGrainline->setEnabled(applyAllowed); +} + +//--------------------------------------------------------------------------------------------------------------------- +VPiece DialogSeamAllowance::GetPiece() const +{ + return CreatePiece(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::SetPiece(const VPiece &piece) +{ + ui->listWidgetMainPath->clear(); + for (int i = 0; i < piece.GetPath().CountNodes(); ++i) + { + NewMainPathItem(piece.GetPath().at(i)); + } + + ui->listWidgetCustomSA->blockSignals(true); + ui->listWidgetCustomSA->clear(); + const QVector<CustomSARecord> records = piece.GetCustomSARecords(); + for (int i = 0; i < records.size(); ++i) + { + NewCustomSA(records.at(i)); + } + ui->listWidgetCustomSA->blockSignals(false); + + ui->listWidgetInternalPaths->clear(); + const QVector<quint32> iPaths = piece.GetInternalPaths(); + for (int i = 0; i < iPaths.size(); ++i) + { + NewInternalPath(iPaths.at(i)); + } + + ui->comboBoxStartPoint->blockSignals(true); + ui->comboBoxStartPoint->clear(); + ui->comboBoxStartPoint->blockSignals(false); + + ui->comboBoxEndPoint->blockSignals(true); + ui->comboBoxEndPoint->clear(); + ui->comboBoxEndPoint->blockSignals(false); + + CustomSAChanged(0); + + ui->checkBoxForbidFlipping->setChecked(piece.IsForbidFlipping()); + ui->checkBoxSeams->setChecked(piece.IsSeamAllowance()); + ui->lineEditName->setText(piece.GetName()); + + ui->plainTextEditFormulaWidth->setPlainText(piece.GetFormulaSAWidth()); + m_saWidth = piece.GetSAWidth(); + + m_mx = piece.GetMx(); + m_my = piece.GetMy(); + + ui->lineEditLetter->setText(piece.GetPatternPieceData().GetLetter()); + ui->checkBoxDetail->setChecked(piece.GetPatternPieceData().IsVisible()); + ui->checkBoxPattern->setChecked(piece.GetPatternInfo().IsVisible()); + + m_conMCP.clear(); + for (int i = 0; i < piece.GetPatternPieceData().GetMCPCount(); ++i) + { + m_conMCP << piece.GetPatternPieceData().GetMCP(i); + } + + UpdateList(); + + ui->checkBoxGrainline->setChecked(piece.GetGrainlineGeometry().IsVisible()); + ui->lineEditRotFormula->setPlainText(piece.GetGrainlineGeometry().GetRotation()); + ui->lineEditLenFormula->setPlainText(piece.GetGrainlineGeometry().GetLength()); + ui->comboBoxArrow->setCurrentIndex(int(piece.GetGrainlineGeometry().GetArrowType())); + + m_oldData = piece.GetPatternPieceData(); + m_oldGeom = piece.GetPatternInfo(); + m_oldGrainline = piece.GetGrainlineGeometry(); + + ValidObjects(MainPathIsValid()); + EnableGrainlineRotation(); + + ListChanged(); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief ChoosedObject gets id and type of selected object. Save right data and ignore wrong. + * @param id id of objects (points, arcs, splines, spline paths) + * @param type type of object + */ +void DialogSeamAllowance::ChosenObject(quint32 id, const SceneObject &type) +{ + if (not prepare) + { + bool reverse = false; + if (QGuiApplication::keyboardModifiers() == Qt::ShiftModifier) + { + reverse = true; + } + if (id != GetLastId()) + { + switch (type) + { + case SceneObject::Arc: + NewMainPathItem(VPieceNode(id, Tool::NodeArc, reverse)); + break; + case SceneObject::Point: + NewMainPathItem(VPieceNode(id, Tool::NodePoint)); + break; + case SceneObject::Spline: + NewMainPathItem(VPieceNode(id, Tool::NodeSpline, reverse)); + break; + case SceneObject::SplinePath: + NewMainPathItem(VPieceNode(id, Tool::NodeSplinePath, reverse)); + break; + case (SceneObject::Line): + case (SceneObject::Detail): + case (SceneObject::Unknown): + default: + qDebug() << "Got wrong scene object. Ignore."; + break; + } + } + else + { + if (ui->listWidgetMainPath->count() > 1) + { + delete GetItemById(id); + } + } + + ValidObjects(MainPathIsValid()); + + if (not applyAllowed) + { + auto visPath = qobject_cast<VisToolPiece *>(vis); + SCASSERT(visPath != nullptr); + const VPiece p = CreatePiece(); + visPath->SetPiece(p); + + if (p.GetPath().CountNodes() == 1) + { + emit ToolTip(tr("Select main path objects clockwise, <b>Shift</b> - reverse direction curve, " + "<b>Enter</b> - finish creation")); + + if (not qApp->getCurrentScene()->items().contains(visPath)) + { + visPath->VisualMode(NULL_ID); + } + else + { + visPath->RefreshGeometry(); + } + } + else + { + visPath->RefreshGeometry(); + } + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::ShowDialog(bool click) +{ + if (click == false) + { + emit ToolTip(""); + prepare = true; + + if (not applyAllowed) + { + auto visPath = qobject_cast<VisToolPiece *>(vis); + SCASSERT(visPath != nullptr); + visPath->SetMode(Mode::Show); + visPath->RefreshGeometry(); + } + + // Fix issue #526. Dialog Detail is not on top after selection second object on Mac. + setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); + show(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::SaveData() +{} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::CheckState() +{ + SCASSERT(bOk != nullptr); + bOk->setEnabled(flagName && flagError && flagFormula); + // In case dialog hasn't apply button + if ( bApply != nullptr && applyAllowed) + { + bApply->setEnabled(bOk->isEnabled()); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::UpdateList() +{ + ui->listWidgetMCP->clear(); + for (int i = 0; i < m_conMCP.count(); ++i) + { + MaterialCutPlacement mcp = m_conMCP.at(i); + QString qsText = tr("Cut %1 of %2%3").arg(mcp.m_iCutNumber); + if (mcp.m_eMaterial < MaterialType::mtUserDefined) + { + qsText = qsText.arg(m_qslMaterials[int(mcp.m_eMaterial)]); + } + else + { + qsText = qsText.arg(mcp.m_qsMaterialUserDef); + } + if (mcp.m_ePlacement == PlacementType::ptCutOnFold) + { + qsText = qsText.arg(QLatin1String(" ") + tr("on Fold")); + } + else + { + qsText = qsText.arg(""); + } + + ui->listWidgetMCP->addItem(qsText); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::AddUpdate() +{ + MaterialCutPlacement mcp; + QStringList qslUserMaterials = qApp->Settings()->GetUserDefinedMaterials(); + +#if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) + int i = ui->comboBoxMaterial->itemData(ui->comboBoxMaterial->currentIndex()).toInt(); +#else + int i = ui->comboBoxMaterial->currentData().toInt(); +#endif + QString qsMat = ui->comboBoxMaterial->currentText(); + if (i < m_qslMaterials.count() && qsMat == m_qslMaterials[i]) + { + mcp.m_eMaterial = MaterialType(i); + mcp.m_qsMaterialUserDef.clear(); + } + else + { + mcp.m_eMaterial = MaterialType::mtUserDefined; + mcp.m_qsMaterialUserDef = qsMat; + // check if we have new user defined material + bool bFound = false; + for (int i = 0; i < qslUserMaterials.count() && bFound == false; ++i) + { + if (mcp.m_qsMaterialUserDef == qslUserMaterials[i]) + { + bFound = true; + } + } + if (bFound == false) + { + qApp->Settings()->AddUserDefinedMaterial(mcp.m_qsMaterialUserDef); + qApp->Settings()->sync(); + ui->comboBoxMaterial->addItem(mcp.m_qsMaterialUserDef, int(MaterialType::mtUserDefined)); + } + } + + mcp.m_iCutNumber = ui->spinBoxCutNumber->value(); + mcp.m_ePlacement = PlacementType(ui->comboBoxPlacement->currentIndex()); + + if (m_bAddMode == true) + { + m_conMCP << mcp; + } + else + { + int iR = ui->listWidgetMCP->currentRow(); + SCASSERT(iR >= 0) + m_conMCP[iR] = mcp; + SetAddMode(); + } + UpdateList(); + ClearFields(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::Cancel() +{ + ClearFields(); + SetAddMode(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::Remove() +{ + int iR = ui->listWidgetMCP->currentRow(); + SCASSERT(iR >= 0) + m_conMCP.removeAt(iR); + UpdateList(); + ClearFields(); + SetAddMode(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::NameDetailChanged() +{ + QLineEdit* edit = qobject_cast<QLineEdit*>(sender()); + if (edit) + { + if (edit->text().isEmpty()) + { + flagName = false; + ChangeColor(ui->labelEditName, Qt::red); + QIcon icon(":/icons/win.icon.theme/16x16/status/dialog-warning.png"); + ui->tabWidget->setTabIcon(1, icon); + } + else + { + flagName = true; + ChangeColor(ui->labelEditName, okColor); + QIcon icon; + ui->tabWidget->setTabIcon(1, icon); + } + } + CheckState(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::MaterialChanged() +{ + ui->pushButtonAdd->setEnabled(ui->comboBoxMaterial->currentText().isEmpty() == false); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::ShowMainPathContextMenu(const QPoint &pos) +{ + const int row = ui->listWidgetMainPath->currentRow(); + if (ui->listWidgetMainPath->count() == 0 || row == -1 || row >= ui->listWidgetMainPath->count()) + { + return; + } + + QMenu *menu = new QMenu(this); + + QListWidgetItem *rowItem = ui->listWidgetMainPath->item(row); + SCASSERT(rowItem != nullptr); + VPieceNode rowNode = qvariant_cast<VPieceNode>(rowItem->data(Qt::UserRole)); + + QAction *actionReverse = nullptr; + if (rowNode.GetTypeTool() != Tool::NodePoint) + { + actionReverse = menu->addAction(tr("Reverse")); + actionReverse->setCheckable(true); + actionReverse->setChecked(rowNode.GetReverse()); + } + + QAction *actionDelete = menu->addAction(QIcon::fromTheme("edit-delete"), tr("Delete")); + + QAction *selectedAction = menu->exec(ui->listWidgetMainPath->viewport()->mapToGlobal(pos)); + if (selectedAction == actionDelete) + { + delete ui->listWidgetMainPath->item(row); + ValidObjects(MainPathIsValid()); + } + else if (rowNode.GetTypeTool() != Tool::NodePoint && selectedAction == actionReverse) + { + rowNode.SetReverse(not rowNode.GetReverse()); + rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode)); + rowItem->setText(GetNodeName(rowNode)); + ValidObjects(MainPathIsValid()); + } + + ListChanged(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::ShowCustomSAContextMenu(const QPoint &pos) +{ + const int row = ui->listWidgetCustomSA->currentRow(); + if (ui->listWidgetCustomSA->count() == 0 || row == -1 || row >= ui->listWidgetCustomSA->count()) + { + return; + } + + QMenu *menu = new QMenu(this); + QAction *actionOption = menu->addAction(QIcon::fromTheme("preferences-other"), tr("Options")); + + QListWidgetItem *rowItem = ui->listWidgetCustomSA->item(row); + SCASSERT(rowItem != nullptr); + CustomSARecord record = qvariant_cast<CustomSARecord>(rowItem->data(Qt::UserRole)); + + QAction *actionReverse = menu->addAction(tr("Reverse")); + actionReverse->setCheckable(true); + actionReverse->setChecked(record.reverse); + + QAction *actionDelete = menu->addAction(QIcon::fromTheme("edit-delete"), tr("Delete")); + + QAction *selectedAction = menu->exec(ui->listWidgetCustomSA->viewport()->mapToGlobal(pos)); + if (selectedAction == actionDelete) + { + delete ui->listWidgetCustomSA->item(row); + } + else if (selectedAction == actionReverse) + { + record.reverse = not record.reverse; + rowItem->setData(Qt::UserRole, QVariant::fromValue(record)); + rowItem->setText(GetPathName(record.path, record.reverse)); + } + else if (selectedAction == actionOption) + { + auto *dialog = new DialogPiecePath(data, record.path, this); + dialog->SetPiecePath(data->GetPiecePath(record.path)); + dialog->SetPieceId(toolId); + if (record.includeType == PiecePathIncludeType::AsMainPath) + { + dialog->SetFormulaSAWidth(GetFormulaSAWidth()); + } + dialog->EnbleShowMode(true); + m_dialog = dialog; + m_dialog->setModal(true); + connect(m_dialog.data(), &DialogTool::DialogClosed, this, &DialogSeamAllowance::PathDialogClosed); + m_dialog->show(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::ShowInternalPathsContextMenu(const QPoint &pos) +{ + const int row = ui->listWidgetInternalPaths->currentRow(); + if (ui->listWidgetInternalPaths->count() == 0 || row == -1 || row >= ui->listWidgetInternalPaths->count()) + { + return; + } + + QMenu *menu = new QMenu(this); + QAction *actionOption = menu->addAction(QIcon::fromTheme("preferences-other"), tr("Options")); + QAction *actionDelete = menu->addAction(QIcon::fromTheme("edit-delete"), tr("Delete")); + + QAction *selectedAction = menu->exec(ui->listWidgetInternalPaths->viewport()->mapToGlobal(pos)); + if (selectedAction == actionDelete) + { + delete ui->listWidgetInternalPaths->item(row); + } + else if (selectedAction == actionOption) + { + QListWidgetItem *rowItem = ui->listWidgetInternalPaths->item(row); + SCASSERT(rowItem != nullptr); + const quint32 pathId = qvariant_cast<quint32>(rowItem->data(Qt::UserRole)); + + auto *dialog = new DialogPiecePath(data, pathId, this); + dialog->SetPiecePath(data->GetPiecePath(pathId)); + dialog->SetPieceId(toolId); + dialog->EnbleShowMode(true); + m_dialog = dialog; + m_dialog->setModal(true); + connect(m_dialog.data(), &DialogTool::DialogClosed, this, &DialogSeamAllowance::PathDialogClosed); + m_dialog->show(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::ListChanged() +{ + if (not applyAllowed) + { + auto visPath = qobject_cast<VisToolPiece *>(vis); + SCASSERT(visPath != nullptr); + visPath->SetPiece(CreatePiece()); + visPath->RefreshGeometry(); + } + InitNodesList(); + CustomSAChanged(ui->listWidgetCustomSA->currentRow()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::EnableSeamAllowance(bool enable) +{ + ui->groupBoxAutomatic->setEnabled(enable); + ui->groupBoxCustom->setEnabled(enable); + + if (enable) + { + InitNodesList(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::NodeChanged(int index) +{ + ui->plainTextEditFormulaWidthBefore->setDisabled(true); + ui->toolButtonExprBefore->setDisabled(true); + ui->pushButtonDefBefore->setDisabled(true); + + ui->plainTextEditFormulaWidthAfter->setDisabled(true); + ui->toolButtonExprAfter->setDisabled(true); + ui->pushButtonDefAfter->setDisabled(true); + + ui->comboBoxAngle->setDisabled(true); + + ui->comboBoxAngle->blockSignals(true); + + if (index != -1) + { + #if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) + const quint32 id = ui->comboBoxNodes->itemData(index).toUInt(); + #else + const quint32 id = ui->comboBoxNodes->currentData().toUInt(); + #endif + const VPiece piece = CreatePiece(); + const int nodeIndex = piece.GetPath().indexOfNode(id); + if (nodeIndex != -1) + { + const VPieceNode &node = piece.GetPath().at(nodeIndex); + + // Seam alowance before + ui->plainTextEditFormulaWidthBefore->setEnabled(true); + ui->toolButtonExprBefore->setEnabled(true); + + QString w1Formula = node.GetFormulaSABefore(); + if (w1Formula != currentSeamAllowance) + { + ui->pushButtonDefBefore->setEnabled(true); + } + if (w1Formula.length() > 80)// increase height if needed. + { + this->DeployWidthBeforeFormulaTextEdit(); + } + w1Formula = qApp->TrVars()->FormulaToUser(w1Formula, qApp->Settings()->GetOsSeparator()); + ui->plainTextEditFormulaWidthBefore->setPlainText(w1Formula); + MoveCursorToEnd(ui->plainTextEditFormulaWidthBefore); + + // Seam alowance after + ui->plainTextEditFormulaWidthAfter->setEnabled(true); + ui->toolButtonExprAfter->setEnabled(true); + + QString w2Formula = node.GetFormulaSAAfter(); + if (w2Formula != currentSeamAllowance) + { + ui->pushButtonDefAfter->setEnabled(true); + } + if (w2Formula.length() > 80)// increase height if needed. + { + this->DeployWidthAfterFormulaTextEdit(); + } + w2Formula = qApp->TrVars()->FormulaToUser(w2Formula, qApp->Settings()->GetOsSeparator()); + ui->plainTextEditFormulaWidthAfter->setPlainText(w2Formula); + MoveCursorToEnd(ui->plainTextEditFormulaWidthAfter); + + // Angle type + ui->comboBoxAngle->setEnabled(true); + const int index = ui->comboBoxAngle->findData(static_cast<unsigned char>(node.GetAngleType())); + if (index != -1) + { + ui->comboBoxAngle->setCurrentIndex(index); + } + } + } + else + { + ui->plainTextEditFormulaWidthBefore->setPlainText(""); + ui->plainTextEditFormulaWidthAfter->setPlainText(""); + ui->comboBoxAngle->setCurrentIndex(-1); + } + ui->comboBoxAngle->blockSignals(false); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::CSAStartPointChanged(int index) +{ + const int row = ui->listWidgetCustomSA->currentRow(); + if (ui->listWidgetCustomSA->count() == 0 || row == -1 || row >= ui->listWidgetCustomSA->count()) + { + return; + } + +#if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) + const quint32 startPoint = ui->comboBoxStartPoint->itemData(index).toUInt(); +#else + Q_UNUSED(index); + const quint32 startPoint = ui->comboBoxStartPoint->currentData().toUInt(); +#endif + + QListWidgetItem *rowItem = ui->listWidgetCustomSA->item(row); + SCASSERT(rowItem != nullptr); + CustomSARecord record = qvariant_cast<CustomSARecord>(rowItem->data(Qt::UserRole)); + record.startPoint = startPoint; + rowItem->setData(Qt::UserRole, QVariant::fromValue(record)); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::CSAEndPointChanged(int index) +{ + const int row = ui->listWidgetCustomSA->currentRow(); + if (ui->listWidgetCustomSA->count() == 0 || row == -1 || row >= ui->listWidgetCustomSA->count()) + { + return; + } + +#if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) + const quint32 endPoint = ui->comboBoxEndPoint->itemData(index).toUInt(); +#else + Q_UNUSED(index); + const quint32 endPoint = ui->comboBoxEndPoint->currentData().toUInt(); +#endif + + QListWidgetItem *rowItem = ui->listWidgetCustomSA->item(row); + SCASSERT(rowItem != nullptr); + CustomSARecord record = qvariant_cast<CustomSARecord>(rowItem->data(Qt::UserRole)); + record.endPoint = endPoint; + rowItem->setData(Qt::UserRole, QVariant::fromValue(record)); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::CSAIncludeTypeChanged(int index) +{ + const int row = ui->listWidgetCustomSA->currentRow(); + if (ui->listWidgetCustomSA->count() == 0 || row == -1 || row >= ui->listWidgetCustomSA->count()) + { + return; + } + +#if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) + const PiecePathIncludeType type = + static_cast<PiecePathIncludeType>(ui->comboBoxIncludeType->itemData(index).toUInt()); +#else + Q_UNUSED(index); + const PiecePathIncludeType type = + static_cast<PiecePathIncludeType>(ui->comboBoxIncludeType->currentData().toUInt()); +#endif + + QListWidgetItem *rowItem = ui->listWidgetCustomSA->item(row); + SCASSERT(rowItem != nullptr); + CustomSARecord record = qvariant_cast<CustomSARecord>(rowItem->data(Qt::UserRole)); + record.includeType = type; + rowItem->setData(Qt::UserRole, QVariant::fromValue(record)); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::NodeAngleChanged(int index) +{ + const int i = ui->comboBoxNodes->currentIndex(); + if (i != -1 && index != -1) + { + #if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) + const quint32 id = ui->comboBoxNodes->itemData(i).toUInt(); + #else + const quint32 id = ui->comboBoxNodes->currentData().toUInt(); + #endif + + QListWidgetItem *rowItem = GetItemById(id); + if (rowItem) + { + #if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) + const PieceNodeAngle angle = static_cast<PieceNodeAngle>(ui->comboBoxAngle->itemData(index).toUInt()); + #else + const PieceNodeAngle angle = static_cast<PieceNodeAngle>(ui->comboBoxAngle->currentData().toUInt()); + #endif + + VPieceNode rowNode = qvariant_cast<VPieceNode>(rowItem->data(Qt::UserRole)); + rowNode.SetAngleType(angle); + rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode)); + + ListChanged(); + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::ReturnDefBefore() +{ + ui->plainTextEditFormulaWidthBefore->setPlainText(currentSeamAllowance); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::ReturnDefAfter() +{ + ui->plainTextEditFormulaWidthAfter->setPlainText(currentSeamAllowance); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::CustomSAChanged(int row) +{ + if (ui->listWidgetCustomSA->count() == 0 || row == -1 || row >= ui->listWidgetCustomSA->count()) + { + ui->comboBoxStartPoint->blockSignals(true); + ui->comboBoxStartPoint->clear(); + ui->comboBoxStartPoint->blockSignals(false); + + ui->comboBoxEndPoint->blockSignals(true); + ui->comboBoxEndPoint->clear(); + ui->comboBoxEndPoint->blockSignals(false); + + ui->comboBoxIncludeType->blockSignals(true); + ui->comboBoxIncludeType->clear(); + ui->comboBoxIncludeType->blockSignals(false); + return; + } + + const QListWidgetItem *item = ui->listWidgetCustomSA->item( row ); + SCASSERT(item != nullptr); + const CustomSARecord record = qvariant_cast<CustomSARecord>(item->data(Qt::UserRole)); + + ui->comboBoxStartPoint->blockSignals(true); + InitCSAPoint(ui->comboBoxStartPoint); + { + const int index = ui->comboBoxStartPoint->findData(record.startPoint); + if (index != -1) + { + ui->comboBoxStartPoint->setCurrentIndex(index); + } + } + ui->comboBoxStartPoint->blockSignals(false); + + ui->comboBoxEndPoint->blockSignals(true); + InitCSAPoint(ui->comboBoxEndPoint); + { + const int index = ui->comboBoxEndPoint->findData(record.endPoint); + if (index != -1) + { + ui->comboBoxEndPoint->setCurrentIndex(index); + } + } + ui->comboBoxEndPoint->blockSignals(false); + + ui->comboBoxIncludeType->blockSignals(true); + InitSAIncludeType(); + { + const int index = ui->comboBoxIncludeType->findData(static_cast<unsigned char>(record.includeType)); + if (index != -1) + { + ui->comboBoxIncludeType->setCurrentIndex(index); + } + } + ui->comboBoxIncludeType->blockSignals(false); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::PathDialogClosed(int result) +{ + if (result == QDialog::Accepted) + { + SCASSERT(not m_dialog.isNull()); + DialogPiecePath *dialogTool = qobject_cast<DialogPiecePath*>(m_dialog.data()); + SCASSERT(dialogTool != nullptr); + try + { + const VPiecePath newPath = dialogTool->GetPiecePath(); + const VPiecePath oldPath = data->GetPiecePath(dialogTool->GetToolId()); + + SavePiecePathOptions *saveCommand = new SavePiecePathOptions(oldPath, newPath, qApp->getCurrentDocument(), + const_cast<VContainer *>(data), + dialogTool->GetToolId()); + qApp->getUndoStack()->push(saveCommand); + UpdateCurrentCustomSARecord(); + UpdateCurrentInternalPathRecord(); + } + catch (const VExceptionBadId &e) + { + qCritical("%s\n\n%s\n\n%s", qUtf8Printable(tr("Error. Can't save piece path.")), + qUtf8Printable(e.ErrorMessage()), qUtf8Printable(e.DetailedInformation())); + } + } + delete m_dialog; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::UpdateValues() +{ + QPlainTextEdit* apleSender[2]; + apleSender[0] = ui->lineEditRotFormula; + apleSender[1] = ui->lineEditLenFormula; + bool bFormulasOK = true; + + for (int i = 0; i < 2; ++i) + { + QLabel* plbVal; + QLabel* plbText; + QString qsUnit; + if (i == 0) + { + plbVal = ui->labelRot; + plbText = ui->labelEditRot; + qsUnit = degreeSymbol; + } + else + { + plbVal = ui->labelLen; + plbText = ui->labelEditLen; + qsUnit = QLatin1String(" ") + VDomDocument::UnitsToStr(qApp->patternUnit()); + } + + plbVal->setToolTip(tr("Value")); + + QString qsFormula = apleSender[i]->toPlainText().simplified(); + Calculator cal; + QString qsVal; + try + { + qsFormula.replace("\n", " "); + qsFormula = qApp->TrVars()->FormulaFromUser(qsFormula, qApp->Settings()->GetOsSeparator()); + qreal dVal; + dVal = cal.EvalFormula(data->PlainVariables(), qsFormula); + if (qIsInf(dVal) == true || qIsNaN(dVal) == true) + { + throw qmu::QmuParserError(tr("Infinite/undefined result")); + } + else if (i == 1 && dVal <= 0.0) + { + throw qmu::QmuParserError(tr("Length should be positive")); + } + else + { + qsVal.setNum(dVal, 'f', 2); + ChangeColor(plbText, okColor); + } + } + catch (qmu::QmuParserError &e) + { + qsVal.clear(); + ChangeColor(plbText, Qt::red); + bFormulasOK = false; + plbVal->setToolTip(tr("Parser error: %1").arg(e.GetMsg())); + } + + if (qsVal.isEmpty() == false) + { + qsVal += qsUnit; + } + plbVal->setText(qsVal); + } + + bOk->setEnabled(bFormulasOK); + if (bFormulasOK == false) + { + QIcon icon(":/icons/win.icon.theme/16x16/status/dialog-warning.png"); + ui->tabWidget->setTabIcon(ui->tabWidget->indexOf(ui->tabGrainline), icon); + } + else + { + ResetWarning(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::SetAddMode() +{ + ui->pushButtonAdd->setText(tr("Add")); + ui->pushButtonCancel->hide(); + ui->pushButtonRemove->hide(); + ui->listWidgetMCP->setCurrentRow(-1); + m_bAddMode = true; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::SetEditMode() +{ + int iR = ui->listWidgetMCP->currentRow(); + // this method can be called by clicking on item or by update. In the latter case there is nothing else to do! + if (iR < 0 || iR >= m_conMCP.count()) + { + return; + } + + ui->pushButtonAdd->setText(tr("Update")); + ui->pushButtonCancel->show(); + ui->pushButtonRemove->show(); + + MaterialCutPlacement mcp = m_conMCP.at(iR); + if (mcp.m_eMaterial == MaterialType::mtUserDefined) + { + int iRow = qApp->Settings()->GetUserDefinedMaterials().indexOf(mcp.m_qsMaterialUserDef); + if (iRow >= 0) + { + ui->comboBoxMaterial->setCurrentIndex(iRow + m_qslMaterials.count()); + } + else + { + ui->comboBoxMaterial->setCurrentText(mcp.m_qsMaterialUserDef); + } + } + else + { + ui->comboBoxMaterial->setCurrentIndex(int(mcp.m_eMaterial)); + } + ui->spinBoxCutNumber->setValue(mcp.m_iCutNumber); + ui->comboBoxPlacement->setCurrentIndex(int(mcp.m_ePlacement)); + + m_bAddMode = false; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::EnableGrainlineRotation() +{ + ui->lineEditRotFormula->setEnabled(ui->checkBoxGrainline->isChecked()); + ui->lineEditLenFormula->setEnabled(ui->checkBoxGrainline->isChecked()); + ui->pushButtonRot->setEnabled(ui->checkBoxGrainline->isChecked()); + ui->pushButtonLen->setEnabled(ui->checkBoxGrainline->isChecked()); + ui->pushButtonShowLen->setEnabled(ui->checkBoxGrainline->isChecked()); + ui->pushButtonShowRot->setEnabled(ui->checkBoxGrainline->isChecked()); + + if (ui->checkBoxGrainline->isChecked() == true) + { + UpdateValues(); + } + else + { + ChangeColor(ui->labelEditLen, okColor); + ChangeColor(ui->labelEditRot, okColor); + bOk->setEnabled(true); + ResetWarning(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::EditFormula() +{ + QPlainTextEdit* pleFormula; + bool bCheckZero; + + if (sender() == ui->pushButtonLen) + { + pleFormula = ui->lineEditLenFormula; + bCheckZero = true; + } + else if (sender() == ui->pushButtonRot) + { + pleFormula = ui->lineEditRotFormula; + bCheckZero = false; + } + else + { + // should not get here! + return; + } + + DialogEditWrongFormula dlg(data, NULL_ID, this); + dlg.SetFormula(pleFormula->toPlainText()); + dlg.setCheckZero(bCheckZero); + if (dlg.exec() == QDialog::Accepted) + { + QString qsFormula = dlg.GetFormula(); + qsFormula.replace("\n", " "); + pleFormula->setPlainText(qsFormula); + UpdateValues(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::DeployRotation() +{ + DeployFormula(ui->lineEditRotFormula, ui->pushButtonShowRot, m_iRotBaseHeight); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::DeployLength() +{ + DeployFormula(ui->lineEditLenFormula, ui->pushButtonShowLen, m_iLenBaseHeight); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::ResetWarning() +{ + QIcon icon; + ui->tabWidget->setTabIcon(ui->tabWidget->indexOf(ui->tabGrainline), icon); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::EvalWidth() +{ + labelEditFormula = ui->labelEditWidth; + const QString postfix = VDomDocument::UnitsToStr(qApp->patternUnit(), true); + const QString formula = ui->plainTextEditFormulaWidth->toPlainText(); + m_saWidth = Eval(formula, flagFormula, ui->labelResultWidth, postfix, false, true); + + if (m_saWidth >= 0) + { + VContainer *locData = const_cast<VContainer *> (data); + locData->AddVariable(currentSeamAllowance, new VIncrement(locData, currentSeamAllowance, 0, m_saWidth, + QString().setNum(m_saWidth), true, + tr("Current seam allowance"))); + + EvalWidthBefore(); + EvalWidthAfter(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::EvalWidthBefore() +{ + labelEditFormula = ui->labelEditBefore; + const QString postfix = VDomDocument::UnitsToStr(qApp->patternUnit(), true); + const QString formula = ui->plainTextEditFormulaWidthBefore->toPlainText(); + bool flagFormula = false; // fake flag + Eval(formula, flagFormula, ui->labelResultBefore, postfix, false, true); + + UpdateNodeSABefore(GetFormulaSAWidthBefore()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::EvalWidthAfter() +{ + labelEditFormula = ui->labelEditAfter; + const QString postfix = VDomDocument::UnitsToStr(qApp->patternUnit(), true); + const QString formula = ui->plainTextEditFormulaWidthAfter->toPlainText(); + bool flagFormula = false; // fake flag + Eval(formula, flagFormula, ui->labelResultAfter, postfix, false, true); + + UpdateNodeSAAfter(GetFormulaSAWidthAfter()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::FXWidth() +{ + DialogEditWrongFormula *dialog = new DialogEditWrongFormula(data, toolId, this); + dialog->setWindowTitle(tr("Edit seam allowance width")); + dialog->SetFormula(GetFormulaSAWidth()); + dialog->setCheckLessThanZero(true); + dialog->setPostfix(VDomDocument::UnitsToStr(qApp->patternUnit(), true)); + if (dialog->exec() == QDialog::Accepted) + { + SetFormulaSAWidth(dialog->GetFormula()); + } + delete dialog; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::FXWidthBefore() +{ + DialogEditWrongFormula *dialog = new DialogEditWrongFormula(data, toolId, this); + dialog->setWindowTitle(tr("Edit seam allowance width before")); + dialog->SetFormula(GetFormulaSAWidthBefore()); + dialog->setCheckLessThanZero(true); + dialog->setPostfix(VDomDocument::UnitsToStr(qApp->patternUnit(), true)); + if (dialog->exec() == QDialog::Accepted) + { + SetCurrentSABefore(dialog->GetFormula()); + } + delete dialog; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::FXWidthAfter() +{ + DialogEditWrongFormula *dialog = new DialogEditWrongFormula(data, toolId, this); + dialog->setWindowTitle(tr("Edit seam allowance width after")); + dialog->SetFormula(GetFormulaSAWidthAfter()); + dialog->setCheckLessThanZero(true); + dialog->setPostfix(VDomDocument::UnitsToStr(qApp->patternUnit(), true)); + if (dialog->exec() == QDialog::Accepted) + { + SetCurrentSAAfter(dialog->GetFormula()); + } + delete dialog; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::WidthChanged() +{ + labelEditFormula = ui->labelEditWidth; + labelResultCalculation = ui->labelResultWidth; + const QString postfix = VDomDocument::UnitsToStr(qApp->patternUnit(), true); + ValFormulaChanged(flagFormula, ui->plainTextEditFormulaWidth, m_timerWidth, postfix); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::WidthBeforeChanged() +{ + labelEditFormula = ui->labelEditBefore; + labelResultCalculation = ui->labelResultBefore; + const QString postfix = VDomDocument::UnitsToStr(qApp->patternUnit(), true); + bool flagFormula = false; + ValFormulaChanged(flagFormula, ui->plainTextEditFormulaWidthBefore, m_timerWidthBefore, postfix); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::WidthAfterChanged() +{ + labelEditFormula = ui->labelEditAfter; + labelResultCalculation = ui->labelResultAfter; + const QString postfix = VDomDocument::UnitsToStr(qApp->patternUnit(), true); + bool flagFormula = false; + ValFormulaChanged(flagFormula, ui->plainTextEditFormulaWidthAfter, m_timerWidthAfter, postfix); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::DeployWidthFormulaTextEdit() +{ + DeployFormula(ui->plainTextEditFormulaWidth, ui->pushButtonGrowWidth, m_formulaBaseWidth); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::DeployWidthBeforeFormulaTextEdit() +{ + DeployFormula(ui->plainTextEditFormulaWidthBefore, ui->pushButtonGrowWidthBefore, m_formulaBaseWidthBefore); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::DeployWidthAfterFormulaTextEdit() +{ + DeployFormula(ui->plainTextEditFormulaWidthAfter, ui->pushButtonGrowWidthAfter, m_formulaBaseWidthAfter); +} + +//--------------------------------------------------------------------------------------------------------------------- +VPiece DialogSeamAllowance::CreatePiece() const +{ + VPiece piece; + for (qint32 i = 0; i < ui->listWidgetMainPath->count(); ++i) + { + QListWidgetItem *item = ui->listWidgetMainPath->item(i); + piece.GetPath().Append(qvariant_cast<VPieceNode>(item->data(Qt::UserRole))); + } + + QVector<CustomSARecord> records; + for (qint32 i = 0; i < ui->listWidgetCustomSA->count(); ++i) + { + QListWidgetItem *item = ui->listWidgetCustomSA->item(i); + records.append(qvariant_cast<CustomSARecord>(item->data(Qt::UserRole))); + } + piece.SetCustomSARecords(records); + + QVector<quint32> iPaths; + for (qint32 i = 0; i < ui->listWidgetInternalPaths->count(); ++i) + { + QListWidgetItem *item = ui->listWidgetInternalPaths->item(i); + iPaths.append(qvariant_cast<quint32>(item->data(Qt::UserRole))); + } + piece.SetInternalPaths(iPaths); + + piece.SetForbidFlipping(ui->checkBoxForbidFlipping->isChecked()); + piece.SetSeamAllowance(ui->checkBoxSeams->isChecked()); + piece.SetName(ui->lineEditName->text()); + piece.SetMx(m_mx); + piece.SetMy(m_my); + + QString width = ui->plainTextEditFormulaWidth->toPlainText(); + width.replace("\n", " "); + piece.SetFormulaSAWidth(width, m_saWidth); + + piece.GetPatternPieceData().SetLetter(ui->lineEditLetter->text()); + + for (int i = 0; i < m_conMCP.count(); ++i) + { + piece.GetPatternPieceData().Append(m_conMCP[i]); + } + + piece.GetPatternPieceData().SetPos(m_oldData.GetPos()); + piece.GetPatternPieceData().SetLabelWidth(m_oldData.GetLabelWidth()); + piece.GetPatternPieceData().SetLabelHeight(m_oldData.GetLabelHeight()); + piece.GetPatternPieceData().SetFontSize(m_oldData.GetFontSize()); + piece.GetPatternPieceData().SetRotation(m_oldData.GetRotation()); + piece.GetPatternPieceData().SetVisible(ui->checkBoxDetail->isChecked()); + + piece.GetPatternInfo() = m_oldGeom; + piece.GetPatternInfo().SetVisible(ui->checkBoxPattern->isChecked()); + + piece.GetGrainlineGeometry() = m_oldGrainline; + piece.GetGrainlineGeometry().SetVisible(ui->checkBoxGrainline->isChecked()); + piece.GetGrainlineGeometry().SetRotation(ui->lineEditRotFormula->toPlainText()); + piece.GetGrainlineGeometry().SetLength(ui->lineEditLenFormula->toPlainText()); + piece.GetGrainlineGeometry().SetArrowType(VGrainlineGeometry::ArrowType(ui->comboBoxArrow->currentIndex())); + + return piece; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::NewMainPathItem(const VPieceNode &node) +{ + NewNodeItem(ui->listWidgetMainPath, node); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::NewCustomSA(const CustomSARecord &record) +{ + if (record.path > NULL_ID) + { + const QString name = GetPathName(record.path, record.reverse); + + QListWidgetItem *item = new QListWidgetItem(name); + item->setFont(QFont("Times", 12, QFont::Bold)); + item->setData(Qt::UserRole, QVariant::fromValue(record)); + ui->listWidgetCustomSA->addItem(item); + ui->listWidgetCustomSA->setCurrentRow(ui->listWidgetCustomSA->count()-1); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::NewInternalPath(quint32 path) +{ + if (path > NULL_ID) + { + const QString name = GetPathName(path); + + QListWidgetItem *item = new QListWidgetItem(name); + item->setFont(QFont("Times", 12, QFont::Bold)); + item->setData(Qt::UserRole, QVariant::fromValue(path)); + ui->listWidgetInternalPaths->addItem(item); + ui->listWidgetInternalPaths->setCurrentRow(ui->listWidgetInternalPaths->count()-1); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +QString DialogSeamAllowance::GetPathName(quint32 path, bool reverse) const +{ + QString name; + + if (path > NULL_ID) + { + name = data->GetPiecePath(path).GetName(); + + if (reverse) + { + name = QLatin1String("- ") + name; + } + } + + return name; +} + +//--------------------------------------------------------------------------------------------------------------------- +bool DialogSeamAllowance::MainPathIsValid() const +{ + QString url = DialogWarningIcon(); + + if(CreatePiece().MainPathPoints(data).count() < 3) + { + url += tr("You need more points!"); + ui->helpLabel->setText(url); + return false; + } + else + { + if(not MainPathIsClockwise()) + { + url += tr("You have to choose points in a clockwise direction!"); + ui->helpLabel->setText(url); + return false; + } + if (FirstPointEqualLast(ui->listWidgetMainPath)) + { + url += tr("First point cannot be equal to the last point!"); + ui->helpLabel->setText(url); + return false; + } + else if (DoublePoints(ui->listWidgetMainPath)) + { + url += tr("You have double points!"); + ui->helpLabel->setText(url); + return false; + } + } + ui->helpLabel->setText(tr("Ready!")); + return true; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::ValidObjects(bool value) +{ + flagError = value; + CheckState(); +} + +//--------------------------------------------------------------------------------------------------------------------- +bool DialogSeamAllowance::MainPathIsClockwise() const +{ + const QVector<QPointF> points = CreatePiece().MainPathPoints(data); + + if(points.count() < 3) + { + return false; + } + + const qreal res = VPiece::SumTrapezoids(points); + if (res < 0) + { + return true; + } + return false; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::InitNodesList() +{ +#if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) + const quint32 id = ui->comboBoxNodes->itemData(ui->comboBoxNodes->currentIndex()).toUInt(); +#else + const quint32 id = ui->comboBoxNodes->currentData().toUInt(); +#endif + + ui->comboBoxNodes->blockSignals(true); + ui->comboBoxNodes->clear(); + + const VPiece piece = CreatePiece(); + + for (int i = 0; i < piece.GetPath().CountNodes(); ++i) + { + const VPieceNode node = piece.GetPath().at(i); + if (node.GetTypeTool() == Tool::NodePoint) + { + const QString name = GetNodeName(node); + + ui->comboBoxNodes->addItem(name, node.GetId()); + } + } + ui->comboBoxNodes->blockSignals(false); + + const int index = ui->comboBoxNodes->findData(id); + if (index != -1) + { + ui->comboBoxNodes->setCurrentIndex(index); + NodeChanged(index);// Need in case combox index was not changed + } + else + { + ui->comboBoxNodes->count() > 0 ? NodeChanged(0) : NodeChanged(-1); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +QListWidgetItem *DialogSeamAllowance::GetItemById(quint32 id) +{ + for (qint32 i = 0; i < ui->listWidgetMainPath->count(); ++i) + { + QListWidgetItem *item = ui->listWidgetMainPath->item(i); + const VPieceNode node = qvariant_cast<VPieceNode>(item->data(Qt::UserRole)); + + if (node.GetId() == id) + { + return item; + } + } + return nullptr; +} + +//--------------------------------------------------------------------------------------------------------------------- +quint32 DialogSeamAllowance::GetLastId() const +{ + const int count = ui->listWidgetMainPath->count(); + if (count > 0) + { + QListWidgetItem *item = ui->listWidgetMainPath->item(count-1); + const VPieceNode node = qvariant_cast<VPieceNode>(item->data(Qt::UserRole)); + return node.GetId(); + } + else + { + return NULL_ID; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::SetCurrentSABefore(const QString &formula) +{ + UpdateNodeSABefore(formula); + ListChanged(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::SetCurrentSAAfter(const QString &formula) +{ + UpdateNodeSAAfter(formula); + ListChanged(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::UpdateNodeSABefore(const QString &formula) +{ + const int index = ui->comboBoxNodes->currentIndex(); + if (index != -1) + { + #if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) + const quint32 id = ui->comboBoxNodes->itemData(index).toUInt(); + #else + const quint32 id = ui->comboBoxNodes->currentData().toUInt(); + #endif + + QListWidgetItem *rowItem = GetItemById(id); + if (rowItem) + { + VPieceNode rowNode = qvariant_cast<VPieceNode>(rowItem->data(Qt::UserRole)); + rowNode.SetFormulaSABefore(formula); + rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode)); + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::UpdateNodeSAAfter(const QString &formula) +{ + const int index = ui->comboBoxNodes->currentIndex(); + if (index != -1) + { + #if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) + const quint32 id = ui->comboBoxNodes->itemData(index).toUInt(); + #else + const quint32 id = ui->comboBoxNodes->currentData().toUInt(); + #endif + + QListWidgetItem *rowItem = GetItemById(id); + if (rowItem) + { + VPieceNode rowNode = qvariant_cast<VPieceNode>(rowItem->data(Qt::UserRole)); + rowNode.SetFormulaSAAfter(formula); + rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode)); + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::InitMainPathTab() +{ + ui->checkBoxForbidFlipping->setChecked(qApp->Settings()->GetForbidWorkpieceFlipping()); + + ui->listWidgetMainPath->setContextMenuPolicy(Qt::CustomContextMenu); + connect(ui->listWidgetMainPath, &QListWidget::customContextMenuRequested, this, + &DialogSeamAllowance::ShowMainPathContextMenu); + connect(ui->listWidgetMainPath->model(), &QAbstractItemModel::rowsMoved, this, &DialogSeamAllowance::ListChanged); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::InitSeamAllowanceTab() +{ + plainTextEditFormula = ui->plainTextEditFormulaWidth; + this->m_formulaBaseWidth = ui->plainTextEditFormulaWidth->height(); + this->m_formulaBaseWidthBefore = ui->plainTextEditFormulaWidthBefore->height(); + this->m_formulaBaseWidthAfter = ui->plainTextEditFormulaWidthAfter->height(); + + ui->plainTextEditFormulaWidth->installEventFilter(this); + ui->plainTextEditFormulaWidthBefore->installEventFilter(this); + ui->plainTextEditFormulaWidthAfter->installEventFilter(this); + + m_timerWidth = new QTimer(this); + connect(m_timerWidth, &QTimer::timeout, this, &DialogSeamAllowance::EvalWidth); + + m_timerWidthBefore = new QTimer(this); + connect(m_timerWidthBefore, &QTimer::timeout, this, &DialogSeamAllowance::EvalWidthBefore); + + m_timerWidthAfter = new QTimer(this); + connect(m_timerWidthAfter, &QTimer::timeout, this, &DialogSeamAllowance::EvalWidthAfter); + + connect(ui->checkBoxSeams, &QCheckBox::toggled, this, &DialogSeamAllowance::EnableSeamAllowance); + + // Default value for seam allowence is 1 cm. But pattern have different units, so just set 1 in dialog not enough. + m_saWidth = UnitConvertor(1, Unit::Cm, qApp->patternUnit()); + ui->plainTextEditFormulaWidth->setPlainText(qApp->LocaleToString(m_saWidth)); + + InitNodesList(); + connect(ui->comboBoxNodes, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, + &DialogSeamAllowance::NodeChanged); + + connect(ui->pushButtonDefBefore, &QPushButton::clicked, this, &DialogSeamAllowance::ReturnDefBefore); + connect(ui->pushButtonDefAfter, &QPushButton::clicked, this, &DialogSeamAllowance::ReturnDefAfter); + + InitNodeAngles(ui->comboBoxAngle); + connect(ui->comboBoxAngle, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, + &DialogSeamAllowance::NodeAngleChanged); + + ui->listWidgetCustomSA->setContextMenuPolicy(Qt::CustomContextMenu); + connect(ui->listWidgetCustomSA, &QListWidget::customContextMenuRequested, this, + &DialogSeamAllowance::ShowCustomSAContextMenu); + connect(ui->listWidgetCustomSA, &QListWidget::currentRowChanged, this, &DialogSeamAllowance::CustomSAChanged); + connect(ui->comboBoxStartPoint, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, + &DialogSeamAllowance::CSAStartPointChanged); + connect(ui->comboBoxEndPoint, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, + &DialogSeamAllowance::CSAEndPointChanged); + connect(ui->comboBoxIncludeType, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, + &DialogSeamAllowance::CSAIncludeTypeChanged); + + connect(ui->toolButtonExprWidth, &QPushButton::clicked, this, &DialogSeamAllowance::FXWidth); + connect(ui->toolButtonExprBefore, &QPushButton::clicked, this, &DialogSeamAllowance::FXWidthBefore); + connect(ui->toolButtonExprAfter, &QPushButton::clicked, this, &DialogSeamAllowance::FXWidthAfter); + + connect(ui->plainTextEditFormulaWidth, &QPlainTextEdit::textChanged, this, &DialogSeamAllowance::WidthChanged); + connect(ui->plainTextEditFormulaWidthBefore, &QPlainTextEdit::textChanged, this, + &DialogSeamAllowance::WidthBeforeChanged); + connect(ui->plainTextEditFormulaWidthAfter, &QPlainTextEdit::textChanged, this, + &DialogSeamAllowance::WidthAfterChanged); + + connect(ui->pushButtonGrowWidth, &QPushButton::clicked, this, &DialogSeamAllowance::DeployWidthFormulaTextEdit); + connect(ui->pushButtonGrowWidthBefore, &QPushButton::clicked, + this, &DialogSeamAllowance::DeployWidthBeforeFormulaTextEdit); + connect(ui->pushButtonGrowWidthAfter, &QPushButton::clicked, this, + &DialogSeamAllowance::DeployWidthAfterFormulaTextEdit); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::InitCSAPoint(QComboBox *box) +{ + SCASSERT(box != nullptr); + box->clear(); + box->addItem(tr("Empty"), NULL_ID); + + const VPiece piece = CreatePiece(); + + for (int i = 0; i < piece.GetPath().CountNodes(); ++i) + { + const VPieceNode &node = piece.GetPath().at(i); + if (node.GetTypeTool() == Tool::NodePoint) + { + const QString name = GetNodeName(node); + box->addItem(name, node.GetId()); + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::InitSAIncludeType() +{ + ui->comboBoxIncludeType->clear(); + + ui->comboBoxIncludeType->addItem(tr("main path"), static_cast<unsigned char>(PiecePathIncludeType::AsMainPath)); + ui->comboBoxIncludeType->addItem(tr("custom seam allowance"), + static_cast<unsigned char>(PiecePathIncludeType::AsCustomSA)); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::InitInternalPathsTab() +{ + ui->listWidgetInternalPaths->setContextMenuPolicy(Qt::CustomContextMenu); + connect(ui->listWidgetInternalPaths, &QListWidget::customContextMenuRequested, this, + &DialogSeamAllowance::ShowInternalPathsContextMenu); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::InitPatternPieceDataTab() +{ +#if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0) + ui->lineEditName->setClearButtonEnabled(true); + ui->lineEditLetter->setClearButtonEnabled(true); +#endif + + connect(ui->lineEditName, &QLineEdit::textChanged, this, &DialogSeamAllowance::NameDetailChanged); + + m_qslMaterials << QApplication::translate("Detail", "Fabric", 0) + << QApplication::translate("Detail", "Lining", 0) + << QApplication::translate("Detail", "Interfacing", 0) + << QApplication::translate("Detail", "Interlining", 0); + + for (int i = 0; i < m_qslMaterials.count(); ++i) + { + ui->comboBoxMaterial->addItem(m_qslMaterials[i], i); + } + + const QStringList qsl = qApp->Settings()->GetUserDefinedMaterials(); + for (int i = 0; i < qsl.count(); ++i) + { + ui->comboBoxMaterial->addItem(qsl.at(i), int(MaterialType::mtUserDefined)); + } + + m_qslPlacements << tr("None") << tr("Cut on fold"); + ui->comboBoxPlacement->addItems(m_qslPlacements); + ui->pushButtonRot->setIcon(QIcon("://icon/16x16/fx.png")); + ui->pushButtonLen->setIcon(QIcon("://icon/16x16/fx.png")); + + connect(ui->pushButtonAdd, &QPushButton::clicked, this, &DialogSeamAllowance::AddUpdate); + connect(ui->pushButtonCancel, &QPushButton::clicked, this, &DialogSeamAllowance::Cancel); + connect(ui->pushButtonRemove, &QPushButton::clicked, this, &DialogSeamAllowance::Remove); + connect(ui->listWidgetMCP, &QListWidget::itemClicked, this, &DialogSeamAllowance::SetEditMode); + connect(ui->comboBoxMaterial, &QComboBox::currentTextChanged, this, &DialogSeamAllowance::MaterialChanged); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::InitGrainlineTab() +{ + connect(ui->checkBoxGrainline, &QCheckBox::toggled, this, &DialogSeamAllowance::EnableGrainlineRotation); + connect(ui->pushButtonRot, &QPushButton::clicked, this, &DialogSeamAllowance::EditFormula); + connect(ui->pushButtonLen, &QPushButton::clicked, this, &DialogSeamAllowance::EditFormula); + connect(ui->lineEditLenFormula, &QPlainTextEdit::textChanged, this, &DialogSeamAllowance::UpdateValues); + connect(ui->lineEditRotFormula, &QPlainTextEdit::textChanged, this, &DialogSeamAllowance::UpdateValues); + + connect(ui->pushButtonShowRot, &QPushButton::clicked, this, &DialogSeamAllowance::DeployRotation); + connect(ui->pushButtonShowLen, &QPushButton::clicked, this, &DialogSeamAllowance::DeployLength); + + SetAddMode(); + EnableGrainlineRotation(); + + ui->comboBoxArrow->addItem(tr("Both")); + ui->comboBoxArrow->addItem(tr("Just front")); + ui->comboBoxArrow->addItem(tr("Just rear")); + + m_iRotBaseHeight = ui->lineEditRotFormula->height(); + m_iLenBaseHeight = ui->lineEditLenFormula->height(); +} + +//--------------------------------------------------------------------------------------------------------------------- +QString DialogSeamAllowance::GetFormulaSAWidth() const +{ + QString width = ui->plainTextEditFormulaWidth->toPlainText(); + width.replace("\n", " "); + return qApp->TrVars()->TryFormulaFromUser(width, qApp->Settings()->GetOsSeparator()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::SetFormulaSAWidth(const QString &formula) +{ + const QString width = qApp->TrVars()->FormulaToUser(formula, qApp->Settings()->GetOsSeparator()); + // increase height if needed. + if (width.length() > 80) + { + this->DeployWidthFormulaTextEdit(); + } + ui->plainTextEditFormulaWidth->setPlainText(width); + + VisToolPiece *path = qobject_cast<VisToolPiece *>(vis); + SCASSERT(path != nullptr) + const VPiece p = CreatePiece(); + path->SetPiece(p); + + MoveCursorToEnd(ui->plainTextEditFormulaWidth); +} + +//--------------------------------------------------------------------------------------------------------------------- +QString DialogSeamAllowance::GetFormulaSAWidthBefore() const +{ + QString width = ui->plainTextEditFormulaWidthBefore->toPlainText(); + width.replace("\n", " "); + return qApp->TrVars()->TryFormulaFromUser(width, qApp->Settings()->GetOsSeparator()); +} + +//--------------------------------------------------------------------------------------------------------------------- +QString DialogSeamAllowance::GetFormulaSAWidthAfter() const +{ + QString width = ui->plainTextEditFormulaWidthAfter->toPlainText(); + width.replace("\n", " "); + return qApp->TrVars()->TryFormulaFromUser(width, qApp->Settings()->GetOsSeparator()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::UpdateCurrentCustomSARecord() +{ + const int row = ui->listWidgetCustomSA->currentRow(); + if (ui->listWidgetCustomSA->count() == 0 || row == -1) + { + return; + } + + QListWidgetItem *item = ui->listWidgetCustomSA->item(row); + SCASSERT(item != nullptr); + const CustomSARecord record = qvariant_cast<CustomSARecord>(item->data(Qt::UserRole)); + item->setText(GetPathName(record.path, record.reverse)); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::UpdateCurrentInternalPathRecord() +{ + const int row = ui->listWidgetInternalPaths->currentRow(); + if (ui->listWidgetInternalPaths->count() == 0 || row == -1) + { + return; + } + + QListWidgetItem *item = ui->listWidgetInternalPaths->item(row); + SCASSERT(item != nullptr); + const quint32 path = qvariant_cast<quint32>(item->data(Qt::UserRole)); + item->setText(GetPathName(path)); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::ClearFields() +{ + ui->comboBoxMaterial->setCurrentIndex(0); + ui->spinBoxCutNumber->setValue(0); + ui->comboBoxPlacement->setCurrentIndex(0); +} diff --git a/src/libs/vtools/dialogs/tools/dialogseamallowance.h b/src/libs/vtools/dialogs/tools/dialogseamallowance.h new file mode 100644 index 000000000..ece3aff7a --- /dev/null +++ b/src/libs/vtools/dialogs/tools/dialogseamallowance.h @@ -0,0 +1,185 @@ +/************************************************************************ + ** + ** @file dialogseamallowance.h + ** @author Roman Telezhynskyi <dismine(at)gmail.com> + ** @date 3 11, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2016 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#ifndef DIALOGSEAMALLOWANCE_H +#define DIALOGSEAMALLOWANCE_H + +#include "dialogtool.h" +#include "../vpatterndb/vpiece.h" +#include "../vpatterndb/vpatterninfogeometry.h" +#include "../vpatterndb/vpatternpiecedata.h" +#include "../vpatterndb/vgrainlinegeometry.h" + +namespace Ui +{ + class DialogSeamAllowance; +} + +class DialogSeamAllowance : public DialogTool +{ + Q_OBJECT + +public: + DialogSeamAllowance(const VContainer *data, const quint32 &toolId, QWidget *parent = nullptr); + virtual ~DialogSeamAllowance(); + + void EnableApply(bool enable); + + VPiece GetPiece() const; + void SetPiece(const VPiece &m_piece); + + QString GetFormulaSAWidth() const; + +public slots: + virtual void ChosenObject(quint32 id, const SceneObject &type) Q_DECL_OVERRIDE; + virtual void ShowDialog(bool click) Q_DECL_OVERRIDE; + +protected: + /** @brief SaveData Put dialog data in local variables */ + virtual void SaveData() Q_DECL_OVERRIDE; + virtual void CheckState() Q_DECL_OVERRIDE; + +protected slots: + void UpdateList(); + void AddUpdate(); + void Cancel(); + void Remove(); + +private slots: + void NameDetailChanged(); + void MaterialChanged(); + void ShowMainPathContextMenu(const QPoint &pos); + void ShowCustomSAContextMenu(const QPoint &pos); + void ShowInternalPathsContextMenu(const QPoint &pos); + + void ListChanged(); + void EnableSeamAllowance(bool enable); + void NodeChanged(int index); + void CSAStartPointChanged(int index); + void CSAEndPointChanged(int index); + void CSAIncludeTypeChanged(int index); + void NodeAngleChanged(int index); + void ReturnDefBefore(); + void ReturnDefAfter(); + void CustomSAChanged(int row); + void PathDialogClosed(int result); + + void UpdateValues(); + void SetAddMode(); + void SetEditMode(); + void EnableGrainlineRotation(); + void EditFormula(); + void DeployRotation(); + void DeployLength(); + void ResetWarning(); + + void EvalWidth(); + void EvalWidthBefore(); + void EvalWidthAfter(); + + void FXWidth(); + void FXWidthBefore(); + void FXWidthAfter(); + + void WidthChanged(); + void WidthBeforeChanged(); + void WidthAfterChanged(); + + void DeployWidthFormulaTextEdit(); + void DeployWidthBeforeFormulaTextEdit(); + void DeployWidthAfterFormulaTextEdit(); + +private: + Q_DISABLE_COPY(DialogSeamAllowance) + + Ui::DialogSeamAllowance *ui; + bool applyAllowed; + bool m_bAddMode; + qreal m_mx; + qreal m_my; + + QPointer<DialogTool> m_dialog; + + QStringList m_qslMaterials; + QStringList m_qslPlacements; + // temporary container for Material/Cut/Placement 3-tuples + MCPContainer m_conMCP; + + VPatternPieceData m_oldData; + VPatternInfoGeometry m_oldGeom; + VGrainlineGeometry m_oldGrainline; + int m_iRotBaseHeight; + int m_iLenBaseHeight; + int m_formulaBaseWidth; + int m_formulaBaseWidthBefore; + int m_formulaBaseWidthAfter; + + QTimer *m_timerWidth; + QTimer *m_timerWidthBefore; + QTimer *m_timerWidthAfter; + qreal m_saWidth; + + VPiece CreatePiece() const; + + void NewMainPathItem(const VPieceNode &node); + void NewCustomSA(const CustomSARecord &record); + void NewInternalPath(quint32 path); + QString GetPathName(quint32 path, bool reverse = false) const; + bool MainPathIsValid() const; + void ValidObjects(bool value); + bool MainPathIsClockwise() const; + void UpdateCurrentCustomSARecord(); + void UpdateCurrentInternalPathRecord(); + void ClearFields(); + + QListWidgetItem *GetItemById(quint32 id); + + quint32 GetLastId() const; + + void SetCurrentSABefore(const QString &formula); + void SetCurrentSAAfter(const QString &formula); + + void UpdateNodeSABefore(const QString &formula); + void UpdateNodeSAAfter(const QString &formula); + + void InitMainPathTab(); + void InitSeamAllowanceTab(); + void InitNodesList(); + void InitCSAPoint(QComboBox *box); + void InitSAIncludeType(); + void InitInternalPathsTab(); + void InitPatternPieceDataTab(); + void InitGrainlineTab(); + + void SetFormulaSAWidth(const QString &formula); + + QString GetFormulaSAWidthBefore() const; + QString GetFormulaSAWidthAfter() const; +}; + +#endif // DIALOGSEAMALLOWANCE_H diff --git a/src/libs/vtools/dialogs/tools/dialogseamallowance.ui b/src/libs/vtools/dialogs/tools/dialogseamallowance.ui new file mode 100644 index 000000000..315098dc5 --- /dev/null +++ b/src/libs/vtools/dialogs/tools/dialogseamallowance.ui @@ -0,0 +1,1581 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>DialogSeamAllowance</class> + <widget class="QDialog" name="DialogSeamAllowance"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>521</width> + <height>611</height> + </rect> + </property> + <property name="windowTitle"> + <string>Seam allowance tool</string> + </property> + <property name="windowIcon"> + <iconset resource="../../../vmisc/share/resources/icon.qrc"> + <normaloff>:/icon/64x64/icon64x64.png</normaloff>:/icon/64x64/icon64x64.png</iconset> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QTabWidget" name="tabWidget"> + <property name="currentIndex"> + <number>1</number> + </property> + <widget class="QWidget" name="tabMainPath"> + <attribute name="title"> + <string>Main path</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_8"> + <item> + <widget class="QLabel" name="label_3"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string/> + </property> + <property name="pixmap"> + <pixmap resource="../../../vmisc/share/resources/icon.qrc">:/icon/32x32/clockwise.png</pixmap> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>All objects in path should follow in clockwise direction.</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QCheckBox" name="checkBoxForbidFlipping"> + <property name="toolTip"> + <string>Forbid piece be mirrored in a layout.</string> + </property> + <property name="text"> + <string>Forbid flipping</string> + </property> + </widget> + </item> + <item> + <widget class="QListWidget" name="listWidgetMainPath"> + <property name="dragDropMode"> + <enum>QAbstractItemView::InternalMove</enum> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="helpLabel"> + <property name="text"> + <string>Ready!</string> + </property> + <property name="textFormat"> + <enum>Qt::RichText</enum> + </property> + <property name="scaledContents"> + <bool>false</bool> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="tabSeamAllowance"> + <attribute name="title"> + <string>Seam allowance</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_11"> + <item> + <widget class="QCheckBox" name="checkBoxSeams"> + <property name="text"> + <string>Seam allowance</string> + </property> + <property name="checked"> + <bool>false</bool> + </property> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBoxAutomatic"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="title"> + <string>Automatic</string> + </property> + <property name="flat"> + <bool>false</bool> + </property> + <property name="checkable"> + <bool>false</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout_5"> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item alignment="Qt::AlignLeft"> + <widget class="QLabel" name="labelEditWidth"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="palette"> + <palette> + <active> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </active> + <inactive> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </inactive> + <disabled> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>159</red> + <green>158</green> + <blue>158</blue> + </color> + </brush> + </colorrole> + </disabled> + </palette> + </property> + <property name="text"> + <string>Width:</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item alignment="Qt::AlignRight"> + <widget class="QToolButton" name="toolButtonExprWidth"> + <property name="toolTip"> + <string>Formula wizard</string> + </property> + <property name="text"> + <string notr="true">...</string> + </property> + <property name="icon"> + <iconset resource="../../../vmisc/share/resources/icon.qrc"> + <normaloff>:/icon/24x24/fx.png</normaloff>:/icon/24x24/fx.png</iconset> + </property> + <property name="iconSize"> + <size> + <width>24</width> + <height>24</height> + </size> + </property> + </widget> + </item> + <item alignment="Qt::AlignRight"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string/> + </property> + <property name="pixmap"> + <pixmap resource="../../../vmisc/share/resources/icon.qrc">:/icon/24x24/equal.png</pixmap> + </property> + </widget> + </item> + <item alignment="Qt::AlignRight"> + <widget class="QLabel" name="labelResultWidth"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>87</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string>Value</string> + </property> + <property name="text"> + <string notr="true">_</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_6"> + <item> + <widget class="QPlainTextEdit" name="plainTextEditFormulaWidth"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>28</height> + </size> + </property> + <property name="toolTip"> + <string>Calculation</string> + </property> + <property name="tabChangesFocus"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButtonGrowWidth"> + <property name="maximumSize"> + <size> + <width>18</width> + <height>18</height> + </size> + </property> + <property name="sizeIncrement"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string><html><head/><body><p>Show full calculation in message box</p></body></html></string> + </property> + <property name="text"> + <string notr="true"/> + </property> + <property name="icon"> + <iconset theme="go-down"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="iconSize"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Nodes</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_10"> + <item> + <widget class="QLabel" name="labelNode"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Node:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="comboBoxNodes"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_7"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_9"> + <item alignment="Qt::AlignLeft"> + <widget class="QLabel" name="labelEditBefore"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="palette"> + <palette> + <active> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </active> + <inactive> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </inactive> + <disabled> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>159</red> + <green>158</green> + <blue>158</blue> + </color> + </brush> + </colorrole> + </disabled> + </palette> + </property> + <property name="text"> + <string>Before:</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="pushButtonDefBefore"> + <property name="toolTip"> + <string>Return to default width</string> + </property> + <property name="text"> + <string>Default</string> + </property> + </widget> + </item> + <item alignment="Qt::AlignRight"> + <widget class="QToolButton" name="toolButtonExprBefore"> + <property name="toolTip"> + <string>Formula wizard</string> + </property> + <property name="text"> + <string notr="true">...</string> + </property> + <property name="icon"> + <iconset resource="../../../vmisc/share/resources/icon.qrc"> + <normaloff>:/icon/24x24/fx.png</normaloff>:/icon/24x24/fx.png</iconset> + </property> + <property name="iconSize"> + <size> + <width>24</width> + <height>24</height> + </size> + </property> + </widget> + </item> + <item alignment="Qt::AlignRight"> + <widget class="QLabel" name="label_6"> + <property name="text"> + <string/> + </property> + <property name="pixmap"> + <pixmap resource="../../../vmisc/share/resources/icon.qrc">:/icon/24x24/equal.png</pixmap> + </property> + </widget> + </item> + <item alignment="Qt::AlignRight"> + <widget class="QLabel" name="labelResultBefore"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>87</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string>Value</string> + </property> + <property name="text"> + <string notr="true">_</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_7"> + <item> + <widget class="QPlainTextEdit" name="plainTextEditFormulaWidthBefore"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>28</height> + </size> + </property> + <property name="toolTip"> + <string>Calculation</string> + </property> + <property name="tabChangesFocus"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButtonGrowWidthBefore"> + <property name="maximumSize"> + <size> + <width>18</width> + <height>18</height> + </size> + </property> + <property name="sizeIncrement"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string><html><head/><body><p>Show full calculation in message box</p></body></html></string> + </property> + <property name="text"> + <string notr="true"/> + </property> + <property name="icon"> + <iconset theme="go-down"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="iconSize"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_16"> + <item alignment="Qt::AlignLeft"> + <widget class="QLabel" name="labelEditAfter"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="palette"> + <palette> + <active> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </active> + <inactive> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </inactive> + <disabled> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>159</red> + <green>158</green> + <blue>158</blue> + </color> + </brush> + </colorrole> + </disabled> + </palette> + </property> + <property name="text"> + <string>After:</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_6"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="pushButtonDefAfter"> + <property name="toolTip"> + <string>Return to default width</string> + </property> + <property name="text"> + <string>Default</string> + </property> + </widget> + </item> + <item alignment="Qt::AlignRight"> + <widget class="QToolButton" name="toolButtonExprAfter"> + <property name="toolTip"> + <string>Formula wizard</string> + </property> + <property name="text"> + <string notr="true">...</string> + </property> + <property name="icon"> + <iconset resource="../../../vmisc/share/resources/icon.qrc"> + <normaloff>:/icon/24x24/fx.png</normaloff>:/icon/24x24/fx.png</iconset> + </property> + <property name="iconSize"> + <size> + <width>24</width> + <height>24</height> + </size> + </property> + </widget> + </item> + <item alignment="Qt::AlignRight"> + <widget class="QLabel" name="label_10"> + <property name="text"> + <string/> + </property> + <property name="pixmap"> + <pixmap resource="../../../vmisc/share/resources/icon.qrc">:/icon/24x24/equal.png</pixmap> + </property> + </widget> + </item> + <item alignment="Qt::AlignRight"> + <widget class="QLabel" name="labelResultAfter"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>87</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string>Value</string> + </property> + <property name="text"> + <string notr="true">_</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_17"> + <item> + <widget class="QPlainTextEdit" name="plainTextEditFormulaWidthAfter"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>28</height> + </size> + </property> + <property name="toolTip"> + <string>Calculation</string> + </property> + <property name="tabChangesFocus"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButtonGrowWidthAfter"> + <property name="maximumSize"> + <size> + <width>18</width> + <height>18</height> + </size> + </property> + <property name="sizeIncrement"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string><html><head/><body><p>Show full calculation in message box</p></body></html></string> + </property> + <property name="text"> + <string notr="true"/> + </property> + <property name="icon"> + <iconset theme="go-down"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="iconSize"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_15"> + <item> + <widget class="QLabel" name="labelAngle"> + <property name="text"> + <string>Angle:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="comboBoxAngle"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_8"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBoxCustom"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="title"> + <string>Custom</string> + </property> + <property name="flat"> + <bool>false</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <property name="spacing"> + <number>6</number> + </property> + <property name="topMargin"> + <number>9</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QSplitter" name="splitter"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="opaqueResize"> + <bool>true</bool> + </property> + <widget class="QWidget" name="layoutWidget"> + <layout class="QFormLayout" name="formLayout_2"> + <property name="fieldGrowthPolicy"> + <enum>QFormLayout::ExpandingFieldsGrow</enum> + </property> + <property name="horizontalSpacing"> + <number>6</number> + </property> + <item row="0" column="0"> + <widget class="QLabel" name="labelStartPoint"> + <property name="text"> + <string>Start point:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="comboBoxStartPoint"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="labelEndPoint"> + <property name="text"> + <string>End point:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QComboBox" name="comboBoxEndPoint"/> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="labelIncludeType"> + <property name="text"> + <string>Include as:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QComboBox" name="comboBoxIncludeType"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QListWidget" name="listWidgetCustomSA"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="sizeIncrement"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + </widget> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <widget class="QWidget" name="tabInternalPaths"> + <attribute name="title"> + <string>Internal paths</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_6"> + <item> + <widget class="QListWidget" name="listWidgetInternalPaths"> + <property name="dragDropMode"> + <enum>QAbstractItemView::InternalMove</enum> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="tabPatternPieceData"> + <attribute name="title"> + <string>Pattern piece data</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_9"> + <item> + <widget class="QSplitter" name="splitter_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <widget class="QWidget" name="layoutWidget1"> + <layout class="QVBoxLayout" name="verticalLayout_7"> + <item> + <layout class="QFormLayout" name="formLayout_3"> + <property name="fieldGrowthPolicy"> + <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + </property> + <item row="0" column="0"> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string>Letter:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="lineEditLetter"> + <property name="maxLength"> + <number>3</number> + </property> + <property name="placeholderText"> + <string>Letter of pattern piece</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="labelEditName"> + <property name="text"> + <string>Name of detail:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="lineEditName"> + <property name="text"> + <string>Detail</string> + </property> + <property name="maxLength"> + <number>30</number> + </property> + <property name="placeholderText"> + <string>Name can't be empty</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> + <string>Material/Cut number/Placement</string> + </property> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="1" column="0"> + <widget class="QLabel" name="label_8"> + <property name="text"> + <string>Cut number:</string> + </property> + </widget> + </item> + <item row="0" column="0" colspan="2"> + <widget class="QLabel" name="label_7"> + <property name="text"> + <string>Material type:</string> + </property> + </widget> + </item> + <item row="0" column="2" colspan="2"> + <widget class="QComboBox" name="comboBoxMaterial"> + <property name="toolTip"> + <string>You can choose one of the predefined materials or enter a new one</string> + </property> + <property name="editable"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="2" colspan="2"> + <widget class="QSpinBox" name="spinBoxCutNumber"> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>1000</number> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_9"> + <property name="text"> + <string>Placement:</string> + </property> + </widget> + </item> + <item row="2" column="2" colspan="2"> + <widget class="QComboBox" name="comboBoxPlacement"/> + </item> + <item row="3" column="0"> + <widget class="QPushButton" name="pushButtonAdd"> + <property name="text"> + <string>Add</string> + </property> + </widget> + </item> + <item row="3" column="1" colspan="2"> + <widget class="QPushButton" name="pushButtonCancel"> + <property name="text"> + <string>Cancel</string> + </property> + </widget> + </item> + <item row="3" column="3"> + <widget class="QPushButton" name="pushButtonRemove"> + <property name="text"> + <string>Remove</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout_8"> + <item> + <widget class="QCheckBox" name="checkBoxDetail"> + <property name="text"> + <string>Detail label visible</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBoxPattern"> + <property name="text"> + <string>Pattern label visible</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <widget class="QListWidget" name="listWidgetMCP"> + <property name="minimumSize"> + <size> + <width>180</width> + <height>0</height> + </size> + </property> + <property name="focusPolicy"> + <enum>Qt::ClickFocus</enum> + </property> + </widget> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="tabGrainline"> + <attribute name="title"> + <string>Grainline</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_10"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_4"> + <item> + <widget class="QCheckBox" name="checkBoxGrainline"> + <property name="text"> + <string>Grainline visible</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_11"> + <item alignment="Qt::AlignLeft"> + <widget class="QLabel" name="labelEditRot"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="palette"> + <palette> + <active> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </active> + <inactive> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </inactive> + <disabled> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>159</red> + <green>158</green> + <blue>158</blue> + </color> + </brush> + </colorrole> + </disabled> + </palette> + </property> + <property name="text"> + <string>Rotation:</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_4"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item alignment="Qt::AlignRight"> + <widget class="QToolButton" name="pushButtonRot"> + <property name="toolTip"> + <string>Formula wizard</string> + </property> + <property name="text"> + <string notr="true">...</string> + </property> + <property name="icon"> + <iconset resource="../../../vmisc/share/resources/icon.qrc"> + <normaloff>:/icon/24x24/fx.png</normaloff>:/icon/24x24/fx.png</iconset> + </property> + <property name="iconSize"> + <size> + <width>24</width> + <height>24</height> + </size> + </property> + </widget> + </item> + <item alignment="Qt::AlignRight"> + <widget class="QLabel" name="labelEqual"> + <property name="text"> + <string/> + </property> + <property name="pixmap"> + <pixmap resource="../../../vmisc/share/resources/icon.qrc">:/icon/24x24/equal.png</pixmap> + </property> + </widget> + </item> + <item alignment="Qt::AlignRight"> + <widget class="QLabel" name="labelRot"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>87</width> + <height>0</height> + </size> + </property> + <property name="baseSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string>Value</string> + </property> + <property name="text"> + <string notr="true">_</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_12"> + <item> + <widget class="QPlainTextEdit" name="lineEditRotFormula"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>28</height> + </size> + </property> + <property name="toolTip"> + <string>Calculation</string> + </property> + <property name="tabChangesFocus"> + <bool>true</bool> + </property> + <property name="plainText"> + <string notr="true"/> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButtonShowRot"> + <property name="maximumSize"> + <size> + <width>18</width> + <height>18</height> + </size> + </property> + <property name="sizeIncrement"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string><html><head/><body><p>Show full calculation in message box</p></body></html></string> + </property> + <property name="text"> + <string notr="true"/> + </property> + <property name="icon"> + <iconset theme="go-down"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="iconSize"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_13"> + <item alignment="Qt::AlignLeft"> + <widget class="QLabel" name="labelEditLen"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="palette"> + <palette> + <active> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </active> + <inactive> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </inactive> + <disabled> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>159</red> + <green>158</green> + <blue>158</blue> + </color> + </brush> + </colorrole> + </disabled> + </palette> + </property> + <property name="text"> + <string>Length:</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_5"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item alignment="Qt::AlignRight"> + <widget class="QToolButton" name="pushButtonLen"> + <property name="toolTip"> + <string>Formula wizard</string> + </property> + <property name="text"> + <string notr="true">...</string> + </property> + <property name="icon"> + <iconset resource="../../../vmisc/share/resources/icon.qrc"> + <normaloff>:/icon/24x24/fx.png</normaloff>:/icon/24x24/fx.png</iconset> + </property> + <property name="iconSize"> + <size> + <width>24</width> + <height>24</height> + </size> + </property> + </widget> + </item> + <item alignment="Qt::AlignRight"> + <widget class="QLabel" name="labelEqual_2"> + <property name="text"> + <string/> + </property> + <property name="pixmap"> + <pixmap resource="../../../vmisc/share/resources/icon.qrc">:/icon/24x24/equal.png</pixmap> + </property> + </widget> + </item> + <item alignment="Qt::AlignRight"> + <widget class="QLabel" name="labelLen"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>87</width> + <height>0</height> + </size> + </property> + <property name="baseSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string>Value</string> + </property> + <property name="text"> + <string notr="true">_</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_14"> + <item> + <widget class="QPlainTextEdit" name="lineEditLenFormula"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>28</height> + </size> + </property> + <property name="toolTip"> + <string>Calculation</string> + </property> + <property name="tabChangesFocus"> + <bool>true</bool> + </property> + <property name="plainText"> + <string notr="true"/> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButtonShowLen"> + <property name="maximumSize"> + <size> + <width>18</width> + <height>18</height> + </size> + </property> + <property name="sizeIncrement"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string><html><head/><body><p>Show full calculation in message box</p></body></html></string> + </property> + <property name="text"> + <string notr="true"/> + </property> + <property name="icon"> + <iconset theme="go-down"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="iconSize"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_5"> + <item> + <widget class="QLabel" name="labelEditLen_2"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="palette"> + <palette> + <active> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </active> + <inactive> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </inactive> + <disabled> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>159</red> + <green>158</green> + <blue>158</blue> + </color> + </brush> + </colorrole> + </disabled> + </palette> + </property> + <property name="text"> + <string>Arrows:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="comboBoxArrow"/> + </item> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </widget> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources> + <include location="../../../vmisc/share/resources/icon.qrc"/> + </resources> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>DialogSeamAllowance</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>DialogSeamAllowance</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/libs/vtools/dialogs/tools/dialogtool.cpp b/src/libs/vtools/dialogs/tools/dialogtool.cpp index 8dedd4752..b0d71b549 100644 --- a/src/libs/vtools/dialogs/tools/dialogtool.cpp +++ b/src/libs/vtools/dialogs/tools/dialogtool.cpp @@ -58,6 +58,7 @@ #include <Qt> #include <QtDebug> #include <new> +#include <QBuffer> #include "../ifc/xml/vdomdocument.h" #include "../qmuparser/qmudef.h" @@ -66,6 +67,7 @@ #include "../vpatterndb/calculator.h" #include "../vpatterndb/vcontainer.h" #include "../vpatterndb/vtranslatevars.h" +#include "../vpatterndb/vpiecenode.h" #include "../../tools/vabstracttool.h" #include "../ifc/xml/vabstractpattern.h" #include "../vgeometry/vabstractcurve.h" @@ -395,6 +397,128 @@ quint32 DialogTool::DNumber(const QString &baseName) const return num; } +//--------------------------------------------------------------------------------------------------------------------- +quint32 DialogTool::RowId(QListWidget *listWidget, int i) +{ + SCASSERT(listWidget != nullptr); + const QListWidgetItem *rowItem = listWidget->item(i); + SCASSERT(rowItem != nullptr); + const VPieceNode rowNode = qvariant_cast<VPieceNode>(rowItem->data(Qt::UserRole)); + return rowNode.GetId(); +} + +//--------------------------------------------------------------------------------------------------------------------- +bool DialogTool::FirstPointEqualLast(QListWidget *listWidget) +{ + SCASSERT(listWidget != nullptr); + if (listWidget->count() > 1) + { + return RowId(listWidget, 0) == RowId(listWidget, listWidget->count()-1); + } + return false; +} + +//--------------------------------------------------------------------------------------------------------------------- +bool DialogTool::DoublePoints(QListWidget *listWidget) +{ + SCASSERT(listWidget != nullptr); + for (int i=0, sz = listWidget->count()-1; i<sz; ++i) + { + if (RowId(listWidget, i) == RowId(listWidget, i+1)) + { + return true; + } + } + return false; +} + +//--------------------------------------------------------------------------------------------------------------------- +QString DialogTool::DialogWarningIcon() +{ + const QIcon icon = QIcon::fromTheme("dialog-warning", + QIcon(":/icons/win.icon.theme/16x16/status/dialog-warning.png")); + + const QPixmap pixmap = icon.pixmap(QSize(16, 16)); + QByteArray byteArray; + QBuffer buffer(&byteArray); + pixmap.save(&buffer, "PNG"); + const QString url = QString("<img src=\"data:image/png;base64,") + byteArray.toBase64() + QLatin1String("\"/> "); + return url; +} + +//--------------------------------------------------------------------------------------------------------------------- +QString DialogTool::GetNodeName(const VPieceNode &node) const +{ + const QSharedPointer<VGObject> obj = data->GeometricObject<VGObject>(node.GetId()); + QString name = obj->name(); + + if (node.GetTypeTool() != Tool::NodePoint && node.GetReverse()) + { + name = QLatin1String("- ") + name; + } + + return name; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogTool::NewNodeItem(QListWidget *listWidget, const VPieceNode &node) +{ + SCASSERT(listWidget != nullptr); + SCASSERT(node.GetId() > NULL_ID); + QString name; + switch (node.GetTypeTool()) + { + case (Tool::NodePoint): + case (Tool::NodeArc): + case (Tool::NodeSpline): + case (Tool::NodeSplinePath): + { + name = GetNodeName(node); + break; + } + default: + qDebug()<<"Got wrong tools. Ignore."; + return; + } + + bool canAddNewPoint = false; + + if(listWidget->count() == 0) + { + canAddNewPoint = true; + } + else + { + if(RowId(listWidget, listWidget->count()-1) != node.GetId()) + { + canAddNewPoint = true; + } + } + + if(canAddNewPoint) + { + QListWidgetItem *item = new QListWidgetItem(name); + item->setFont(QFont("Times", 12, QFont::Bold)); + item->setData(Qt::UserRole, QVariant::fromValue(node)); + listWidget->addItem(item); + listWidget->setCurrentRow(listWidget->count()-1); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogTool::InitNodeAngles(QComboBox *box) +{ + SCASSERT(box != nullptr); + box->clear(); + + box->addItem(tr("by length"), static_cast<unsigned char>(PieceNodeAngle::ByLength)); + box->addItem(tr("by points intersetions"), static_cast<unsigned char>(PieceNodeAngle::ByPointsIntersection)); + box->addItem(tr("by first edge symmetry"), static_cast<unsigned char>(PieceNodeAngle::ByFirstEdgeSymmetry)); + box->addItem(tr("by second edge symmetry"), static_cast<unsigned char>(PieceNodeAngle::BySecondEdgeSymmetry)); + box->addItem(tr("by first edge right angle"), static_cast<unsigned char>(PieceNodeAngle::ByFirstEdgeRightAngle)); + box->addItem(tr("by second edge right angle"), static_cast<unsigned char>(PieceNodeAngle::BySecondEdgeRightAngle)); +} + //--------------------------------------------------------------------------------------------------------------------- bool DialogTool::IsSplinePath(const QSharedPointer<VGObject> &obj) const { @@ -458,7 +582,7 @@ void DialogTool::ValFormulaChanged(bool &flag, QPlainTextEdit *edit, QTimer *tim return; } timer->setSingleShot(true); - timer->start(1000); + timer->start(300); } //--------------------------------------------------------------------------------------------------------------------- @@ -470,13 +594,11 @@ void DialogTool::ValFormulaChanged(bool &flag, QPlainTextEdit *edit, QTimer *tim * @param postfix unit name * @param checkZero true - if formula can't be equal zero */ -qreal DialogTool::Eval(const QString &text, bool &flag, QLabel *label, const QString& postfix, bool checkZero) +qreal DialogTool::Eval(const QString &text, bool &flag, QLabel *label, const QString& postfix, bool checkZero, + bool checkLessThanZero) { - qDebug() << "Eval started"; SCASSERT(label != nullptr) - qDebug() << "Label ok"; SCASSERT(labelEditFormula != nullptr) - qDebug() << "lef ok"; qreal result = INT_MIN;//Value can be 0, so use max imposible value @@ -516,6 +638,13 @@ qreal DialogTool::Eval(const QString &text, bool &flag, QLabel *label, const QSt label->setText(tr("Error") + " (" + postfix + ")"); label->setToolTip(tr("Value can't be 0")); } + else if (checkLessThanZero && result < 0) + { + flag = false; + ChangeColor(labelEditFormula, Qt::red); + label->setText(tr("Error") + " (" + postfix + ")"); + label->setToolTip(tr("Value can't be lass than 0")); + } else { label->setText(qApp->LocaleToString(result) + " " +postfix); @@ -966,6 +1095,12 @@ void DialogTool::Build(const Tool &type) Q_UNUSED(type) } +//--------------------------------------------------------------------------------------------------------------------- +void DialogTool::SetPiecesList(const QVector<quint32> &list) +{ + Q_UNUSED(list); +} + //--------------------------------------------------------------------------------------------------------------------- void DialogTool::SetAssociatedTool(VAbstractTool *tool) { diff --git a/src/libs/vtools/dialogs/tools/dialogtool.h b/src/libs/vtools/dialogs/tools/dialogtool.h index 81ac40462..460a28d18 100644 --- a/src/libs/vtools/dialogs/tools/dialogtool.h +++ b/src/libs/vtools/dialogs/tools/dialogtool.h @@ -95,6 +95,7 @@ public: virtual void ShowDialog(bool click); virtual void Build(const Tool &type); + virtual void SetPiecesList(const QVector<quint32> &list); quint32 GetToolId() const; void SetToolId(const quint32 &value); @@ -230,7 +231,7 @@ protected: void ValFormulaChanged(bool &flag, QPlainTextEdit *edit, QTimer * timer, const QString &postfix = QString()); qreal Eval(const QString &text, bool &flag, QLabel *label, const QString &postfix, - bool checkZero = true); + bool checkZero = true, bool checkLessThanZero = false); void setCurrentPointId(QComboBox *box, const quint32 &value, FillComboBox rule = FillComboBox::NoChildren, @@ -274,6 +275,16 @@ protected: void MoveCursorToEnd(QPlainTextEdit *plainTextEdit); virtual bool eventFilter(QObject *object, QEvent *event) Q_DECL_OVERRIDE; quint32 DNumber(const QString &baseName) const; + + static quint32 RowId(QListWidget *listWidget, int i); + static bool FirstPointEqualLast(QListWidget *listWidget); + static bool DoublePoints(QListWidget *listWidget); + static QString DialogWarningIcon(); + + QString GetNodeName(const VPieceNode &node) const; + void NewNodeItem(QListWidget *listWidget, const VPieceNode &node); + + void InitNodeAngles(QComboBox *box); private: void FillList(QComboBox *box, const QMap<QString, quint32> &list)const; diff --git a/src/libs/vtools/dialogs/tools/dialoguniondetails.cpp b/src/libs/vtools/dialogs/tools/dialoguniondetails.cpp index 0078616b1..8c54a9dee 100644 --- a/src/libs/vtools/dialogs/tools/dialoguniondetails.cpp +++ b/src/libs/vtools/dialogs/tools/dialoguniondetails.cpp @@ -33,7 +33,8 @@ #include "../ifc/ifcdef.h" #include "../vpatterndb/vcontainer.h" -#include "../vpatterndb/vdetail.h" +#include "../vpatterndb/vpiece.h" +#include "../vpatterndb/vpiecenode.h" #include "dialogtool.h" #include "ui_dialoguniondetails.h" @@ -96,8 +97,8 @@ bool DialogUnionDetails::CheckObject(const quint32 &id, const quint32 &idDetail) { return false; } - const VDetail det = data->GetDetail(idDetail); - return det.Containes(id); + const VPiece det = data->GetPiece(idDetail); + return det.GetPath().Contains(id); } //--------------------------------------------------------------------------------------------------------------------- @@ -107,8 +108,8 @@ bool DialogUnionDetails::CheckDetail(const quint32 &idDetail) const { return false; } - const VDetail det = data->GetDetail(idDetail); - if (det.CountNode() >= 3 && det.listNodePoint().size() >= 2) + const VPiece det = data->GetPiece(idDetail); + if (det.GetPath().CountNodes() >= 3 && det.GetPath().ListNodePoint().size() >= 2) { return true; } @@ -166,11 +167,11 @@ void DialogUnionDetails::ChoosedDetail(const quint32 &id, const SceneObject &typ emit ToolTip(tr("Select a unique point")); return; } - VDetail d = data->GetDetail(idDetail); - if (d.OnEdge(p1, id)) + VPiece d = data->GetPiece(idDetail); + if (d.GetPath().OnEdge(p1, id)) { p2 = id; - index = d.Edge(p1, p2); + index = d.GetPath().Edge(p1, p2); ++numberD; if (numberD > 1) { diff --git a/src/libs/vtools/tools/drawTools/vdrawtool.cpp b/src/libs/vtools/tools/drawTools/vdrawtool.cpp index 4de01fb70..db85d3d0a 100644 --- a/src/libs/vtools/tools/drawTools/vdrawtool.cpp +++ b/src/libs/vtools/tools/drawTools/vdrawtool.cpp @@ -28,7 +28,6 @@ #include "vdrawtool.h" -#include <qnumeric.h> #include <QDialog> #include <QDomNode> #include <QMessageLogger> @@ -41,10 +40,6 @@ #include "../ifc/ifcdef.h" #include "../ifc/xml/vdomdocument.h" #include "../ifc/xml/vabstractpattern.h" -#include "../ifc/exception/vexceptionundo.h" -#include "../vpatterndb/calculator.h" -#include "../../dialogs/support/dialogeditwrongformula.h" -#include "../../dialogs/support/dialogundo.h" #include "../../undocommands/addtocalc.h" #include "../../undocommands/savetooloptions.h" #include "../qmuparser/qmuparsererror.h" @@ -292,96 +287,6 @@ void VDrawTool::DetailsMode(bool mode) // Do nothing. } -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief CheckFormula check formula. - * - * Try calculate formula. If find error show dialog that allow user try fix formula. If user can't throw exception. In - * successes case return result calculation and fixed formula string. If formula ok don't touch formula. - * - * @param toolId [in] tool's id. - * @param formula [in|out] string with formula. - * @param data [in] container with variables. Need for math parser. - * @throw QmuParserError. - * @return result of calculation formula. - */ -qreal VDrawTool::CheckFormula(const quint32 &toolId, QString &formula, VContainer *data) -{ - SCASSERT(data != nullptr) - qreal result = 0; - try - { - QScopedPointer<Calculator> cal(new Calculator()); - result = cal->EvalFormula(data->PlainVariables(), formula); - - if (qIsInf(result) || qIsNaN(result)) - { - qDebug() << "Invalid the formula value"; - return 0; - } - } - catch (qmu::QmuParserError &e) - { - qDebug() << "\nMath parser error:\n" - << "--------------------------------------\n" - << "Message: " << e.GetMsg() << "\n" - << "Expression: " << e.GetExpr() << "\n" - << "--------------------------------------"; - - if (qApp->IsAppInGUIMode()) - { - QScopedPointer<DialogUndo> dialogUndo(new DialogUndo(qApp->getMainWindow())); - forever - { - if (dialogUndo->exec() == QDialog::Accepted) - { - const UndoButton resultUndo = dialogUndo->Result(); - if (resultUndo == UndoButton::Fix) - { - auto *dialog = new DialogEditWrongFormula(data, toolId, qApp->getMainWindow()); - dialog->setWindowTitle(tr("Edit wrong formula")); - dialog->SetFormula(formula); - if (dialog->exec() == QDialog::Accepted) - { - formula = dialog->GetFormula(); - /* Need delete dialog here because parser in dialog don't allow use correct separator for - * parsing here. */ - delete dialog; - QScopedPointer<Calculator> cal1(new Calculator()); - result = cal1->EvalFormula(data->PlainVariables(), formula); - - if (qIsInf(result) || qIsNaN(result)) - { - qDebug() << "Invalid the formula value"; - return 0; - } - - break; - } - else - { - delete dialog; - } - } - else - { - throw VExceptionUndo(QString("Undo wrong formula %1").arg(formula)); - } - } - else - { - throw; - } - } - } - else - { - throw; - } - } - return result; -} - //--------------------------------------------------------------------------------------------------------------------- /** * @brief AddToCalculation add tool to calculation tag in pattern file. diff --git a/src/libs/vtools/tools/drawTools/vdrawtool.h b/src/libs/vtools/tools/drawTools/vdrawtool.h index cbb1281aa..105e212e6 100644 --- a/src/libs/vtools/tools/drawTools/vdrawtool.h +++ b/src/libs/vtools/tools/drawTools/vdrawtool.h @@ -75,7 +75,6 @@ public: /** @brief setDialog set dialog when user want change tool option. */ virtual void setDialog() {} virtual void DialogLinkDestroy(); - static qreal CheckFormula(const quint32 &toolId, QString &formula, VContainer *data); QString getLineType() const; virtual void SetTypeLine(const QString &value); diff --git a/src/libs/vtools/tools/nodeDetails/nodedetails.h b/src/libs/vtools/tools/nodeDetails/nodedetails.h index 8f9321212..918551ec5 100644 --- a/src/libs/vtools/tools/nodeDetails/nodedetails.h +++ b/src/libs/vtools/tools/nodeDetails/nodedetails.h @@ -34,5 +34,6 @@ #include "vnodepoint.h" #include "vnodespline.h" #include "vnodesplinepath.h" +#include "vtoolpiecepath.h" #endif // NODEDETAILS_H diff --git a/src/libs/vtools/tools/nodeDetails/vabstractnode.cpp b/src/libs/vtools/tools/nodeDetails/vabstractnode.cpp index 381509163..a8e2f433c 100644 --- a/src/libs/vtools/tools/nodeDetails/vabstractnode.cpp +++ b/src/libs/vtools/tools/nodeDetails/vabstractnode.cpp @@ -75,7 +75,7 @@ void VAbstractNode::ShowVisualization(bool show) //--------------------------------------------------------------------------------------------------------------------- void VAbstractNode::incrementReferens() { - ++_referens; + VAbstractTool::incrementReferens(); if (_referens == 1) { if (idTool != NULL_ID) @@ -102,10 +102,7 @@ void VAbstractNode::incrementReferens() */ void VAbstractNode::decrementReferens() { - if (_referens > 0) - { - --_referens; - } + VAbstractTool::decrementReferens(); if (_referens == 0) { if (idTool != NULL_ID) diff --git a/src/libs/vtools/tools/nodeDetails/vtoolpiecepath.cpp b/src/libs/vtools/tools/nodeDetails/vtoolpiecepath.cpp new file mode 100644 index 000000000..0a3cb028c --- /dev/null +++ b/src/libs/vtools/tools/nodeDetails/vtoolpiecepath.cpp @@ -0,0 +1,325 @@ +/************************************************************************ + ** + ** @file + ** @author Roman Telezhynskyi <dismine(at)gmail.com> + ** @date 24 11, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2016 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#include "vtoolpiecepath.h" +#include "../../dialogs/tools/dialogpiecepath.h" +#include "../vpatterndb/vpiecepath.h" +#include "../vpatterndb/vpiecenode.h" +#include "../../undocommands/savepieceoptions.h" +#include "../vtoolseamallowance.h" + +//--------------------------------------------------------------------------------------------------------------------- +VToolPiecePath *VToolPiecePath::Create(DialogTool *dialog, VMainGraphicsScene *scene, VAbstractPattern *doc, + VContainer *data) +{ + SCASSERT(dialog != nullptr); + DialogPiecePath *dialogTool = qobject_cast<DialogPiecePath*>(dialog); + SCASSERT(dialogTool != nullptr); + VPiecePath path = dialogTool->GetPiecePath(); + const quint32 pieceId = dialogTool->GetPieceId(); + qApp->getUndoStack()->beginMacro("add path"); + path.SetNodes(PrepareNodes(path, scene, doc, data)); + + VToolPiecePath *pathTool = Create(0, path, pieceId, scene, doc, data, Document::FullParse, Source::FromGui); + return pathTool; +} + +//--------------------------------------------------------------------------------------------------------------------- +VToolPiecePath *VToolPiecePath::Create(quint32 _id, const VPiecePath &path, quint32 pieceId, VMainGraphicsScene *scene, + VAbstractPattern *doc, VContainer *data, const Document &parse, + const Source &typeCreation, const QString &drawName, const quint32 &idTool) +{ + quint32 id = _id; + if (typeCreation == Source::FromGui) + { + id = data->AddPiecePath(path); + } + else + { + data->UpdatePiecePath(id, path); + if (parse != Document::FullParse) + { + doc->UpdateToolData(id, data); + } + } + + VAbstractTool::AddRecord(id, Tool::PiecePath, doc); + if (parse == Document::FullParse) + { + //TODO Need create garbage collector and remove all nodes, that we don't use. + //Better check garbage before each saving file. Check only modeling tags. + VToolPiecePath *pathTool = new VToolPiecePath(doc, data, id, pieceId, typeCreation, drawName, idTool, doc); + + doc->AddTool(id, pathTool); + if (idTool != NULL_ID) + { + //Some nodes we don't show on scene. Tool that create this nodes must free memory. + VDataTool *tool = doc->getTool(idTool); + SCASSERT(tool != nullptr); + pathTool->setParent(tool);// Adopted by a tool + } + else + { + if (typeCreation == Source::FromGui && path.GetType() == PiecePathType::InternalPath) + { // Seam allowance tool already initializated and can't init the path + SCASSERT(pieceId > NULL_ID); + VToolSeamAllowance *saTool = qobject_cast<VToolSeamAllowance*>(doc->getTool(pieceId)); + SCASSERT(saTool != nullptr); + pathTool->setParentItem(saTool); + pathTool->SetParentType(ParentType::Item); + } + else + { + // Try to prevent memory leak + scene->addItem(pathTool);// First adopted by scene + pathTool->hide();// If no one will use node, it will stay hidden + pathTool->SetParentType(ParentType::Scene); + } + } + return pathTool; + } + return nullptr; +} + +//--------------------------------------------------------------------------------------------------------------------- +QString VToolPiecePath::getTagName() const +{ + return VAbstractPattern::TagPath; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolPiecePath::incrementReferens() +{ + VAbstractTool::incrementReferens(); + if (_referens == 1) + { + if (idTool != NULL_ID) + { + doc->IncrementReferens(idTool); + } + else + { + IncrementNodes(VAbstractTool::data.GetPiecePath(id)); + } + ShowNode(); + QDomElement domElement = doc->elementById(id); + if (domElement.isElement()) + { + doc->SetParametrUsage(domElement, AttrInUse, NodeUsage::InUse); + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolPiecePath::decrementReferens() +{ + VAbstractTool::decrementReferens(); + if (_referens == 0) + { + if (idTool != NULL_ID) + { + doc->DecrementReferens(idTool); + } + else + { + DecrementNodes(VAbstractTool::data.GetPiecePath(id)); + } + HideNode(); + QDomElement domElement = doc->elementById(id); + if (domElement.isElement()) + { + doc->SetParametrUsage(domElement, AttrInUse, NodeUsage::NotInUse); + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolPiecePath::AddAttributes(VAbstractPattern *doc, QDomElement &domElement, quint32 id, const VPiecePath &path) +{ + doc->SetAttribute(domElement, VDomDocument::AttrId, id); + doc->SetAttribute(domElement, AttrName, path.GetName()); + doc->SetAttribute(domElement, AttrType, static_cast<int>(path.GetType())); + doc->SetAttribute(domElement, AttrTypeLine, PenStyleToLineStyle(path.GetPenType())); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolPiecePath::FullUpdateFromFile() +{ + RefreshGeometry(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolPiecePath::AllowHover(bool enabled) +{ + Q_UNUSED(enabled) + // do nothing +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolPiecePath::AllowSelecting(bool enabled) +{ + Q_UNUSED(enabled) + // do nothing +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolPiecePath::AddToFile() +{ + QDomElement domElement = doc->createElement(getTagName()); + const VPiecePath path = VAbstractTool::data.GetPiecePath(id); + + AddAttributes(doc, domElement, id, path); + + if (idTool != NULL_ID) + { + doc->SetAttribute(domElement, AttrIdTool, idTool); + } + + AddNodes(doc, domElement, path); + + AddToModeling(domElement); + + if (m_pieceId > NULL_ID) + { + const VPiece oldDet = VAbstractTool::data.GetPiece(m_pieceId); + VPiece newDet = oldDet; + + if (path.GetType() == PiecePathType::InternalPath) + { + QVector<quint32> iPaths = newDet.GetInternalPaths(); + iPaths.append(id); + newDet.SetInternalPaths(iPaths); + } + else if (path.GetType() == PiecePathType::CustomSeamAllowance) + { + CustomSARecord record; + record.path = id; + + QVector<CustomSARecord> records = newDet.GetCustomSARecords(); + records.append(record); + newDet.SetCustomSARecords(records); + } + + SavePieceOptions *saveCommand = new SavePieceOptions(oldDet, newDet, doc, m_pieceId); + qApp->getUndoStack()->push(saveCommand);// First push then make a connect + VAbstractTool::data.UpdatePiece(m_pieceId, newDet);// Update piece because first save will not call lite update + connect(saveCommand, &SavePieceOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolPiecePath::RefreshDataInFile() +{ + QDomElement domElement = doc->elementById(id); + if (domElement.isElement()) + { + if (idTool != NULL_ID) + { + doc->SetAttribute(domElement, AttrIdTool, idTool); + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolPiecePath::ShowNode() +{ + if (parentType != ParentType::Scene) + { + show(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolPiecePath::HideNode() +{ + hide(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolPiecePath::ToolCreation(const Source &typeCreation) +{ + if (typeCreation == Source::FromGui || typeCreation == Source::FromTool) + { + AddToFile(); + if (typeCreation != Source::FromTool) + { + qApp->getUndoStack()->endMacro(); + } + } + else + { + RefreshDataInFile(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +VToolPiecePath::VToolPiecePath(VAbstractPattern *doc, VContainer *data, quint32 id, quint32 pieceId, + const Source &typeCreation, const QString &drawName, const quint32 &idTool, + QObject *qoParent, QGraphicsItem *parent) + :VAbstractNode(doc, data, id, 0, drawName, idTool, qoParent), + QGraphicsPathItem(parent), + m_pieceId(pieceId) +{ + IncrementNodes(VAbstractTool::data.GetPiecePath(id)); + RefreshGeometry(); + ToolCreation(typeCreation); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolPiecePath::RefreshGeometry() +{ + const VPiecePath path = VAbstractTool::data.GetPiecePath(id); + if (path.GetType() == PiecePathType::InternalPath) + { + QPainterPath p = path.PainterPath(this->getData()); + p.setFillRule(Qt::OddEvenFill); + + this->setPath(p); + QPen pen = this->pen(); + pen.setStyle(path.GetPenType()); + this->setPen(pen); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolPiecePath::IncrementNodes(const VPiecePath &path) const +{ + for (int i = 0; i < path.CountNodes(); ++i) + { + doc->IncrementReferens(VAbstractTool::data.GetGObject(path.at(i).GetId())->getIdTool()); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolPiecePath::DecrementNodes(const VPiecePath &path) const +{ + for (int i = 0; i < path.CountNodes(); ++i) + { + doc->DecrementReferens(VAbstractTool::data.GetGObject(path.at(i).GetId())->getIdTool()); + } +} diff --git a/src/libs/vtools/tools/nodeDetails/vtoolpiecepath.h b/src/libs/vtools/tools/nodeDetails/vtoolpiecepath.h new file mode 100644 index 000000000..2b1f4fca8 --- /dev/null +++ b/src/libs/vtools/tools/nodeDetails/vtoolpiecepath.h @@ -0,0 +1,82 @@ +/************************************************************************ + ** + ** @file + ** @author Roman Telezhynskyi <dismine(at)gmail.com> + ** @date 24 11, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2016 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#ifndef VTOOLPIECEPATH_H +#define VTOOLPIECEPATH_H + +#include <QtGlobal> + +#include "vabstractnode.h" + +class DialogTool; + +class VToolPiecePath : public VAbstractNode, public QGraphicsPathItem +{ + Q_OBJECT +public: + static VToolPiecePath* Create(DialogTool *dialog, VMainGraphicsScene *scene, VAbstractPattern *doc, + VContainer *data); + static VToolPiecePath *Create(quint32 _id, const VPiecePath &path, quint32 pieceId, VMainGraphicsScene *scene, + VAbstractPattern *doc, VContainer *data, const Document &parse, + const Source &typeCreation, const QString &drawName = QString(), + const quint32 &idTool = 0); + + virtual int type() const Q_DECL_OVERRIDE {return Type;} + enum { Type = UserType + static_cast<int>(Tool::PiecePath)}; + virtual QString getTagName() const Q_DECL_OVERRIDE; + + virtual void incrementReferens() Q_DECL_OVERRIDE; + virtual void decrementReferens() Q_DECL_OVERRIDE; + + static void AddAttributes(VAbstractPattern *doc, QDomElement &domElement, quint32 id, const VPiecePath &path); +public slots: + virtual void FullUpdateFromFile () Q_DECL_OVERRIDE; + virtual void AllowHover(bool enabled) Q_DECL_OVERRIDE; + virtual void AllowSelecting(bool enabled) Q_DECL_OVERRIDE; +protected: + virtual void AddToFile() Q_DECL_OVERRIDE; + virtual void RefreshDataInFile() Q_DECL_OVERRIDE; + virtual void ShowNode() Q_DECL_OVERRIDE; + virtual void HideNode() Q_DECL_OVERRIDE; + virtual void ToolCreation(const Source &typeCreation) Q_DECL_OVERRIDE; +private: + Q_DISABLE_COPY(VToolPiecePath) + + quint32 m_pieceId; + + VToolPiecePath(VAbstractPattern *doc, VContainer *data, quint32 id, quint32 pieceId, const Source &typeCreation, + const QString &drawName = QString(), const quint32 &idTool = 0, QObject *qoParent = nullptr, + QGraphicsItem * parent = nullptr ); + + void RefreshGeometry(); + + void IncrementNodes(const VPiecePath &path) const; + void DecrementNodes(const VPiecePath &path) const; +}; + +#endif // VTOOLPIECEPATH_H diff --git a/src/libs/vtools/tools/tools.pri b/src/libs/vtools/tools/tools.pri index b1a63e83b..2b755c117 100644 --- a/src/libs/vtools/tools/tools.pri +++ b/src/libs/vtools/tools/tools.pri @@ -2,7 +2,6 @@ # This need for corect working file translations.pro HEADERS += \ - $$PWD/vtooldetail.h \ $$PWD/vdatatool.h \ $$PWD/vabstracttool.h \ $$PWD/tools.h \ @@ -51,18 +50,17 @@ HEADERS += \ $$PWD/drawTools/toolcurve/vtoolcubicbezier.h \ $$PWD/drawTools/toolcurve/vtoolcubicbezierpath.h \ $$PWD/drawTools/operation/vtoolrotation.h \ - $$PWD/vtextgraphicsitem.h \ - $$PWD/vgrainlineitem.h \ $$PWD/drawTools/operation/flipping/vtoolflippingbyline.h \ $$PWD/drawTools/operation/vabstractoperation.h \ $$PWD/drawTools/operation/flipping/vtoolflippingbyaxis.h \ $$PWD/drawTools/operation/flipping/vabstractflipping.h \ $$PWD/drawTools/operation/vtoolmove.h \ $$PWD/drawTools/toolcurve/vtoolellipticalarc.h \ - $$PWD/nodeDetails/vnodeellipticalarc.h + $$PWD/nodeDetails/vnodeellipticalarc.h \ + $$PWD/vtoolseamallowance.h \ + $$PWD/nodeDetails/vtoolpiecepath.h SOURCES += \ - $$PWD/vtooldetail.cpp \ $$PWD/vdatatool.cpp \ $$PWD/vabstracttool.cpp \ $$PWD/drawTools/toolpoint/toolsinglepoint/vtooltriangle.cpp \ @@ -108,12 +106,12 @@ SOURCES += \ $$PWD/drawTools/toolcurve/vtoolcubicbezier.cpp \ $$PWD/drawTools/toolcurve/vtoolcubicbezierpath.cpp \ $$PWD/drawTools/operation/vtoolrotation.cpp \ - $$PWD/vtextgraphicsitem.cpp \ - $$PWD/vgrainlineitem.cpp \ $$PWD/drawTools/operation/flipping/vtoolflippingbyline.cpp \ $$PWD/drawTools/operation/vabstractoperation.cpp \ $$PWD/drawTools/operation/flipping/vtoolflippingbyaxis.cpp \ $$PWD/drawTools/operation/flipping/vabstractflipping.cpp \ $$PWD/drawTools/operation/vtoolmove.cpp \ $$PWD/drawTools/toolcurve/vtoolellipticalarc.cpp \ - $$PWD/nodeDetails/vnodeellipticalarc.cpp + $$PWD/nodeDetails/vnodeellipticalarc.cpp \ + $$PWD/vtoolseamallowance.cpp \ + $$PWD/nodeDetails/vtoolpiecepath.cpp diff --git a/src/libs/vtools/tools/vabstracttool.cpp b/src/libs/vtools/tools/vabstracttool.cpp index f15c3232b..7cd873b5f 100644 --- a/src/libs/vtools/tools/vabstracttool.cpp +++ b/src/libs/vtools/tools/vabstracttool.cpp @@ -52,21 +52,32 @@ #include <QUndoStack> #include <QVector> #include <new> +#include <qnumeric.h> #include "../vgeometry/vpointf.h" #include "../vpropertyexplorer/checkablemessagebox.h" #include "../vwidgets/vmaingraphicsview.h" #include "../ifc/exception/vexception.h" +#include "../ifc/exception/vexceptionundo.h" #include "../ifc/xml/vtoolrecord.h" #include "../undocommands/deltool.h" #include "../vgeometry/../ifc/ifcdef.h" #include "../vgeometry/vgeometrydef.h" #include "../vgeometry/vgobject.h" +#include "../vgeometry/vcubicbezier.h" +#include "../vgeometry/vcubicbezierpath.h" +#include "../vgeometry/vsplinepath.h" +#include "../vgeometry/varc.h" +#include "../vgeometry/vellipticalarc.h" #include "../vmisc/vcommonsettings.h" #include "../vmisc/logging.h" #include "../vpatterndb/vcontainer.h" +#include "../vpatterndb/vpiecenode.h" +#include "../vpatterndb/calculator.h" #include "../vwidgets/vgraphicssimpletextitem.h" -#include "vdatatool.h" +#include "nodeDetails/nodedetails.h" +#include "../dialogs/support/dialogundo.h" +#include "../dialogs/support/dialogeditwrongformula.h" class QGraphicsEllipseItem; class QGraphicsLineItem; @@ -74,6 +85,51 @@ template <class T> class QSharedPointer; const QString VAbstractTool::AttrInUse = QStringLiteral("inUse"); +namespace +{ +//--------------------------------------------------------------------------------------------------------------------- +template<typename T> +/** + * @brief CreateNode create new node for detail. + * @param data container. + * @param id id parent object. + * @return id for new object. + */ +quint32 CreateNode(VContainer *data, quint32 id) +{ + //We can't use exist object. Need create new. + T *node = new T(*data->GeometricObject<T>(id).data()); + node->setMode(Draw::Modeling); + return data->AddGObject(node); +} + +//--------------------------------------------------------------------------------------------------------------------- +quint32 CreateNodeSpline(VContainer *data, quint32 id) +{ + if (data->GetGObject(id)->getType() == GOType::Spline) + { + return CreateNode<VSpline>(data, id); + } + else + { + return CreateNode<VCubicBezier>(data, id); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +quint32 CreateNodeSplinePath(VContainer *data, quint32 id) +{ + if (data->GetGObject(id)->getType() == GOType::SplinePath) + { + return CreateNode<VSplinePath>(data, id); + } + else + { + return CreateNode<VCubicBezierPath>(data, id); + } +} +}//static functions + //--------------------------------------------------------------------------------------------------------------------- /** * @brief VAbstractTool container. @@ -101,6 +157,96 @@ VAbstractTool::~VAbstractTool() } } +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief CheckFormula check formula. + * + * Try calculate formula. If find error show dialog that allow user try fix formula. If user can't throw exception. In + * successes case return result calculation and fixed formula string. If formula ok don't touch formula. + * + * @param toolId [in] tool's id. + * @param formula [in|out] string with formula. + * @param data [in] container with variables. Need for math parser. + * @throw QmuParserError. + * @return result of calculation formula. + */ +qreal VAbstractTool::CheckFormula(const quint32 &toolId, QString &formula, VContainer *data) +{ + SCASSERT(data != nullptr) + qreal result = 0; + try + { + QScopedPointer<Calculator> cal(new Calculator()); + result = cal->EvalFormula(data->PlainVariables(), formula); + + if (qIsInf(result) || qIsNaN(result)) + { + qDebug() << "Invalid the formula value"; + return 0; + } + } + catch (qmu::QmuParserError &e) + { + qDebug() << "\nMath parser error:\n" + << "--------------------------------------\n" + << "Message: " << e.GetMsg() << "\n" + << "Expression: " << e.GetExpr() << "\n" + << "--------------------------------------"; + + if (qApp->IsAppInGUIMode()) + { + QScopedPointer<DialogUndo> dialogUndo(new DialogUndo(qApp->getMainWindow())); + forever + { + if (dialogUndo->exec() == QDialog::Accepted) + { + const UndoButton resultUndo = dialogUndo->Result(); + if (resultUndo == UndoButton::Fix) + { + auto *dialog = new DialogEditWrongFormula(data, toolId, qApp->getMainWindow()); + dialog->setWindowTitle(tr("Edit wrong formula")); + dialog->SetFormula(formula); + if (dialog->exec() == QDialog::Accepted) + { + formula = dialog->GetFormula(); + /* Need delete dialog here because parser in dialog don't allow use correct separator for + * parsing here. */ + delete dialog; + QScopedPointer<Calculator> cal1(new Calculator()); + result = cal1->EvalFormula(data->PlainVariables(), formula); + + if (qIsInf(result) || qIsNaN(result)) + { + qDebug() << "Invalid the formula value"; + return 0; + } + + break; + } + else + { + delete dialog; + } + } + else + { + throw VExceptionUndo(QString("Undo wrong formula %1").arg(formula)); + } + } + else + { + throw; + } + } + } + else + { + throw; + } + } + return result; +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief DeleteTool full delete object form scene and file. @@ -188,6 +334,35 @@ Qt::PenStyle VAbstractTool::LineStyleToPenStyle(const QString &typeLine) } } +//--------------------------------------------------------------------------------------------------------------------- +QString VAbstractTool::PenStyleToLineStyle(Qt::PenStyle penStyle) +{ + QT_WARNING_PUSH + QT_WARNING_DISABLE_GCC("-Wswitch-default") + + switch (penStyle) + { + case Qt::NoPen: + return TypeLineNone; + case Qt::DashLine: + return TypeLineDashLine; + case Qt::DotLine: + return TypeLineDotLine; + case Qt::DashDotLine: + return TypeLineDashDotLine; + case Qt::DashDotDotLine: + return TypeLineDashDotDotLine; + case Qt::SolidLine: + case Qt::CustomDashLine: + default: + break; + } + + QT_WARNING_POP + + return TypeLineLine; +} + //--------------------------------------------------------------------------------------------------------------------- QMap<QString, QIcon> VAbstractTool::LineStylesPics() { @@ -385,6 +560,26 @@ void VAbstractTool::AddRecord(const quint32 id, const Tool &toolType, VAbstractP } } +//--------------------------------------------------------------------------------------------------------------------- +void VAbstractTool::AddNodes(VAbstractPattern *doc, QDomElement &domElement, const VPiecePath &path) +{ + if (path.CountNodes() > 0) + { + QDomElement nodesElement = doc->createElement(VAbstractPattern::TagNodes); + for (int i = 0; i < path.CountNodes(); ++i) + { + AddNode(doc, nodesElement, path.at(i)); + } + domElement.appendChild(nodesElement); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VAbstractTool::AddNodes(VAbstractPattern *doc, QDomElement &domElement, const VPiece &piece) +{ + AddNodes(doc, domElement, piece.GetPath()); +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief RefreshLine refresh line to label on scene. @@ -421,3 +616,104 @@ void VAbstractTool::RefreshLine(QGraphicsEllipseItem *point, VGraphicsSimpleText lineName->setVisible(false); } } + +//--------------------------------------------------------------------------------------------------------------------- +QDomElement VAbstractTool::AddSANode(VAbstractPattern *doc, const QString &tagName, const VPieceNode &node) +{ + QDomElement nod = doc->createElement(tagName); + + doc->SetAttribute(nod, AttrIdObject, node.GetId()); + + const Tool type = node.GetTypeTool(); + if (type != Tool::NodePoint) + { + doc->SetAttribute(nod, VAbstractPattern::AttrNodeReverse, static_cast<quint8>(node.GetReverse())); + } + else + { + if (node.GetFormulaSABefore() != currentSeamAllowance) + { + doc->SetAttribute(nod, VAbstractPattern::AttrSABefore, node.GetFormulaSABefore()); + } + + if (node.GetFormulaSAAfter() != currentSeamAllowance) + { + doc->SetAttribute(nod, VAbstractPattern::AttrSAAfter, node.GetFormulaSAAfter()); + } + } + + switch (type) + { + case (Tool::NodeArc): + doc->SetAttribute(nod, AttrType, VAbstractPattern::NodeArc); + break; + case (Tool::NodePoint): + doc->SetAttribute(nod, AttrType, VAbstractPattern::NodePoint); + break; + case (Tool::NodeSpline): + doc->SetAttribute(nod, AttrType, VAbstractPattern::NodeSpline); + break; + case (Tool::NodeSplinePath): + doc->SetAttribute(nod, AttrType, VAbstractPattern::NodeSplinePath); + break; + default: + qDebug()<<"May be wrong tool type!!! Ignoring."<<Q_FUNC_INFO; + break; + } + + const unsigned char angleType = static_cast<unsigned char>(node.GetAngleType()); + + if (angleType > 0) + { + doc->SetAttribute(nod, AttrAngle, angleType); + } + + return nod; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VAbstractTool::AddNode(VAbstractPattern *doc, QDomElement &domElement, const VPieceNode &node) +{ + domElement.appendChild(AddSANode(doc, VAbstractPattern::TagNode, node)); +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<VPieceNode> VAbstractTool::PrepareNodes(const VPiecePath &path, VMainGraphicsScene *scene, + VAbstractPattern *doc, VContainer *data) +{ + QVector<VPieceNode> nodes; + for (int i = 0; i< path.CountNodes(); ++i) + { + quint32 id = 0; + VPieceNode nodeD = path.at(i); + switch (nodeD.GetTypeTool()) + { + case (Tool::NodePoint): + id = CreateNode<VPointF>(data, nodeD.GetId()); + VNodePoint::Create(doc, data, scene, id, nodeD.GetId(), Document::FullParse, Source::FromGui); + break; + case (Tool::NodeArc): + id = CreateNode<VArc>(data, nodeD.GetId()); + VNodeArc::Create(doc, data, id, nodeD.GetId(), Document::FullParse, Source::FromGui); + break; + case (Tool::NodeElArc): + id = CreateNode<VEllipticalArc>(data, nodeD.GetId()); + VNodeEllipticalArc::Create(doc, data, id, nodeD.GetId(), Document::FullParse, Source::FromGui); + break; + case (Tool::NodeSpline): + id = CreateNodeSpline(data, nodeD.GetId()); + VNodeSpline::Create(doc, data, id, nodeD.GetId(), Document::FullParse, Source::FromGui); + break; + case (Tool::NodeSplinePath): + id = CreateNodeSplinePath(data, nodeD.GetId()); + VNodeSplinePath::Create(doc, data, id, nodeD.GetId(), Document::FullParse, Source::FromGui); + break; + default: + qDebug()<<"May be wrong tool type!!! Ignoring."<<Q_FUNC_INFO; + break; + } + nodeD.SetId(id); + nodes.append(nodeD); + } + return nodes; +} diff --git a/src/libs/vtools/tools/vabstracttool.h b/src/libs/vtools/tools/vabstracttool.h index 5c8b22102..e4bec6a15 100644 --- a/src/libs/vtools/tools/vabstracttool.h +++ b/src/libs/vtools/tools/vabstracttool.h @@ -73,14 +73,19 @@ public: static const QString AttrInUse; + static qreal CheckFormula(const quint32 &toolId, QString &formula, VContainer *data); + static const QStringList StylesList(); static Qt::PenStyle LineStyleToPenStyle(const QString &typeLine); + static QString PenStyleToLineStyle(Qt::PenStyle penStyle); static QMap<QString, QIcon> LineStylesPics(); static const QStringList Colors(); static QMap<QString, QString> ColorsList(); - static void AddRecord(const quint32 id, const Tool &toolType, VAbstractPattern *doc); + static void AddRecord(const quint32 id, const Tool &toolType, VAbstractPattern *doc); + static void AddNodes(VAbstractPattern *doc, QDomElement &domElement, const VPiecePath &path); + static void AddNodes(VAbstractPattern *doc, QDomElement &domElement, const VPiece &piece); const VContainer *getData() const; @@ -144,10 +149,16 @@ protected: void AddVisualization(); virtual void SetVisualization()=0; - void ToolCreation(const Source &typeCreation); + virtual void ToolCreation(const Source &typeCreation); - static void RefreshLine(QGraphicsEllipseItem *point, VGraphicsSimpleTextItem *namePoint, QGraphicsLineItem *lineName, - const qreal radius); + static void RefreshLine(QGraphicsEllipseItem *point, VGraphicsSimpleTextItem *namePoint, + QGraphicsLineItem *lineName, const qreal radius); + + static QDomElement AddSANode(VAbstractPattern *doc, const QString &tagName, const VPieceNode &node); + static void AddNode(VAbstractPattern *doc, QDomElement &domElement, const VPieceNode &node); + + static QVector<VPieceNode> PrepareNodes(const VPiecePath &path, VMainGraphicsScene *scene, VAbstractPattern *doc, + VContainer *data); private: Q_DISABLE_COPY(VAbstractTool) }; diff --git a/src/libs/vtools/tools/vgrainlineitem.h b/src/libs/vtools/tools/vgrainlineitem.h deleted file mode 100644 index 41ea59eb5..000000000 --- a/src/libs/vtools/tools/vgrainlineitem.h +++ /dev/null @@ -1,103 +0,0 @@ -/************************************************************************ - ** - ** @file vgrainlineitem.h - ** @author Bojan Kverh - ** @date September 10, 2016 - ** - ** @brief - ** @copyright - ** This source code is part of the Valentine project, a pattern making - ** program, whose allow create and modeling patterns of clothing. - ** Copyright (C) 2013-2015 Valentina project - ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. - ** - ** Valentina is free software: you can redistribute it and/or modify - ** it under the terms of the GNU General Public License as published by - ** the Free Software Foundation, either version 3 of the License, or - ** (at your option) any later version. - ** - ** Valentina is distributed in the hope that it will be useful, - ** but WITHOUT ANY WARRANTY; without even the implied warranty of - ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - ** GNU General Public License for more details. - ** - ** You should have received a copy of the GNU General Public License - ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. - ** - *************************************************************************/ - -#ifndef VGRAINLINEITEM_H -#define VGRAINLINEITEM_H - -#include <QGraphicsObject> - -#include "../vpatterndb/vgrainlinegeometry.h" - -class QGraphicsObject; -class QPainter; -class QStyleOptionGraphicsItem; -class QWidget; - -class VGrainlineItem : public QGraphicsObject -{ - Q_OBJECT - - enum Mode { - mNormal, - mMove, - mResize, - mRotate - }; - -public: - explicit VGrainlineItem(QGraphicsItem* pParent = nullptr); - virtual ~VGrainlineItem(); - - void paint(QPainter* pP, const QStyleOptionGraphicsItem* pOption, QWidget* pWidget); - void UpdateGeometry(const QPointF& ptPos, qreal dRotation, qreal dLength, - VGrainlineGeometry::ArrowType eAT); - - QRectF boundingRect() const; - void Reset(); - bool IsIdle() const; - bool IsContained(const QPointF &pt, qreal dRot, qreal &dX, qreal &dY) const; - void SetScale(qreal dScale); - -protected: - void mousePressEvent(QGraphicsSceneMouseEvent* pME); - void mouseMoveEvent(QGraphicsSceneMouseEvent* pME); - void mouseReleaseEvent(QGraphicsSceneMouseEvent* pME); - void UpdateBox(); - void UpdateRectangle(); - - qreal GetAngle(const QPointF& pt) const; - QPointF Rotate(const QPointF& pt, const QPointF& ptCenter, qreal dAng) const; - QPointF GetInsideCorner(int i, qreal dDist) const; - -signals: - void SignalMoved(const QPointF& ptPos); - void SignalResized(qreal dLength); - void SignalRotated(qreal dRot, const QPointF& ptNewPos); - -private: - Mode m_eMode; - bool m_bReleased; - qreal m_dRotation; - qreal m_dStartRotation; - qreal m_dLength; - QRectF m_rectBoundingBox; - QPolygonF m_polyBound; - QPointF m_ptStartPos; - QPointF m_ptStartMove; - qreal m_dScale; - QPolygonF m_polyResize; - qreal m_dStartLength; - QPointF m_ptStart; - QPointF m_ptFinish; - QPointF m_ptCenter; - QPointF m_ptRotCenter; - qreal m_dAngle; - VGrainlineGeometry::ArrowType m_eArrowType; -}; - -#endif // VGRAINLINEITEM_H diff --git a/src/libs/vtools/tools/vtextgraphicsitem.h b/src/libs/vtools/tools/vtextgraphicsitem.h deleted file mode 100644 index 923b91ac2..000000000 --- a/src/libs/vtools/tools/vtextgraphicsitem.h +++ /dev/null @@ -1,128 +0,0 @@ -/************************************************************************ - ** - ** @file vtextgraphicsitem.h - ** @author Bojan Kverh - ** @date June 16, 2016 - ** - ** @brief - ** @copyright - ** This source code is part of the Valentine project, a pattern making - ** program, whose allow create and modeling patterns of clothing. - ** Copyright (C) 2013-2015 Valentina project - ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. - ** - ** Valentina is free software: you can redistribute it and/or modify - ** it under the terms of the GNU General Public License as published by - ** the Free Software Foundation, either version 3 of the License, or - ** (at your option) any later version. - ** - ** Valentina is distributed in the hope that it will be useful, - ** but WITHOUT ANY WARRANTY; without even the implied warranty of - ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - ** GNU General Public License for more details. - ** - ** You should have received a copy of the GNU General Public License - ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. - ** - *************************************************************************/ - -#ifndef VTEXTGRAPHICSITEM_H -#define VTEXTGRAPHICSITEM_H - -#include <QFont> -#include <QGraphicsObject> -#include <QList> -#include <QMetaObject> -#include <QObject> -#include <QPointF> -#include <QRectF> -#include <QSizeF> -#include <QString> -#include <QtGlobal> - -#include "../vlayout/vtextmanager.h" - -class QFont; -class QGraphicsItem; -class QGraphicsSceneHoverEvent; -class QGraphicsSceneMouseEvent; -class QPainter; -class QPointF; -class QRectF; -class QStyleOptionGraphicsItem; -class QWidget; -class VAbstractPattern; -class VPatternPieceData; - -/** - * @brief The VTextGraphicsItem class. This class implements text graphics item, - * which can be dragged around, resized and rotated within the parent item. The text font - * size will be automatically updated, so that the entire text will fit into the item. - */ -class VTextGraphicsItem : public QGraphicsObject -{ - Q_OBJECT - - enum Mode { - mNormal, - mMove, - mResize, - mRotate - }; - -public: - explicit VTextGraphicsItem(QGraphicsItem* pParent = nullptr); - virtual ~VTextGraphicsItem(); - - void SetFont(const QFont& fnt); - virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, - QWidget *widget) Q_DECL_OVERRIDE; - - void Reset(); - bool IsIdle() const; - - int GetFontSize() const; - virtual QRectF boundingRect() const Q_DECL_OVERRIDE; - void AddLine(const TextLine& tl); - void Clear(); - void SetSize(qreal fW, qreal fH); - void Update(); - bool IsContained(QRectF rectBB, qreal dRot, qreal& dX, qreal& dY) const; - void UpdateData(const QString& qsName, const VPatternPieceData& data); - void UpdateData(const VAbstractPattern* pDoc, qreal dSize, qreal dHeight); - int GetTextLines() const; - -protected: - virtual void mousePressEvent(QGraphicsSceneMouseEvent* pME) Q_DECL_OVERRIDE; - virtual void mouseMoveEvent(QGraphicsSceneMouseEvent* pME) Q_DECL_OVERRIDE; - virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent* pME) Q_DECL_OVERRIDE; - virtual void hoverMoveEvent(QGraphicsSceneHoverEvent* pHE) Q_DECL_OVERRIDE; - virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent* pHE) Q_DECL_OVERRIDE; - void UpdateBox(); - void CorrectLabel(); - - double GetAngle(QPointF pt) const; - -signals: - void SignalMoved(const QPointF& ptPos); - void SignalResized(qreal iTW, int iFontSize); - void SignalRotated(qreal dAng); - void SignalShrink(); - -private: - Mode m_eMode; - bool m_bReleased; - QPointF m_ptStartPos; - QPointF m_ptStart; - QPointF m_ptRotCenter; - QSizeF m_szStart; - double m_dRotation; - double m_dAngle; - QRectF m_rectResize; - QRectF m_rectBoundingBox; - VTextManager m_tm; - - QRectF GetBoundingRect(QRectF rectBB, qreal dRot) const; -}; - -#endif // VTEXTGRAPHICSITEM_H diff --git a/src/libs/vtools/tools/vtooldetail.cpp b/src/libs/vtools/tools/vtooldetail.cpp deleted file mode 100644 index c5b2313e9..000000000 --- a/src/libs/vtools/tools/vtooldetail.cpp +++ /dev/null @@ -1,1330 +0,0 @@ -/************************************************************************ - ** - ** @file vtooldetail.cpp - ** @author Roman Telezhynskyi <dismine(at)gmail.com> - ** @date November 15, 2013 - ** - ** @brief - ** @copyright - ** This source code is part of the Valentine project, a pattern making - ** program, whose allow create and modeling patterns of clothing. - ** Copyright (C) 2013-2015 Valentina project - ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. - ** - ** Valentina is free software: you can redistribute it and/or modify - ** it under the terms of the GNU General Public License as published by - ** the Free Software Foundation, either version 3 of the License, or - ** (at your option) any later version. - ** - ** Valentina is distributed in the hope that it will be useful, - ** but WITHOUT ANY WARRANTY; without even the implied warranty of - ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - ** GNU General Public License for more details. - ** - ** You should have received a copy of the GNU General Public License - ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. - ** - *************************************************************************/ - -#include "vtooldetail.h" - -#include <QAction> -#include <QBrush> -#include <QDialog> -#include <QDomElement> -#include <QEvent> -#include <QFlags> -#include <QFont> -#include <QGraphicsItem> -#include <QGraphicsScene> -#include <QGraphicsSceneContextMenuEvent> -#include <QGraphicsSceneMouseEvent> -#include <QGraphicsView> -#include <QHash> -#include <QIcon> -#include <QKeyEvent> -#include <QList> -#include <QMenu> -#include <QMessageBox> -#include <QMessageLogger> -#include <QPainter> -#include <QPainterPath> -#include <QPen> -#include <QPoint> -#include <QPointF> -#include <QPolygonF> -#include <QRectF> -#include <QSharedPointer> -#include <QStaticStringData> -#include <QString> -#include <QStringData> -#include <QStringDataPtr> -#include <QStringList> -#include <QUndoStack> -#include <QVariant> -#include <Qt> -#include <QtDebug> -#include <new> - -#include "../dialogs/tools/dialogdetail.h" -#include "../dialogs/tools/dialogtool.h" -#include "../ifc/exception/vexception.h" -#include "../ifc/xml/vdomdocument.h" -#include "../ifc/xml/vabstractpattern.h" -#include "../ifc/ifcdef.h" -#include "../undocommands/adddet.h" -#include "../undocommands/deletedetail.h" -#include "../undocommands/movedetail.h" -#include "../undocommands/savedetailoptions.h" -#include "../undocommands/toggledetailinlayout.h" -#include "../vgeometry/varc.h" -#include "../vgeometry/vellipticalarc.h" -#include "../vgeometry/vcubicbezier.h" -#include "../vgeometry/vcubicbezierpath.h" -#include "../vgeometry/vgeometrydef.h" -#include "../vgeometry/vgobject.h" -#include "../vgeometry/vpointf.h" -#include "../vgeometry/vspline.h" -#include "../vgeometry/vsplinepath.h" -#include "../vmisc/vabstractapplication.h" -#include "../vpatterndb/vcontainer.h" -#include "../vpatterndb/vdetail.h" -#include "../vpatterndb/vpatterninfogeometry.h" -#include "../vpatterndb/vpatternpiecedata.h" -#include "../vpatterndb/calculator.h" -#include "../vmisc/def.h" -#include "../vwidgets/vmaingraphicsscene.h" -#include "../vwidgets/vmaingraphicsview.h" -#include "../vwidgets/vnobrushscalepathitem.h" -#include "../tools/vtooldetail.h" -#include "vabstracttool.h" -#include "nodeDetails/vabstractnode.h" -#include "nodeDetails/vnodearc.h" -#include "nodeDetails/vnodeellipticalarc.h" -#include "nodeDetails/vnodepoint.h" -#include "nodeDetails/vnodespline.h" -#include "nodeDetails/vnodesplinepath.h" -#include "vtextgraphicsitem.h" -#include "vnodedetail.h" - -class QDomElement; -class QGraphicsSceneContextMenuEvent; -class QGraphicsSceneHoverEvent; -class QGraphicsSceneMouseEvent; -class QKeyEvent; -class QStyleOptionGraphicsItem; -class QWidget; -class VDataTool; - -const QString VToolDetail::TagNode = QStringLiteral("node"); - -const QString VToolDetail::AttrSupplement = QStringLiteral("supplement"); -const QString VToolDetail::AttrClosed = QStringLiteral("closed"); -const QString VToolDetail::AttrForbidFlipping = QStringLiteral("forbidFlipping"); -const QString VToolDetail::AttrWidth = QStringLiteral("width"); -const QString VToolDetail::AttrHeight = QStringLiteral("height"); -const QString VToolDetail::AttrNodeType = QStringLiteral("nodeType"); -const QString VToolDetail::AttrReverse = QStringLiteral("reverse"); -const QString VToolDetail::AttrFont = QStringLiteral("fontSize"); -const QString VToolDetail::AttrRotation = QStringLiteral("rotation"); - -const QString VToolDetail::NodeTypeContour = QStringLiteral("Contour"); -const QString VToolDetail::NodeTypeModeling = QStringLiteral("Modeling"); - -const QString VToolDetail::NodeArc = QStringLiteral("NodeArc"); -const QString VToolDetail::NodeElArc = QStringLiteral("NodeElArc"); -const QString VToolDetail::NodePoint = QStringLiteral("NodePoint"); -const QString VToolDetail::NodeSpline = QStringLiteral("NodeSpline"); -const QString VToolDetail::NodeSplinePath = QStringLiteral("NodeSplinePath"); - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief VToolDetail constructor. - * @param doc dom document container - * @param data container with variables - * @param id object id in container - * @param typeCreation way we create this tool. - * @param scene pointer to scene. - * @param parent parent object - */ -VToolDetail::VToolDetail(VAbstractPattern *doc, VContainer *data, const quint32 &id, const Source &typeCreation, - VMainGraphicsScene *scene, const QString &drawName, QGraphicsItem *parent) - :VAbstractTool(doc, data, id), VNoBrushScalePathItem(parent), dialog(nullptr), sceneDetails(scene), - drawName(drawName), seamAllowance(new VNoBrushScalePathItem(this)), dataLabel(new VTextGraphicsItem(this)), - patternInfo(new VTextGraphicsItem(this)), grainLine(new VGrainlineItem(this)) -{ - VDetail detail = data->GetDetail(id); - for (int i = 0; i< detail.CountNode(); ++i) - { - switch (detail.at(i).getTypeTool()) - { - case (Tool::NodePoint): - { - VNodePoint *tool = InitTool<VNodePoint>(scene, detail.at(i)); - connect(tool, &VNodePoint::ShowContextMenu, this, &VToolDetail::contextMenuEvent); - break; - } - case (Tool::NodeArc): - case (Tool::NodeElArc): - case (Tool::NodeSpline): - case (Tool::NodeSplinePath): - doc->IncrementReferens(detail.at(i).getId()); - break; - default: - qDebug()<<"Get wrong tool type. Ignore."; - break; - } - } - this->setFlag(QGraphicsItem::ItemIsMovable, true); - this->setFlag(QGraphicsItem::ItemIsSelectable, true); - RefreshGeometry(); - - this->setBrush(QBrush(Qt::Dense7Pattern)); - seamAllowance->setBrush(QBrush(Qt::FDiagPattern)); - - this->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); - this->setFlag(QGraphicsItem::ItemIsFocusable, true);// For keyboard input focus - - connect(scene, &VMainGraphicsScene::EnableToolMove, this, &VToolDetail::EnableToolMove); - connect(scene, &VMainGraphicsScene::ItemClicked, this, &VToolDetail::ResetChildren); - if (typeCreation == Source::FromGui || typeCreation == Source::FromTool) - { - AddToFile(); - if (typeCreation != Source::FromTool) - { - qApp->getUndoStack()->endMacro(); - } - } - setAcceptHoverEvents(true); - - connect(dataLabel, &VTextGraphicsItem::SignalMoved, this, &VToolDetail::SaveMoveDetail); - connect(dataLabel, &VTextGraphicsItem::SignalResized, this, &VToolDetail::SaveResizeDetail); - connect(dataLabel, &VTextGraphicsItem::SignalRotated, this, &VToolDetail::SaveRotationDetail); - - connect(patternInfo, &VTextGraphicsItem::SignalMoved, this, &VToolDetail::SaveMovePattern); - connect(patternInfo, &VTextGraphicsItem::SignalResized, this, &VToolDetail::SaveResizePattern); - connect(patternInfo, &VTextGraphicsItem::SignalRotated, this, &VToolDetail::SaveRotationPattern); - - connect(grainLine, &VGrainlineItem::SignalMoved, this, &VToolDetail::SaveMoveGrainline); - connect(grainLine, &VGrainlineItem::SignalResized, this, &VToolDetail::SaveResizeGrainline); - connect(grainLine, &VGrainlineItem::SignalRotated, this, &VToolDetail::SaveRotateGrainline); - - connect(doc, &VAbstractPattern::patternChanged, this, &VToolDetail::UpdatePatternInfo); - connect(doc, &VAbstractPattern::CheckLayout, this, &VToolDetail::UpdateLabel); - connect(doc, &VAbstractPattern::CheckLayout, this, &VToolDetail::UpdatePatternInfo); - connect(doc, &VAbstractPattern::CheckLayout, this, &VToolDetail::UpdateGrainline); - - connect(sceneDetails, &VMainGraphicsScene::DimensionsChanged, this, &VToolDetail::UpdateLabel); - connect(sceneDetails, &VMainGraphicsScene::DimensionsChanged, this, &VToolDetail::UpdatePatternInfo); - connect(sceneDetails, &VMainGraphicsScene::LanguageChanged, this, &VToolDetail::retranslateUi); - - UpdateLabel(); - UpdatePatternInfo(); - UpdateGrainline(); -} - -//--------------------------------------------------------------------------------------------------------------------- -VToolDetail::~VToolDetail() -{ - delete dialog; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief setDialog set dialog when user want change tool option. - */ -void VToolDetail::setDialog() -{ - SCASSERT(dialog != nullptr) - DialogDetail *dialogTool = qobject_cast<DialogDetail*>(dialog); - SCASSERT(dialogTool != nullptr) - dialogTool->setDetail(VAbstractTool::data.GetDetail(id)); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief Create help create tool from GUI. - * @param dialog dialog. - * @param scene pointer to scene. - * @param doc dom document container. - * @param data container with variables. - */ -void VToolDetail::Create(DialogTool *dialog, VMainGraphicsScene *scene, VAbstractPattern *doc, VContainer *data) -{ - SCASSERT(dialog != nullptr) - DialogDetail *dialogTool = qobject_cast<DialogDetail*>(dialog); - SCASSERT(dialogTool != nullptr) - VDetail detail = dialogTool->getDetail(); - VDetail det; - qApp->getUndoStack()->beginMacro("add detail"); - for (int i = 0; i< detail.CountNode(); ++i) - { - quint32 id = 0; - const VNodeDetail &nodeD = detail.at(i); - switch (nodeD.getTypeTool()) - { - case (Tool::NodePoint): - { - id = CreateNode<VPointF>(data, nodeD.getId()); - VNodePoint::Create(doc, data, scene, id, nodeD.getId(), Document::FullParse, Source::FromGui); - } - break; - case (Tool::NodeArc): - { - id = CreateNode<VArc>(data, nodeD.getId()); - VNodeArc::Create(doc, data, id, nodeD.getId(), Document::FullParse, Source::FromGui); - } - break; - case (Tool::NodeElArc): - { - id = CreateNode<VEllipticalArc>(data, nodeD.getId()); - VNodeEllipticalArc::Create(doc, data, id, nodeD.getId(), Document::FullParse, Source::FromGui); - } - break; - case (Tool::NodeSpline): - { - const auto obj = data->GetGObject(nodeD.getId()); - if (obj->getType() == GOType::Spline) - { - id = CreateNode<VSpline>(data, nodeD.getId()); - } - else - { - id = CreateNode<VCubicBezier>(data, nodeD.getId()); - } - VNodeSpline::Create(doc, data, id, nodeD.getId(), Document::FullParse, Source::FromGui); - } - break; - case (Tool::NodeSplinePath): - { - const auto obj = data->GetGObject(nodeD.getId()); - if (obj->getType() == GOType::SplinePath) - { - id = CreateNode<VSplinePath>(data, nodeD.getId()); - } - else - { - id = CreateNode<VCubicBezierPath>(data, nodeD.getId()); - } - VNodeSplinePath::Create(doc, data, id, nodeD.getId(), Document::FullParse, Source::FromGui); - } - break; - default: - qDebug()<<"May be wrong tool type!!! Ignoring."<<Q_FUNC_INFO; - break; - } - VNodeDetail node(id, nodeD.getTypeTool(), NodeDetail::Contour, nodeD.getMx(), nodeD.getMy(), - nodeD.getReverse()); - det.append(node); - } - det.setName(detail.getName()); - det.setWidth(detail.getWidth()); - det.setClosed(detail.getClosed()); - det.setSeamAllowance(detail.getSeamAllowance()); - det.setForbidFlipping(detail.getForbidFlipping()); - det.SetPatternPieceData(detail.GetPatternPieceData()); - det.SetPatternInfo(detail.GetPatternInfo()); - Create(0, det, scene, doc, data, Document::FullParse, Source::FromGui); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief Create help create tool. - * @param _id tool id, 0 if tool doesn't exist yet. - * @param newDetail detail what we want show. - * @param scene pointer to scene. - * @param doc dom document container. - * @param data container with variables. - * @param parse parser file mode. - * @param typeCreation way we create this tool. - */ -void VToolDetail::Create(const quint32 &_id, const VDetail &newDetail, VMainGraphicsScene *scene, VAbstractPattern *doc, - VContainer *data, const Document &parse, const Source &typeCreation, const QString &drawName) -{ - quint32 id = _id; - if (typeCreation == Source::FromGui || typeCreation == Source::FromTool) - { - id = data->AddDetail(newDetail); - } - else - { - data->UpdateDetail(id, newDetail); - if (parse != Document::FullParse) - { - doc->UpdateToolData(id, data); - } - } - VAbstractTool::AddRecord(id, Tool::Detail, doc); - if (parse == Document::FullParse) - { - VToolDetail *detail = new VToolDetail(doc, data, id, typeCreation, scene, drawName); - scene->addItem(detail); - connect(detail, &VToolDetail::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem); - connect(scene, &VMainGraphicsScene::EnableDetailItemHover, detail, &VToolDetail::AllowHover); - connect(scene, &VMainGraphicsScene::EnableDetailItemSelection, detail, &VToolDetail::AllowSelecting); - connect(scene, &VMainGraphicsScene::HighlightDetail, detail, &VToolDetail::Highlight); - doc->AddTool(id, detail); - } -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief Remove full delete detail. - */ -void VToolDetail::Remove(bool ask) -{ - try - { - DeleteTool(ask); - } - catch(const VExceptionToolWasDeleted &e) - { - Q_UNUSED(e) - return;//Leave this method immediately!!! - } -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief FullUpdateFromFile update tool data form file. - */ -void VToolDetail::FullUpdateFromFile() -{ - RefreshGeometry(); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief FullUpdateFromGuiOk refresh tool data after change in options. - * @param result keep result working dialog. - */ -void VToolDetail::FullUpdateFromGuiOk(int result) -{ - if (result == QDialog::Accepted) - { - SCASSERT(dialog != nullptr) - DialogDetail *dialogTool = qobject_cast<DialogDetail*>(dialog); - SCASSERT(dialogTool != nullptr) - const VDetail newDet = dialogTool->getDetail(); - const VDetail oldDet = VAbstractTool::data.GetDetail(id); - - qDebug() << "VToolDetail Position" << newDet.GetPatternPieceData().GetPos(); - SaveDetailOptions *saveCommand = new SaveDetailOptions(oldDet, newDet, doc, id, this->scene()); - connect(saveCommand, &SaveDetailOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); - qApp->getUndoStack()->push(saveCommand); - UpdateLabel(); - } - delete dialog; - dialog = nullptr; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief VToolDetail::paint draws a bounding box around detail, if one of its text or grainline items is not idle. - */ -void VToolDetail::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) -{ - if (scene()->views().count() > 0) - { - const QPoint pt0 = scene()->views().at(0)->mapFromScene(0, 0); - const QPoint pt = scene()->views().at(0)->mapFromScene(0, 100); - - const QPoint p = pt - pt0; - -#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) - const qreal dScale = qSqrt(QPoint::dotProduct(p, p)); -#else - const qreal dScale = qSqrt(p.x() * p.x() + p.y() * p.y()); -#endif //QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) - grainLine->SetScale(100/dScale); - //qDebug() << "SCALE" << dScale << 10/dScale; - } - - if (dataLabel->IsIdle() == false || patternInfo->IsIdle() == false || grainLine->IsIdle() == false) - { - painter->save(); - painter->setPen(QPen(Qt::black, 3, Qt::DashLine)); - painter->drawRect(boundingRect().adjusted(1, 1, -1, -1)); - painter->restore(); - } - VNoBrushScalePathItem::paint(painter, option, widget); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief AddToFile add tag with informations about tool into file. - */ -void VToolDetail::AddToFile() -{ - const VDetail detail = VAbstractTool::data.GetDetail(id); - QDomElement domElement = doc->createElement(getTagName()); - - doc->SetAttribute(domElement, VDomDocument::AttrId, id); - doc->SetAttribute(domElement, AttrName, detail.getName()); - doc->SetAttribute(domElement, AttrMx, qApp->fromPixel(detail.getMx())); - doc->SetAttribute(domElement, AttrMy, qApp->fromPixel(detail.getMy())); - doc->SetAttribute(domElement, AttrSupplement, static_cast<quint8>(detail.getSeamAllowance())); - doc->SetAttribute(domElement, AttrClosed, static_cast<quint8>(detail.getClosed())); - doc->SetAttribute(domElement, AttrWidth, detail.getWidth()); - doc->SetAttribute(domElement, AttrForbidFlipping, static_cast<quint8>(detail.getForbidFlipping())); - - // detail data - QDomElement domData = doc->createElement(VAbstractPattern::TagData); - const VPatternPieceData& data = detail.GetPatternPieceData(); - doc->SetAttribute(domData, VAbstractPattern::AttrLetter, data.GetLetter()); - doc->SetAttribute(domData, VAbstractPattern::AttrVisible, data.IsVisible() == true? trueStr : falseStr); - doc->SetAttribute(domData, AttrMx, data.GetPos().x()); - doc->SetAttribute(domData, AttrMy, data.GetPos().y()); - doc->SetAttribute(domData, AttrWidth, data.GetLabelWidth()); - doc->SetAttribute(domData, AttrHeight, data.GetLabelHeight()); - doc->SetAttribute(domData, AttrFont, data.GetFontSize()); - doc->SetAttribute(domData, AttrRotation, data.GetRotation()); - - for (int i = 0; i < data.GetMCPCount(); ++i) - { - MaterialCutPlacement mcp = data.GetMCP(i); - QDomElement domMCP = doc->createElement(VAbstractPattern::TagMCP); - doc->SetAttribute(domMCP, VAbstractPattern::AttrMaterial, int(mcp.m_eMaterial)); - if (mcp.m_eMaterial == MaterialType::mtUserDefined) - { - doc->SetAttribute(domMCP, VAbstractPattern::AttrUserDefined, mcp.m_qsMaterialUserDef); - } - doc->SetAttribute(domMCP, VAbstractPattern::AttrCutNumber, mcp.m_iCutNumber); - doc->SetAttribute(domMCP, VAbstractPattern::AttrPlacement, int(mcp.m_ePlacement)); - domData.appendChild(domMCP); - } - domElement.appendChild(domData); - - // pattern info - domData = doc->createElement(VAbstractPattern::TagPatternInfo); - const VPatternInfoGeometry& geom = detail.GetPatternInfo(); - doc->SetAttribute(domData, VAbstractPattern::AttrVisible, geom.IsVisible() == true? trueStr : falseStr); - doc->SetAttribute(domData, AttrMx, geom.GetPos().x()); - doc->SetAttribute(domData, AttrMy, geom.GetPos().y()); - doc->SetAttribute(domData, AttrWidth, geom.GetLabelWidth()); - doc->SetAttribute(domData, AttrHeight, geom.GetLabelHeight()); - doc->SetAttribute(domData, AttrFont, geom.GetFontSize()); - doc->SetAttribute(domData, AttrRotation, geom.GetRotation()); - domElement.appendChild(domData); - - // grainline - domData = doc->createElement(VAbstractPattern::TagGrainline); - const VGrainlineGeometry& glGeom = detail.GetGrainlineGeometry(); - doc->SetAttribute(domData, VAbstractPattern::AttrVisible, glGeom.IsVisible() == true? trueStr : falseStr); - doc->SetAttribute(domData, AttrMx, glGeom.GetPos().x()); - doc->SetAttribute(domData, AttrMy, glGeom.GetPos().y()); - doc->SetAttribute(domData, AttrLength, glGeom.GetLength()); - doc->SetAttribute(domData, AttrRotation, glGeom.GetRotation()); - doc->SetAttribute(domData, VAbstractPattern::AttrArrows, int(glGeom.GetArrowType())); - qDebug() << "XML ROTATION" << glGeom.GetRotation(); - - // nodes - for (int i = 0; i < detail.CountNode(); ++i) - { - AddNode(doc, domElement, detail.at(i)); - } - - AddDet *addDet = new AddDet(domElement, doc, detail, drawName); - connect(addDet, &AddDet::NeedFullParsing, doc, &VAbstractPattern::NeedFullParsing); - qApp->getUndoStack()->push(addDet); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief RefreshDataInFile refresh attributes in file. If attributes don't exist create them. - */ -void VToolDetail::RefreshDataInFile() -{ - QDomElement domElement = doc->elementById(id); - if (domElement.isElement()) - { - VDetail det = VAbstractTool::data.GetDetail(id); - doc->SetAttribute(domElement, AttrName, det.getName()); - doc->SetAttribute(domElement, AttrSupplement, QString().setNum(static_cast<quint8>(det.getSeamAllowance()))); - doc->SetAttribute(domElement, AttrClosed, QString().setNum(static_cast<quint8>(det.getClosed()))); - doc->SetAttribute(domElement, AttrWidth, QString().setNum(det.getWidth())); - doc->RemoveAllChildren(domElement); - - // detail data - QDomElement domData = doc->createElement(VAbstractPattern::TagData); - const VPatternPieceData& data = det.GetPatternPieceData(); - doc->SetAttribute(domData, VAbstractPattern::AttrLetter, data.GetLetter()); - doc->SetAttribute(domData, VAbstractPattern::AttrVisible, data.IsVisible() == true? trueStr : falseStr); - doc->SetAttribute(domData, AttrMx, data.GetPos().x()); - doc->SetAttribute(domData, AttrMy, data.GetPos().y()); - doc->SetAttribute(domData, AttrWidth, data.GetLabelWidth()); - doc->SetAttribute(domData, AttrHeight, data.GetLabelHeight()); - doc->SetAttribute(domData, AttrFont, data.GetFontSize()); - doc->SetAttribute(domData, AttrRotation, data.GetRotation()); - - for (int i = 0; i < data.GetMCPCount(); ++i) - { - MaterialCutPlacement mcp = data.GetMCP(i); - QDomElement domMCP = doc->createElement(VAbstractPattern::TagMCP); - doc->SetAttribute(domMCP, VAbstractPattern::AttrMaterial, int(mcp.m_eMaterial)); - if (mcp.m_eMaterial == MaterialType::mtUserDefined) - { - doc->SetAttribute(domMCP, VAbstractPattern::AttrUserDefined, mcp.m_qsMaterialUserDef); - } - else - { - domMCP.removeAttribute(VAbstractPattern::AttrUserDefined); - } - doc->SetAttribute(domMCP, VAbstractPattern::AttrCutNumber, mcp.m_iCutNumber); - doc->SetAttribute(domMCP, VAbstractPattern::AttrPlacement, int(mcp.m_ePlacement)); - domData.appendChild(domMCP); - } - domElement.appendChild(domData); - - // pattern info - domData = doc->createElement(VAbstractPattern::TagPatternInfo); - const VPatternInfoGeometry& geom = det.GetPatternInfo(); - doc->SetAttribute(domData, VAbstractPattern::AttrVisible, geom.IsVisible() == true? trueStr : falseStr); - doc->SetAttribute(domData, AttrMx, geom.GetPos().x()); - doc->SetAttribute(domData, AttrMy, geom.GetPos().y()); - doc->SetAttribute(domData, AttrWidth, geom.GetLabelWidth()); - doc->SetAttribute(domData, AttrHeight, geom.GetLabelHeight()); - doc->SetAttribute(domData, AttrFont, geom.GetFontSize()); - doc->SetAttribute(domData, AttrRotation, geom.GetRotation()); - - // grainline - domData = doc->createElement(VAbstractPattern::TagGrainline); - const VGrainlineGeometry& glGeom = det.GetGrainlineGeometry(); - doc->SetAttribute(domData, VAbstractPattern::AttrVisible, glGeom.IsVisible() == true? trueStr : falseStr); - doc->SetAttribute(domData, AttrMx, glGeom.GetPos().x()); - doc->SetAttribute(domData, AttrMy, glGeom.GetPos().y()); - doc->SetAttribute(domData, AttrLength, glGeom.GetLength()); - doc->SetAttribute(domData, AttrRotation, glGeom.GetRotation()); - doc->SetAttribute(domData, VAbstractPattern::AttrArrows, int(glGeom.GetArrowType())); - - // nodes - for (int i = 0; i < det.CountNode(); ++i) - { - AddNode(doc, domElement, det.at(i)); - } - } -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief itemChange handle detail change. - * @param change change - * @param value value - * @return new value. - */ -QVariant VToolDetail::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) -{ - if (change == ItemPositionChange && scene()) - { - // Each time we move something we call recalculation scene rect. In some cases this can cause moving - // objects positions. And this cause infinite redrawing. That's why we wait the finish of saving the last move. - static bool changeFinished = true; - if (changeFinished) - { - changeFinished = false; - - // value - this is new position. - const QPointF newPos = value.toPointF(); - - MoveDetail *moveDet = new MoveDetail(doc, newPos.x(), newPos.y(), id, scene()); - connect(moveDet, &MoveDetail::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); - qApp->getUndoStack()->push(moveDet); - - const QList<QGraphicsView *> viewList = scene()->views(); - if (not viewList.isEmpty()) - { - if (QGraphicsView *view = viewList.at(0)) - { - const int xmargin = 50; - const int ymargin = 50; - - const QRectF viewRect = VMainGraphicsView::SceneVisibleArea(view); - const QRectF itemRect = mapToScene(boundingRect()|childrenBoundingRect()).boundingRect(); - - // If item's rect is bigger than view's rect ensureVisible works very unstable. - if (itemRect.height() + 2*ymargin < viewRect.height() && - itemRect.width() + 2*xmargin < viewRect.width()) - { - view->ensureVisible(itemRect, xmargin, ymargin); - } - else - { - // Ensure visible only small rect around a cursor - VMainGraphicsScene *currentScene = qobject_cast<VMainGraphicsScene *>(scene()); - SCASSERT(currentScene) - const QPointF cursorPosition = currentScene->getScenePos(); - view->ensureVisible(QRectF(cursorPosition.x()-5, cursorPosition.y()-5, 10, 10)); - } - } - } - // Don't forget to update geometry, because first change never call full parse - RefreshGeometry(); - changeFinished = true; - } - } - - if (change == QGraphicsItem::ItemSelectedChange) - { - if (value == true) - { - // do stuff if selected - this->setFocus(); - } - else - { - // do stuff if not selected - } - } - - return VNoBrushScalePathItem::itemChange(change, value); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief keyReleaseEvent handle key release events. - * @param event key release event. - */ -void VToolDetail::keyReleaseEvent(QKeyEvent *event) -{ - switch (event->key()) - { - case Qt::Key_Delete: - try - { - DeleteTool(); - } - catch(const VExceptionToolWasDeleted &e) - { - Q_UNUSED(e) - return;//Leave this method immediately!!! - } - break; - default: - break; - } - VNoBrushScalePathItem::keyReleaseEvent ( event ); -} - -//--------------------------------------------------------------------------------------------------------------------- -void VToolDetail::mousePressEvent(QGraphicsSceneMouseEvent *event) -{ - // Special for not selectable item first need to call standard mousePressEvent then accept event - VNoBrushScalePathItem::mousePressEvent(event); - - // Somehow clicking on notselectable object do not clean previous selections. - if (not (flags() & ItemIsSelectable) && scene()) - { - scene()->clearSelection(); - } - - if (flags() & QGraphicsItem::ItemIsMovable) - { - if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick) - { - SetOverrideCursor(cursorArrowCloseHand, 1, 1); - } - } - - if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick) - { - doc->SelectedDetail(id); - emit ChoosedTool(id, SceneObject::Detail); - } - - event->accept();// Special for not selectable item first need to call standard mousePressEvent then accept event -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief mouseReleaseEvent handle mouse release events. - * @param event mouse release event. - */ -void VToolDetail::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) -{ - if (event->button() == Qt::LeftButton) - { - //Disable cursor-arrow-closehand - RestoreOverrideCursor(cursorArrowCloseHand); - } - VNoBrushScalePathItem::mouseReleaseEvent(event); -} - -//--------------------------------------------------------------------------------------------------------------------- -void VToolDetail::hoverMoveEvent(QGraphicsSceneHoverEvent *event) -{ - Q_UNUSED(event) - if (flags() & QGraphicsItem::ItemIsMovable) - { - SetOverrideCursor(cursorArrowOpenHand, 1, 1); - } -} - -//--------------------------------------------------------------------------------------------------------------------- -void VToolDetail::hoverEnterEvent(QGraphicsSceneHoverEvent *event) -{ - Q_UNUSED(event) - if (flags() & QGraphicsItem::ItemIsMovable) - { - SetOverrideCursor(cursorArrowOpenHand, 1, 1); - } -} - -//--------------------------------------------------------------------------------------------------------------------- -void VToolDetail::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) -{ - Q_UNUSED(event) - //Disable cursor-arrow-openhand - if (flags() & QGraphicsItem::ItemIsMovable) - { - RestoreOverrideCursor(cursorArrowOpenHand); - } -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief contextMenuEvent handle context menu events. - * @param event context menu event. - */ -void VToolDetail::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) -{ - QMenu menu; - QAction *actionOption = menu.addAction(QIcon::fromTheme("preferences-other"), tr("Options")); - - QAction *inLayoutOption = menu.addAction(tr("In layout")); - inLayoutOption->setCheckable(true); - const VDetail detail = VAbstractTool::data.GetDetail(id); - inLayoutOption->setChecked(detail.IsInLayout()); - - QAction *actionRemove = menu.addAction(QIcon::fromTheme("edit-delete"), tr("Delete")); - _referens > 1 ? actionRemove->setEnabled(false) : actionRemove->setEnabled(true); - - QAction *selectedAction = menu.exec(event->screenPos()); - if (selectedAction == actionOption) - { - dialog = new DialogDetail(getData(), id, qApp->getMainWindow()); - dialog->setModal(true); - connect(qobject_cast< VMainGraphicsScene * >(this->scene()), &VMainGraphicsScene::ChoosedObject, - dialog, &DialogTool::ChosenObject); - connect(dialog, &DialogTool::DialogClosed, this, &VToolDetail::FullUpdateFromGuiOk); - setDialog(); - dialog->show(); - } - else if (selectedAction == inLayoutOption) - { - ToggleDetailInLayout *togglePrint = new ToggleDetailInLayout(id, selectedAction->isChecked(), - &(VAbstractTool::data), doc); - connect(togglePrint, &ToggleDetailInLayout::UpdateList, doc, &VAbstractPattern::CheckInLayoutList); - qApp->getUndoStack()->push(togglePrint); - } - else if (selectedAction == actionRemove) - { - try - { - DeleteTool(); - } - catch(const VExceptionToolWasDeleted &e) - { - Q_UNUSED(e) - return;//Leave this method immediately!!! - } - return; //Leave this method immediately after call!!! - } -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief UpdateLabel updates the text label, making it just big enough for the text to fit it - */ -void VToolDetail::UpdateLabel() -{ - const VDetail detail = VAbstractTool::data.GetDetail(id); - const VPatternPieceData& data = detail.GetPatternPieceData(); - - if (data.IsVisible() == true) - { - QFont fnt = qApp->font(); - { - const int iFS = data.GetFontSize(); - iFS < MIN_FONT_SIZE ? fnt.setPixelSize(MIN_FONT_SIZE) : fnt.setPixelSize(iFS); - } - dataLabel->SetFont(fnt); - dataLabel->SetSize(data.GetLabelWidth(), data.GetLabelHeight()); - dataLabel->UpdateData(detail.getName(), data); - QPointF pt = data.GetPos(); - QRectF rectBB; - rectBB.setTopLeft(pt); - rectBB.setWidth(dataLabel->boundingRect().width()); - rectBB.setHeight(dataLabel->boundingRect().height()); - qreal dX; - qreal dY; - if (dataLabel->IsContained(rectBB, data.GetRotation(), dX, dY) == false) - { - pt.setX(pt.x() + dX); - pt.setY(pt.y() + dY); - } - - dataLabel->setPos(pt); - dataLabel->setRotation(data.GetRotation()); - dataLabel->Update(); - dataLabel->show(); - } - else - { - dataLabel->hide(); - } -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief UpdatePatternInfo updates the pattern info label - */ -void VToolDetail::UpdatePatternInfo() -{ - const VDetail detail = VAbstractTool::data.GetDetail(id); - const VPatternInfoGeometry& geom = detail.GetPatternInfo(); - - if (geom.IsVisible() == true) - { - QFont fnt = qApp->font(); - int iFS = geom.GetFontSize(); - if (iFS < MIN_FONT_SIZE) - { - iFS = MIN_FONT_SIZE; - } - fnt.setPixelSize(iFS); - patternInfo->SetFont(fnt); - patternInfo->SetSize(geom.GetLabelWidth(), geom.GetLabelHeight()); - patternInfo->UpdateData(doc, getData()->size(), getData()->height()); - - QPointF pt = geom.GetPos(); - QRectF rectBB; - rectBB.setTopLeft(pt); - rectBB.setWidth(patternInfo->boundingRect().width()); - rectBB.setHeight(patternInfo->boundingRect().height()); - qreal dX; - qreal dY; - if (patternInfo->IsContained(rectBB, geom.GetRotation(), dX, dY) == false) - { - pt.setX(pt.x() + dX); - pt.setY(pt.y() + dY); - } - - patternInfo->setPos(pt); - patternInfo->setRotation(geom.GetRotation()); - patternInfo->Update(); - if (patternInfo->GetTextLines() > 0) - { - patternInfo->show(); - } - else - { - patternInfo->hide(); - } - } - else - { - patternInfo->hide(); - } -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief VToolDetail::UpdateGrainline updates the grain line item - */ -void VToolDetail::UpdateGrainline() -{ - const VDetail detail = VAbstractTool::data.GetDetail(id); - const VGrainlineGeometry& geom = detail.GetGrainlineGeometry(); - - if (geom.IsVisible() == true) - { - qreal dRotation; - qreal dLength; - try - { - QString qsFormula; - qsFormula = geom.GetRotation().replace("\n", " "); - qsFormula = qApp->TrVars()->FormulaFromUser(qsFormula, qApp->Settings()->GetOsSeparator()); - - Calculator cal1; - dRotation = cal1.EvalFormula(VDataTool::data.PlainVariables(), qsFormula); - - qsFormula = geom.GetLength().replace("\n", " "); - qsFormula = qApp->TrVars()->FormulaFromUser(qsFormula, qApp->Settings()->GetOsSeparator()); - Calculator cal2; - dLength = cal2.EvalFormula(VDataTool::data.PlainVariables(), qsFormula); - } - catch(...) - { - grainLine->hide(); - return; - } - - grainLine->UpdateGeometry(geom.GetPos(), dRotation, ToPixel(dLength, *VDataTool::data.GetPatternUnit()), - geom.GetArrowType()); - grainLine->show(); - } - else - { - grainLine->hide(); - } -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief SaveMoveDetail saves the move detail operation to the undo stack - */ -void VToolDetail::SaveMoveDetail(const QPointF& ptPos) -{ - VDetail oldDet = VAbstractTool::data.GetDetail(id); - VDetail newDet = oldDet; - newDet.GetPatternPieceData().SetPos(ptPos); - newDet.GetPatternPieceData().SetLabelWidth(dataLabel->boundingRect().width()); - newDet.GetPatternPieceData().SetLabelHeight(dataLabel->boundingRect().height()); - newDet.GetPatternPieceData().SetFontSize(dataLabel->GetFontSize()); - newDet.GetPatternPieceData().SetRotation(dataLabel->rotation()); - - SaveDetailOptions* moveCommand = new SaveDetailOptions(oldDet, newDet, doc, id, this->scene()); - moveCommand->setText(tr("move pattern piece label")); - connect(moveCommand, &SaveDetailOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); - qApp->getUndoStack()->push(moveCommand); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief SaveResizeDetail saves the resize detail label operation to the undo stack - */ -void VToolDetail::SaveResizeDetail(qreal dLabelW, int iFontSize) -{ - VDetail oldDet = VAbstractTool::data.GetDetail(id); - VDetail newDet = oldDet; - newDet.GetPatternPieceData().SetLabelWidth(dLabelW); - newDet.GetPatternPieceData().SetLabelHeight(dataLabel->boundingRect().height()); - newDet.GetPatternPieceData().SetFontSize(iFontSize); - newDet.GetPatternPieceData().SetRotation(dataLabel->rotation()); - SaveDetailOptions* resizeCommand = new SaveDetailOptions(oldDet, newDet, doc, id, this->scene()); - resizeCommand->setText(tr("resize pattern piece label")); - connect(resizeCommand, &SaveDetailOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); - qApp->getUndoStack()->push(resizeCommand); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief SaveRotationDetail saves the rotation detail label operation to the undo stack - */ -void VToolDetail::SaveRotationDetail(qreal dRot) -{ - VDetail oldDet = VAbstractTool::data.GetDetail(id); - VDetail newDet = oldDet; - newDet.GetPatternPieceData().SetPos(dataLabel->pos()); - newDet.GetPatternPieceData().SetLabelWidth(dataLabel->boundingRect().width()); - newDet.GetPatternPieceData().SetLabelHeight(dataLabel->boundingRect().height()); - newDet.GetPatternPieceData().SetFontSize(dataLabel->GetFontSize()); - newDet.GetPatternPieceData().SetRotation(dRot); - - SaveDetailOptions* rotateCommand = new SaveDetailOptions(oldDet, newDet, doc, id, this->scene()); - rotateCommand->setText(tr("rotate pattern piece label")); - connect(rotateCommand, &SaveDetailOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); - qApp->getUndoStack()->push(rotateCommand); -} - - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief SaveMovePattern saves the pattern label position - */ -void VToolDetail::SaveMovePattern(const QPointF &ptPos) -{ - VDetail oldDet = VAbstractTool::data.GetDetail(id); - VDetail newDet = oldDet; - newDet.GetPatternInfo().SetPos(ptPos); - newDet.GetPatternInfo().SetLabelWidth(patternInfo->boundingRect().width()); - newDet.GetPatternInfo().SetLabelHeight(patternInfo->boundingRect().height()); - newDet.GetPatternInfo().SetFontSize(patternInfo->GetFontSize()); - newDet.GetPatternInfo().SetRotation(patternInfo->rotation()); - - SaveDetailOptions* moveCommand = new SaveDetailOptions(oldDet, newDet, doc, id, this->scene()); - moveCommand->setText(tr("move pattern info label")); - connect(moveCommand, &SaveDetailOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); - qApp->getUndoStack()->push(moveCommand); - -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief: SaveResizePattern saves the pattern label width and font size - */ -void VToolDetail::SaveResizePattern(qreal dLabelW, int iFontSize) -{ - VDetail oldDet = VAbstractTool::data.GetDetail(id); - VDetail newDet = oldDet; - newDet.GetPatternInfo().SetLabelWidth(dLabelW); - newDet.GetPatternInfo().SetLabelHeight(patternInfo->boundingRect().height()); - newDet.GetPatternInfo().SetFontSize(iFontSize); - newDet.GetPatternInfo().SetRotation(patternInfo->rotation()); - SaveDetailOptions* resizeCommand = new SaveDetailOptions(oldDet, newDet, doc, id, this->scene()); - resizeCommand->setText(tr("resize pattern info label")); - connect(resizeCommand, &SaveDetailOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); - qApp->getUndoStack()->push(resizeCommand); -} - -//--------------------------------------------------------------------------------------------------------------------- -void VToolDetail::SaveRotationPattern(qreal dRot) -{ - VDetail oldDet = VAbstractTool::data.GetDetail(id); - VDetail newDet = oldDet; - newDet.GetPatternInfo().SetPos(patternInfo->pos()); - newDet.GetPatternInfo().SetLabelWidth(patternInfo->boundingRect().width()); - newDet.GetPatternInfo().SetLabelHeight(patternInfo->boundingRect().height()); - newDet.GetPatternInfo().SetFontSize(patternInfo->GetFontSize()); - newDet.GetPatternInfo().SetRotation(dRot); - - SaveDetailOptions* rotateCommand = new SaveDetailOptions(oldDet, newDet, doc, id, this->scene()); - rotateCommand->setText(tr("rotate pattern info label")); - connect(rotateCommand, &SaveDetailOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); - qApp->getUndoStack()->push(rotateCommand); -} - - -//--------------------------------------------------------------------------------------------------------------------- -void VToolDetail::SaveMoveGrainline(const QPointF& ptPos) -{ - VDetail oldDet = VAbstractTool::data.GetDetail(id); - VDetail newDet = oldDet; - newDet.GetGrainlineGeometry().SetPos(ptPos); - qDebug() << "******* new grainline pos" << ptPos; - - SaveDetailOptions* moveCommand = new SaveDetailOptions(oldDet, newDet, doc, id, this->scene()); - moveCommand->setText(tr("move grainline")); - connect(moveCommand, &SaveDetailOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); - qApp->getUndoStack()->push(moveCommand); -} - -//--------------------------------------------------------------------------------------------------------------------- -void VToolDetail::SaveResizeGrainline(qreal dLength) -{ - VDetail oldDet = VAbstractTool::data.GetDetail(id); - VDetail newDet = oldDet; - - dLength = FromPixel(dLength, *VDataTool::data.GetPatternUnit()); - newDet.GetGrainlineGeometry().SetLength(qApp->LocaleToString(dLength)); - SaveDetailOptions* resizeCommand = new SaveDetailOptions(oldDet, newDet, doc, id, this->scene()); - resizeCommand->setText(tr("resize grainline")); - connect(resizeCommand, &SaveDetailOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); - qApp->getUndoStack()->push(resizeCommand); -} - -//--------------------------------------------------------------------------------------------------------------------- -void VToolDetail::SaveRotateGrainline(qreal dRot, const QPointF& ptPos) -{ - VDetail oldDet = VAbstractTool::data.GetDetail(id); - VDetail newDet = oldDet; - - dRot = qRadiansToDegrees(dRot); - newDet.GetGrainlineGeometry().SetRotation(qApp->LocaleToString(dRot)); - newDet.GetGrainlineGeometry().SetPos(ptPos); - SaveDetailOptions* rotateCommand = new SaveDetailOptions(oldDet, newDet, doc, id, this->scene()); - rotateCommand->setText(tr("rotate grainline")); - connect(rotateCommand, &SaveDetailOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); - qApp->getUndoStack()->push(rotateCommand); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief AddNode add node to the file. - * @param domElement tag in xml tree. - * @param node node of detail. - */ -void VToolDetail::AddNode(VAbstractPattern *doc, QDomElement &domElement, const VNodeDetail &node) -{ - QDomElement nod = doc->createElement(TagNode); - - doc->SetAttribute(nod, AttrIdObject, node.getId()); - doc->SetAttribute(nod, AttrMx, qApp->fromPixel(node.getMx())); - doc->SetAttribute(nod, AttrMy, qApp->fromPixel(node.getMy())); - - if (node.getTypeTool() != Tool::NodePoint) - { - doc->SetAttribute(nod, AttrReverse, static_cast<quint8>(node.getReverse())); - } - - if (node.getTypeNode() == NodeDetail::Contour) - { - doc->SetAttribute(nod, AttrNodeType, NodeTypeContour); - } - else - { - doc->SetAttribute(nod, AttrNodeType, NodeTypeModeling); - } - switch (node.getTypeTool()) - { - case (Tool::NodeArc): - doc->SetAttribute(nod, AttrType, NodeArc); - break; - case (Tool::NodeElArc): - doc->SetAttribute(nod, AttrType, NodeElArc); - break; - case (Tool::NodePoint): - doc->SetAttribute(nod, AttrType, NodePoint); - break; - case (Tool::NodeSpline): - doc->SetAttribute(nod, AttrType, NodeSpline); - break; - case (Tool::NodeSplinePath): - doc->SetAttribute(nod, AttrType, NodeSplinePath); - break; - default: - qDebug()<<"May be wrong tool type!!! Ignoring."<<Q_FUNC_INFO; - break; - } - domElement.appendChild(nod); -} - -//--------------------------------------------------------------------------------------------------------------------- -QString VToolDetail::getTagName() const -{ - return VAbstractPattern::TagDetail; -} - -//--------------------------------------------------------------------------------------------------------------------- -void VToolDetail::ShowVisualization(bool show) -{ - Q_UNUSED(show) -} - -//--------------------------------------------------------------------------------------------------------------------- -void VToolDetail::GroupVisibility(quint32 object, bool visible) -{ - Q_UNUSED(object) - Q_UNUSED(visible) -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief RefreshGeometry refresh item on scene. - */ -void VToolDetail::RefreshGeometry() -{ - this->setFlag(QGraphicsItem::ItemSendsGeometryChanges, false); - - const VDetail detail = VAbstractTool::data.GetDetail(id); - QPainterPath mainPath = detail.ContourPath(this->getData()); - this->setPath(mainPath); - this->setPos(detail.getMx(), detail.getMy()); - - if (detail.getSeamAllowance()) - { - mainPath.addPath(detail.SeamAllowancePath(this->getData())); - mainPath.setFillRule(Qt::OddEvenFill); - seamAllowance->setPath(mainPath); - } - else - { - seamAllowance->setPath(QPainterPath()); - } - - this->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); -} - -//--------------------------------------------------------------------------------------------------------------------- -void VToolDetail::DeleteTool(bool ask) -{ - QScopedPointer<DeleteDetail> delDet(new DeleteDetail(doc, id, VAbstractTool::data.GetDetail(id))); - if (ask) - { - if (ConfirmDeletion() == QMessageBox::No) - { - return; - } - /* If UnionDetails tool delete detail no need emit FullParsing.*/ - connect(delDet.data(), &DeleteDetail::NeedFullParsing, doc, &VAbstractPattern::NeedFullParsing); - } - qApp->getUndoStack()->push(delDet.take()); - - // Throw exception, this will help prevent case when we forget to immediately quit function. - VExceptionToolWasDeleted e("Tool was used after deleting."); - throw e; -} - -//--------------------------------------------------------------------------------------------------------------------- -template <typename Tool> -//cppcheck-suppress unusedFunction -Tool* VToolDetail::InitTool(VMainGraphicsScene *scene, const VNodeDetail &node) -{ - QHash<quint32, VDataTool*>* tools = doc->getTools(); - SCASSERT(tools != nullptr) - Tool *tool = qobject_cast<Tool*>(tools->value(node.getId())); - SCASSERT(tool != nullptr) - connect(tool, &Tool::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem); - tool->setParentItem(this); - tool->SetParentType(ParentType::Item); - doc->IncrementReferens(node.getId()); - return tool; -} - -//--------------------------------------------------------------------------------------------------------------------- -void VToolDetail::EnableToolMove(bool move) -{ - setFlag(QGraphicsItem::ItemIsMovable, move); -} - -//--------------------------------------------------------------------------------------------------------------------- -void VToolDetail::AllowHover(bool enabled) -{ - setAcceptHoverEvents(enabled); -} - -//--------------------------------------------------------------------------------------------------------------------- -void VToolDetail::AllowSelecting(bool enabled) -{ - setFlag(QGraphicsItem::ItemIsSelectable, enabled); -} - -//--------------------------------------------------------------------------------------------------------------------- -void VToolDetail::ResetChildren(QGraphicsItem *pItem) -{ - const VDetail detail = VAbstractTool::data.GetDetail(id); - VTextGraphicsItem* pVGI = dynamic_cast<VTextGraphicsItem*>(pItem); - if (pVGI != dataLabel) - { - if (detail.GetPatternPieceData().IsVisible()) - { - dataLabel->Reset(); - } - } - if (pVGI != patternInfo) - { - if (detail.GetPatternInfo().IsVisible()) - { - patternInfo->Reset(); - } - } - VGrainlineItem* pGLI = dynamic_cast<VGrainlineItem*>(pItem); - if (pGLI != grainLine) - { - if (detail.GetGrainlineGeometry().IsVisible()) - { - grainLine->Reset(); - } - } -} - -//--------------------------------------------------------------------------------------------------------------------- -void VToolDetail::UpdateAll() -{ - sceneDetails->update(); - update(); -} - -//--------------------------------------------------------------------------------------------------------------------- -void VToolDetail::retranslateUi() -{ - UpdateLabel(); - UpdatePatternInfo(); -} - -//--------------------------------------------------------------------------------------------------------------------- -void VToolDetail::Highlight(quint32 id) -{ - setSelected(this->id == id); -} diff --git a/src/libs/vtools/tools/vtooldetail.h b/src/libs/vtools/tools/vtooldetail.h deleted file mode 100644 index d46b144e6..000000000 --- a/src/libs/vtools/tools/vtooldetail.h +++ /dev/null @@ -1,164 +0,0 @@ -/************************************************************************ - ** - ** @file vtooldetail.h - ** @author Roman Telezhynskyi <dismine(at)gmail.com> - ** @date November 15, 2013 - ** - ** @brief - ** @copyright - ** This source code is part of the Valentine project, a pattern making - ** program, whose allow create and modeling patterns of clothing. - ** Copyright (C) 2013-2015 Valentina project - ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. - ** - ** Valentina is free software: you can redistribute it and/or modify - ** it under the terms of the GNU General Public License as published by - ** the Free Software Foundation, either version 3 of the License, or - ** (at your option) any later version. - ** - ** Valentina is distributed in the hope that it will be useful, - ** but WITHOUT ANY WARRANTY; without even the implied warranty of - ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - ** GNU General Public License for more details. - ** - ** You should have received a copy of the GNU General Public License - ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. - ** - *************************************************************************/ - -#ifndef VTOOLDETAIL_H -#define VTOOLDETAIL_H - -#include <qcompilerdetection.h> -#include <QObject> -#include <QtGlobal> - -#include "../vwidgets/vnobrushscalepathitem.h" -#include "vabstracttool.h" -#include "vtextgraphicsitem.h" -#include "vgrainlineitem.h" - -class VMainGraphicsScene; -class DialogTool; - -/** - * @brief The VToolDetail class for working with detail. - */ -class VToolDetail: public VAbstractTool, public VNoBrushScalePathItem -{ - Q_OBJECT -public: - ~VToolDetail(); - - virtual void setDialog(); - template<typename T> - /** - * @brief CreateNode create new node for detail. - * @param data container. - * @param id id parent object. - * @return id for new object. - */ - static quint32 CreateNode(VContainer *data, const quint32 &id) - { - //We can't use exist object. Need create new. - T *node = new T(*data->GeometricObject<T>(id).data()); - node->setMode(Draw::Modeling); - return data->AddGObject(node); - } - - static void Create(DialogTool *dialog, VMainGraphicsScene *scene, VAbstractPattern *doc, VContainer *data); - static void Create(const quint32 &_id, const VDetail &newDetail, VMainGraphicsScene *scene, - VAbstractPattern *doc, VContainer *data, const Document &parse, - const Source &typeCreation, const QString &drawName = QString()); - static const QString TagNode; - static const QString AttrSupplement; - static const QString AttrClosed; - static const QString AttrForbidFlipping; - static const QString AttrWidth; - static const QString AttrHeight; - static const QString AttrNodeType; - static const QString AttrReverse; - static const QString AttrFont; - static const QString AttrRotation; - static const QString NodeTypeContour; - static const QString NodeTypeModeling; - static const QString NodeArc; - static const QString NodeElArc; - static const QString NodePoint; - static const QString NodeSpline; - static const QString NodeSplinePath; - void Remove(bool ask); - static void AddNode(VAbstractPattern *doc, QDomElement &domElement, const VNodeDetail &node); - virtual int type() const Q_DECL_OVERRIDE {return Type;} - enum { Type = UserType + static_cast<int>(Tool::Detail)}; - virtual QString getTagName() const Q_DECL_OVERRIDE; - virtual void ShowVisualization(bool show) Q_DECL_OVERRIDE; - virtual void GroupVisibility(quint32 object, bool visible) Q_DECL_OVERRIDE; -public slots: - virtual void FullUpdateFromFile () Q_DECL_OVERRIDE; - virtual void FullUpdateFromGuiOk(int result); - void EnableToolMove(bool move); - virtual void AllowHover(bool enabled) Q_DECL_OVERRIDE; - virtual void AllowSelecting(bool enabled) Q_DECL_OVERRIDE; - virtual void ResetChildren(QGraphicsItem* pItem); - virtual void UpdateAll(); - virtual void retranslateUi(); - void Highlight(quint32 id); -protected: - virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, - QWidget *widget) Q_DECL_OVERRIDE; - virtual void AddToFile () Q_DECL_OVERRIDE; - virtual void RefreshDataInFile() Q_DECL_OVERRIDE; - virtual QVariant itemChange ( GraphicsItemChange change, const QVariant &value ) Q_DECL_OVERRIDE; - virtual void mousePressEvent( QGraphicsSceneMouseEvent * event) Q_DECL_OVERRIDE; - virtual void mouseReleaseEvent ( QGraphicsSceneMouseEvent * event ) Q_DECL_OVERRIDE; - virtual void hoverMoveEvent( QGraphicsSceneHoverEvent * event ) Q_DECL_OVERRIDE; - virtual void hoverEnterEvent ( QGraphicsSceneHoverEvent * event ) Q_DECL_OVERRIDE; - virtual void hoverLeaveEvent ( QGraphicsSceneHoverEvent * event ) Q_DECL_OVERRIDE; - virtual void contextMenuEvent ( QGraphicsSceneContextMenuEvent * event ) Q_DECL_OVERRIDE; - virtual void keyReleaseEvent(QKeyEvent * event) Q_DECL_OVERRIDE; - virtual void SetVisualization() Q_DECL_OVERRIDE {} - -protected slots: - virtual void UpdateLabel(); - virtual void UpdatePatternInfo(); - virtual void UpdateGrainline(); - virtual void SaveMoveDetail(const QPointF &ptPos); - virtual void SaveResizeDetail(qreal dLabelW, int iFontSize); - virtual void SaveRotationDetail(qreal dRot); - virtual void SaveMovePattern(const QPointF& ptPos); - virtual void SaveResizePattern(qreal dLabelW, int iFontSize); - virtual void SaveRotationPattern(qreal dRot); - virtual void SaveMoveGrainline(const QPointF& ptPos); - virtual void SaveResizeGrainline(qreal dLength); - virtual void SaveRotateGrainline(qreal dRot, const QPointF& ptPos); - -private: - Q_DISABLE_COPY(VToolDetail) - /** @brief dialog dialog options. */ - DialogTool *dialog; - - /** @brief sceneDetails pointer to the scene. */ - VMainGraphicsScene *sceneDetails; - QString drawName; - - VNoBrushScalePathItem *seamAllowance; - VTextGraphicsItem *dataLabel; - VTextGraphicsItem *patternInfo; - VGrainlineItem *grainLine; - - VToolDetail(VAbstractPattern *doc, VContainer *data, const quint32 &id, const Source &typeCreation, - VMainGraphicsScene *scene, const QString &drawName, QGraphicsItem * parent = nullptr); - - void RefreshGeometry (); - template <typename Tool> - /** - * @brief InitTool initial node item on scene - * @param scene pointer to scene. - * @param node node of detail. - */ - Tool* InitTool(VMainGraphicsScene *scene, const VNodeDetail &node); - virtual void DeleteTool(bool ask = true) Q_DECL_OVERRIDE; -}; - -#endif // VTOOLDETAIL_H diff --git a/src/libs/vtools/tools/vtoolseamallowance.cpp b/src/libs/vtools/tools/vtoolseamallowance.cpp new file mode 100644 index 000000000..7a13ae281 --- /dev/null +++ b/src/libs/vtools/tools/vtoolseamallowance.cpp @@ -0,0 +1,1211 @@ +/************************************************************************ + ** + ** @file + ** @author Roman Telezhynskyi <dismine(at)gmail.com> + ** @date 6 11, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2016 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#include "vtoolseamallowance.h" +#include "../dialogs/tools/dialogseamallowance.h" +#include "../vpatterndb/vpiecenode.h" +#include "../vpatterndb/vpiecepath.h" +#include "../vpatterndb/calculator.h" +#include "../vpatterndb/vpatterninfogeometry.h" +#include "../vpatterndb/vpatternpiecedata.h" +#include "nodeDetails/vnodearc.h" +#include "nodeDetails/vnodeellipticalarc.h" +#include "nodeDetails/vnodepoint.h" +#include "nodeDetails/vnodespline.h" +#include "nodeDetails/vnodesplinepath.h" +#include "nodeDetails/vtoolpiecepath.h" +#include "../vgeometry/varc.h" +#include "../vgeometry/vellipticalarc.h" +#include "../vgeometry/vcubicbezier.h" +#include "../vgeometry/vcubicbezierpath.h" +#include "../vgeometry/vpointf.h" +#include "../vgeometry/vspline.h" +#include "../vgeometry/vsplinepath.h" +#include "../ifc/xml/vpatternconverter.h" +#include "../undocommands/addpiece.h" +#include "../undocommands/deletepiece.h" +#include "../undocommands/movepiece.h" +#include "../undocommands/savepieceoptions.h" +#include "../undocommands/togglepieceinlayout.h" +#include "../vwidgets/vmaingraphicsview.h" +#include "../vwidgets/vnobrushscalepathitem.h" + +#include <QGraphicsSceneMouseEvent> +#include <QGraphicsView> +#include <QKeyEvent> +#include <QMenu> +#include <QMessageBox> + +// Current version of seam allowance tag nned for backward compatibility +const quint8 VToolSeamAllowance::pieceVersion = 2; + +const QString VToolSeamAllowance::TagCSA = QStringLiteral("csa"); +const QString VToolSeamAllowance::TagRecord = QStringLiteral("record"); +const QString VToolSeamAllowance::TagIPaths = QStringLiteral("iPaths"); + +const QString VToolSeamAllowance::AttrVersion = QStringLiteral("version"); +const QString VToolSeamAllowance::AttrForbidFlipping = QStringLiteral("forbidFlipping"); +const QString VToolSeamAllowance::AttrSeamAllowance = QStringLiteral("seamAllowance"); +const QString VToolSeamAllowance::AttrHeight = QStringLiteral("height"); +const QString VToolSeamAllowance::AttrUnited = QStringLiteral("united"); +const QString VToolSeamAllowance::AttrFont = QStringLiteral("fontSize"); + +//--------------------------------------------------------------------------------------------------------------------- +VToolSeamAllowance::~VToolSeamAllowance() +{ + delete m_dialog; +} + +//--------------------------------------------------------------------------------------------------------------------- +VToolSeamAllowance *VToolSeamAllowance::Create(DialogTool *dialog, VMainGraphicsScene *scene, VAbstractPattern *doc, + VContainer *data) +{ + SCASSERT(dialog != nullptr); + DialogSeamAllowance *dialogTool = qobject_cast<DialogSeamAllowance*>(dialog); + SCASSERT(dialogTool != nullptr); + VPiece detail = dialogTool->GetPiece(); + QString width = detail.GetFormulaSAWidth(); + qApp->getUndoStack()->beginMacro("add detail"); + detail.GetPath().SetNodes(PrepareNodes(detail.GetPath(), scene, doc, data)); + + VToolSeamAllowance *piece = Create(0, detail, width, scene, doc, data, Document::FullParse, Source::FromGui); + + if (piece != nullptr) + { + piece->m_dialog = dialogTool; + } + return piece; +} + +//--------------------------------------------------------------------------------------------------------------------- +VToolSeamAllowance *VToolSeamAllowance::Create(quint32 id, VPiece newPiece, QString &width, VMainGraphicsScene *scene, + VAbstractPattern *doc, VContainer *data, const Document &parse, + const Source &typeCreation, const QString &drawName) +{ + if (typeCreation == Source::FromGui || typeCreation == Source::FromTool) + { + data->AddVariable(currentSeamAllowance, new VIncrement(data, currentSeamAllowance, 0, newPiece.GetSAWidth(), + width, true, tr("Current seam allowance"))); + id = data->AddPiece(newPiece); + } + else + { + const qreal calcWidth = CheckFormula(id, width, data); + newPiece.SetFormulaSAWidth(width, calcWidth); + + data->AddVariable(currentSeamAllowance, new VIncrement(data, currentSeamAllowance, 0, calcWidth, + width, true, tr("Current seam allowance"))); + + data->UpdatePiece(id, newPiece); + if (parse != Document::FullParse) + { + doc->UpdateToolData(id, data); + } + } + VAbstractTool::AddRecord(id, Tool::Piece, doc); + VToolSeamAllowance *piece = nullptr; + if (parse == Document::FullParse) + { + piece = new VToolSeamAllowance(doc, data, id, typeCreation, scene, drawName); + scene->addItem(piece); + connect(piece, &VToolSeamAllowance::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem); + connect(scene, &VMainGraphicsScene::EnableDetailItemHover, piece, &VToolSeamAllowance::AllowHover); + connect(scene, &VMainGraphicsScene::EnableDetailItemSelection, piece, &VToolSeamAllowance::AllowSelecting); + connect(scene, &VMainGraphicsScene::HighlightDetail, piece, &VToolSeamAllowance::Highlight); + doc->AddTool(id, piece); + } + //Very important to delete it. Only this tool need this special variable. + data->RemoveVariable(currentLength); + return piece; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::Remove(bool ask) +{ + try + { + DeleteTool(ask); + } + catch(const VExceptionToolWasDeleted &e) + { + Q_UNUSED(e); + return;//Leave this method immediately!!! + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::AddAttributes(VAbstractPattern *doc, QDomElement &domElement, quint32 id, const VPiece &piece) +{ + SCASSERT(doc != nullptr); + + doc->SetAttribute(domElement, VDomDocument::AttrId, id); + doc->SetAttribute(domElement, AttrName, piece.GetName()); + doc->SetAttribute(domElement, AttrVersion, QString().setNum(pieceVersion)); + doc->SetAttribute(domElement, AttrMx, qApp->fromPixel(piece.GetMx())); + doc->SetAttribute(domElement, AttrMy, qApp->fromPixel(piece.GetMy())); + doc->SetAttribute(domElement, AttrInLayout, piece.IsInLayout()); + doc->SetAttribute(domElement, AttrForbidFlipping, piece.IsForbidFlipping()); + doc->SetAttribute(domElement, AttrSeamAllowance, piece.IsSeamAllowance()); + doc->SetAttribute(domElement, VAbstractPattern::AttrWidth, piece.GetFormulaSAWidth()); + doc->SetAttribute(domElement, AttrUnited, piece.IsUnited()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::AddCSARecord(VAbstractPattern *doc, QDomElement &domElement, const CustomSARecord &record) +{ + QDomElement recordNode = doc->createElement(VToolSeamAllowance::TagRecord); + + doc->SetAttribute(recordNode, VAbstractPattern::AttrStart, record.startPoint); + doc->SetAttribute(recordNode, VAbstractPattern::AttrPath, record.path); + doc->SetAttribute(recordNode, VAbstractPattern::AttrEnd, record.endPoint); + doc->SetAttribute(recordNode, VAbstractPattern::AttrNodeReverse, record.reverse); + doc->SetAttribute(recordNode, VAbstractPattern::AttrIncludeAs, static_cast<unsigned int>(record.includeType)); + + domElement.appendChild(recordNode); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::AddCSARecords(VAbstractPattern *doc, QDomElement &domElement, + const QVector<CustomSARecord> &records) +{ + if (records.size() > 0) + { + QDomElement csaRecordsElement = doc->createElement(VToolSeamAllowance::TagCSA); + for (int i = 0; i < records.size(); ++i) + { + AddCSARecord(doc, csaRecordsElement, records.at(i)); + } + domElement.appendChild(csaRecordsElement); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::AddInternalPaths(VAbstractPattern *doc, QDomElement &domElement, const QVector<quint32> &paths) +{ + if (paths.size() > 0) + { + QDomElement iPathsElement = doc->createElement(VToolSeamAllowance::TagIPaths); + for (int i = 0; i < paths.size(); ++i) + { + QDomElement recordNode = doc->createElement(VToolSeamAllowance::TagRecord); + doc->SetAttribute(recordNode, VAbstractPattern::AttrPath, paths.at(i)); + iPathsElement.appendChild(recordNode); + } + domElement.appendChild(iPathsElement); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::AddPatternPieceData(VAbstractPattern *doc, QDomElement &domElement, const VPiece &piece) +{ + QDomElement domData = doc->createElement(VAbstractPattern::TagData); + const VPatternPieceData& data = piece.GetPatternPieceData(); + doc->SetAttribute(domData, VAbstractPattern::AttrLetter, data.GetLetter()); + doc->SetAttribute(domData, VAbstractPattern::AttrVisible, data.IsVisible() == true? trueStr : falseStr); + doc->SetAttribute(domData, AttrMx, data.GetPos().x()); + doc->SetAttribute(domData, AttrMy, data.GetPos().y()); + doc->SetAttribute(domData, VAbstractPattern::AttrWidth, data.GetLabelWidth()); + doc->SetAttribute(domData, AttrHeight, data.GetLabelHeight()); + doc->SetAttribute(domData, AttrFont, data.GetFontSize()); + doc->SetAttribute(domData, VAbstractPattern::AttrRotation, data.GetRotation()); + + for (int i = 0; i < data.GetMCPCount(); ++i) + { + const MaterialCutPlacement mcp = data.GetMCP(i); + QDomElement domMCP = doc->createElement(VAbstractPattern::TagMCP); + doc->SetAttribute(domMCP, VAbstractPattern::AttrMaterial, int(mcp.m_eMaterial)); + if (mcp.m_eMaterial == MaterialType::mtUserDefined) + { + doc->SetAttribute(domMCP, VAbstractPattern::AttrUserDefined, mcp.m_qsMaterialUserDef); + } + doc->SetAttribute(domMCP, VAbstractPattern::AttrCutNumber, mcp.m_iCutNumber); + doc->SetAttribute(domMCP, VAbstractPattern::AttrPlacement, int(mcp.m_ePlacement)); + domData.appendChild(domMCP); + } + domElement.appendChild(domData); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::AddPatternInfo(VAbstractPattern *doc, QDomElement &domElement, const VPiece &piece) +{ + QDomElement domData = doc->createElement(VAbstractPattern::TagPatternInfo); + const VPatternInfoGeometry& geom = piece.GetPatternInfo(); + doc->SetAttribute(domData, VAbstractPattern::AttrVisible, geom.IsVisible() == true ? trueStr : falseStr); + doc->SetAttribute(domData, AttrMx, geom.GetPos().x()); + doc->SetAttribute(domData, AttrMy, geom.GetPos().y()); + doc->SetAttribute(domData, VAbstractPattern::AttrWidth, geom.GetLabelWidth()); + doc->SetAttribute(domData, AttrHeight, geom.GetLabelHeight()); + doc->SetAttribute(domData, AttrFont, geom.GetFontSize()); + doc->SetAttribute(domData, VAbstractPattern::AttrRotation, geom.GetRotation()); + domElement.appendChild(domData); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::AddGrainline(VAbstractPattern *doc, QDomElement &domElement, const VPiece &piece) +{ + // grainline + QDomElement domData = doc->createElement(VAbstractPattern::TagGrainline); + const VGrainlineGeometry& glGeom = piece.GetGrainlineGeometry(); + doc->SetAttribute(domData, VAbstractPattern::AttrVisible, glGeom.IsVisible() == true ? trueStr : falseStr); + doc->SetAttribute(domData, AttrMx, glGeom.GetPos().x()); + doc->SetAttribute(domData, AttrMy, glGeom.GetPos().y()); + doc->SetAttribute(domData, AttrLength, glGeom.GetLength()); + doc->SetAttribute(domData, VAbstractPattern::AttrRotation, glGeom.GetRotation()); + doc->SetAttribute(domData, VAbstractPattern::AttrArrows, int(glGeom.GetArrowType())); + domElement.appendChild(domData); +} + +//--------------------------------------------------------------------------------------------------------------------- +QString VToolSeamAllowance::getTagName() const +{ + return VAbstractPattern::TagDetail; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::ShowVisualization(bool show) +{ + Q_UNUSED(show) +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::GroupVisibility(quint32 object, bool visible) +{ + Q_UNUSED(object); + Q_UNUSED(visible); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::FullUpdateFromFile() +{ + RefreshGeometry(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::FullUpdateFromGuiOk(int result) +{ + if (result == QDialog::Accepted) + { + SaveDialogChange(); + } + delete m_dialog; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::FullUpdateFromGuiApply() +{ + SaveDialogChange(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::EnableToolMove(bool move) +{ + setFlag(QGraphicsItem::ItemIsMovable, move); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::AllowHover(bool enabled) +{ + setAcceptHoverEvents(enabled); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::AllowSelecting(bool enabled) +{ + setFlag(QGraphicsItem::ItemIsSelectable, enabled); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::ResetChildren(QGraphicsItem *pItem) +{ + const VPiece detail = VAbstractTool::data.GetPiece(id); + VTextGraphicsItem* pVGI = qgraphicsitem_cast<VTextGraphicsItem*>(pItem); + if (pVGI != m_dataLabel) + { + if (detail.GetPatternPieceData().IsVisible()) + { + m_dataLabel->Reset(); + } + } + if (pVGI != m_patternInfo) + { + if (detail.GetPatternInfo().IsVisible()) + { + m_patternInfo->Reset(); + } + } + VGrainlineItem* pGLI = qgraphicsitem_cast<VGrainlineItem*>(pItem); + if (pGLI != m_grainLine) + { + if (detail.GetGrainlineGeometry().IsVisible()) + { + m_grainLine->Reset(); + } + } + + update(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::UpdateAll() +{ + m_sceneDetails->update(); + update(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::retranslateUi() +{ + UpdateLabel(); + UpdatePatternInfo(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::Highlight(quint32 id) +{ + setSelected(this->id == id); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief UpdateLabel updates the text label, making it just big enough for the text to fit it + */ +void VToolSeamAllowance::UpdateLabel() +{ + const VPiece detail = VAbstractTool::data.GetPiece(id); + const VPatternPieceData& data = detail.GetPatternPieceData(); + + if (data.IsVisible() == true) + { + QFont fnt = qApp->font(); + { + const int iFS = data.GetFontSize(); + iFS < MIN_FONT_SIZE ? fnt.setPixelSize(MIN_FONT_SIZE) : fnt.setPixelSize(iFS); + } + m_dataLabel->SetFont(fnt); + m_dataLabel->SetSize(data.GetLabelWidth(), data.GetLabelHeight()); + m_dataLabel->UpdateData(detail.GetName(), data); + QPointF pt = data.GetPos(); + QRectF rectBB; + rectBB.setTopLeft(pt); + rectBB.setWidth(m_dataLabel->boundingRect().width()); + rectBB.setHeight(m_dataLabel->boundingRect().height()); + qreal dX; + qreal dY; + if (m_dataLabel->IsContained(rectBB, data.GetRotation(), dX, dY) == false) + { + pt.setX(pt.x() + dX); + pt.setY(pt.y() + dY); + } + + m_dataLabel->setPos(pt); + m_dataLabel->setRotation(data.GetRotation()); + m_dataLabel->Update(); + m_dataLabel->show(); + } + else + { + m_dataLabel->hide(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief UpdatePatternInfo updates the pattern info label + */ +void VToolSeamAllowance::UpdatePatternInfo() +{ + const VPiece detail = VAbstractTool::data.GetPiece(id); + const VPatternInfoGeometry& geom = detail.GetPatternInfo(); + + if (geom.IsVisible() == true) + { + QFont fnt = qApp->font(); + int iFS = geom.GetFontSize(); + if (iFS < MIN_FONT_SIZE) + { + iFS = MIN_FONT_SIZE; + } + fnt.setPixelSize(iFS); + m_patternInfo->SetFont(fnt); + m_patternInfo->SetSize(geom.GetLabelWidth(), geom.GetLabelHeight()); + m_patternInfo->UpdateData(doc, getData()->size(), getData()->height()); + + QPointF pt = geom.GetPos(); + QRectF rectBB; + rectBB.setTopLeft(pt); + rectBB.setWidth(m_patternInfo->boundingRect().width()); + rectBB.setHeight(m_patternInfo->boundingRect().height()); + qreal dX; + qreal dY; + if (m_patternInfo->IsContained(rectBB, geom.GetRotation(), dX, dY) == false) + { + pt.setX(pt.x() + dX); + pt.setY(pt.y() + dY); + } + + m_patternInfo->setPos(pt); + m_patternInfo->setRotation(geom.GetRotation()); + m_patternInfo->Update(); + m_patternInfo->GetTextLines() > 0 ? m_patternInfo->show() : m_patternInfo->hide(); + } + else + { + m_patternInfo->hide(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VToolDetail::UpdateGrainline updates the grain line item + */ +void VToolSeamAllowance::UpdateGrainline() +{ + const VPiece detail = VAbstractTool::data.GetPiece(id); + const VGrainlineGeometry& geom = detail.GetGrainlineGeometry(); + + if (geom.IsVisible() == true) + { + qreal dRotation; + qreal dLength; + try + { + QString qsFormula; + qsFormula = geom.GetRotation().replace("\n", " "); + qsFormula = qApp->TrVars()->FormulaFromUser(qsFormula, qApp->Settings()->GetOsSeparator()); + + Calculator cal1; + dRotation = cal1.EvalFormula(VDataTool::data.PlainVariables(), qsFormula); + + qsFormula = geom.GetLength().replace("\n", " "); + qsFormula = qApp->TrVars()->FormulaFromUser(qsFormula, qApp->Settings()->GetOsSeparator()); + Calculator cal2; + dLength = cal2.EvalFormula(VDataTool::data.PlainVariables(), qsFormula); + } + catch(...) + { + m_grainLine->hide(); + return; + } + + m_grainLine->UpdateGeometry(geom.GetPos(), dRotation, ToPixel(dLength, *VDataTool::data.GetPatternUnit()), + geom.GetArrowType()); + m_grainLine->show(); + } + else + { + m_grainLine->hide(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief SaveMoveDetail saves the move detail operation to the undo stack + */ +void VToolSeamAllowance::SaveMoveDetail(const QPointF& ptPos) +{ + VPiece oldDet = VAbstractTool::data.GetPiece(id); + VPiece newDet = oldDet; + newDet.GetPatternPieceData().SetPos(ptPos); + newDet.GetPatternPieceData().SetLabelWidth(m_dataLabel->boundingRect().width()); + newDet.GetPatternPieceData().SetLabelHeight(m_dataLabel->boundingRect().height()); + newDet.GetPatternPieceData().SetFontSize(m_dataLabel->GetFontSize()); + newDet.GetPatternPieceData().SetRotation(m_dataLabel->rotation()); + + SavePieceOptions* moveCommand = new SavePieceOptions(oldDet, newDet, doc, id); + moveCommand->setText(tr("move pattern piece label")); + connect(moveCommand, &SavePieceOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); + qApp->getUndoStack()->push(moveCommand); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief SaveResizeDetail saves the resize detail label operation to the undo stack + */ +void VToolSeamAllowance::SaveResizeDetail(qreal dLabelW, int iFontSize) +{ + VPiece oldDet = VAbstractTool::data.GetPiece(id); + VPiece newDet = oldDet; + newDet.GetPatternPieceData().SetLabelWidth(dLabelW); + newDet.GetPatternPieceData().SetLabelHeight(m_dataLabel->boundingRect().height()); + newDet.GetPatternPieceData().SetFontSize(iFontSize); + newDet.GetPatternPieceData().SetRotation(m_dataLabel->rotation()); + SavePieceOptions* resizeCommand = new SavePieceOptions(oldDet, newDet, doc, id); + resizeCommand->setText(tr("resize pattern piece label")); + connect(resizeCommand, &SavePieceOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); + qApp->getUndoStack()->push(resizeCommand); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief SaveRotationDetail saves the rotation detail label operation to the undo stack + */ +void VToolSeamAllowance::SaveRotationDetail(qreal dRot) +{ + VPiece oldDet = VAbstractTool::data.GetPiece(id); + VPiece newDet = oldDet; + newDet.GetPatternPieceData().SetPos(m_dataLabel->pos()); + newDet.GetPatternPieceData().SetLabelWidth(m_dataLabel->boundingRect().width()); + newDet.GetPatternPieceData().SetLabelHeight(m_dataLabel->boundingRect().height()); + newDet.GetPatternPieceData().SetFontSize(m_dataLabel->GetFontSize()); + newDet.GetPatternPieceData().SetRotation(dRot); + + SavePieceOptions* rotateCommand = new SavePieceOptions(oldDet, newDet, doc, id); + rotateCommand->setText(tr("rotate pattern piece label")); + connect(rotateCommand, &SavePieceOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); + qApp->getUndoStack()->push(rotateCommand); +} + + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief SaveMovePattern saves the pattern label position + */ +void VToolSeamAllowance::SaveMovePattern(const QPointF &ptPos) +{ + VPiece oldDet = VAbstractTool::data.GetPiece(id); + VPiece newDet = oldDet; + newDet.GetPatternInfo().SetPos(ptPos); + newDet.GetPatternInfo().SetLabelWidth(m_patternInfo->boundingRect().width()); + newDet.GetPatternInfo().SetLabelHeight(m_patternInfo->boundingRect().height()); + newDet.GetPatternInfo().SetFontSize(m_patternInfo->GetFontSize()); + newDet.GetPatternInfo().SetRotation(m_patternInfo->rotation()); + + SavePieceOptions* moveCommand = new SavePieceOptions(oldDet, newDet, doc, id); + moveCommand->setText(tr("move pattern info label")); + connect(moveCommand, &SavePieceOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); + qApp->getUndoStack()->push(moveCommand); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief: SaveResizePattern saves the pattern label width and font size + */ +void VToolSeamAllowance::SaveResizePattern(qreal dLabelW, int iFontSize) +{ + VPiece oldDet = VAbstractTool::data.GetPiece(id); + VPiece newDet = oldDet; + newDet.GetPatternInfo().SetLabelWidth(dLabelW); + newDet.GetPatternInfo().SetLabelHeight(m_patternInfo->boundingRect().height()); + newDet.GetPatternInfo().SetFontSize(iFontSize); + newDet.GetPatternInfo().SetRotation(m_patternInfo->rotation()); + SavePieceOptions* resizeCommand = new SavePieceOptions(oldDet, newDet, doc, id); + resizeCommand->setText(tr("resize pattern info label")); + connect(resizeCommand, &SavePieceOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); + qApp->getUndoStack()->push(resizeCommand); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::SaveRotationPattern(qreal dRot) +{ + VPiece oldDet = VAbstractTool::data.GetPiece(id); + VPiece newDet = oldDet; + newDet.GetPatternInfo().SetPos(m_patternInfo->pos()); + newDet.GetPatternInfo().SetLabelWidth(m_patternInfo->boundingRect().width()); + newDet.GetPatternInfo().SetLabelHeight(m_patternInfo->boundingRect().height()); + newDet.GetPatternInfo().SetFontSize(m_patternInfo->GetFontSize()); + newDet.GetPatternInfo().SetRotation(dRot); + + SavePieceOptions* rotateCommand = new SavePieceOptions(oldDet, newDet, doc, id); + rotateCommand->setText(tr("rotate pattern info label")); + connect(rotateCommand, &SavePieceOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); + qApp->getUndoStack()->push(rotateCommand); +} + + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::SaveMoveGrainline(const QPointF& ptPos) +{ + VPiece oldDet = VAbstractTool::data.GetPiece(id); + VPiece newDet = oldDet; + newDet.GetGrainlineGeometry().SetPos(ptPos); + qDebug() << "******* new grainline pos" << ptPos; + + SavePieceOptions* moveCommand = new SavePieceOptions(oldDet, newDet, doc, id); + moveCommand->setText(tr("move grainline")); + connect(moveCommand, &SavePieceOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); + qApp->getUndoStack()->push(moveCommand); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::SaveResizeGrainline(qreal dLength) +{ + VPiece oldDet = VAbstractTool::data.GetPiece(id); + VPiece newDet = oldDet; + + dLength = FromPixel(dLength, *VDataTool::data.GetPatternUnit()); + newDet.GetGrainlineGeometry().SetLength(qApp->LocaleToString(dLength)); + SavePieceOptions* resizeCommand = new SavePieceOptions(oldDet, newDet, doc, id); + resizeCommand->setText(tr("resize grainline")); + connect(resizeCommand, &SavePieceOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); + qApp->getUndoStack()->push(resizeCommand); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::SaveRotateGrainline(qreal dRot, const QPointF& ptPos) +{ + VPiece oldDet = VAbstractTool::data.GetPiece(id); + VPiece newDet = oldDet; + + dRot = qRadiansToDegrees(dRot); + newDet.GetGrainlineGeometry().SetRotation(qApp->LocaleToString(dRot)); + newDet.GetGrainlineGeometry().SetPos(ptPos); + SavePieceOptions* rotateCommand = new SavePieceOptions(oldDet, newDet, doc, id); + rotateCommand->setText(tr("rotate grainline")); + connect(rotateCommand, &SavePieceOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); + qApp->getUndoStack()->push(rotateCommand); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VToolDetail::paint draws a bounding box around detail, if one of its text or grainline items is not idle. + */ +void VToolSeamAllowance::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + if (scene()->views().count() > 0) + { + const QPoint pt0 = scene()->views().at(0)->mapFromScene(0, 0); + const QPoint pt = scene()->views().at(0)->mapFromScene(0, 100); + + const QPoint p = pt - pt0; + +#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) + const qreal dScale = qSqrt(QPoint::dotProduct(p, p)); +#else + const qreal dScale = qSqrt(p.x() * p.x() + p.y() * p.y()); +#endif //QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) + m_grainLine->SetScale(100/dScale); + } + + if (m_dataLabel->IsIdle() == false || m_patternInfo->IsIdle() == false || m_grainLine->IsIdle() == false) + { + painter->save(); + painter->setPen(QPen(Qt::black, 3, Qt::DashLine)); + painter->drawRect(boundingRect().adjusted(1, 1, -1, -1)); + painter->restore(); + } + QGraphicsPathItem::paint(painter, option, widget); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::AddToFile() +{ + const VPiece piece = VAbstractTool::data.GetPiece(id); + + QDomElement domElement = doc->createElement(getTagName()); + + AddAttributes(doc, domElement, id, piece); + AddPatternPieceData(doc, domElement, piece); + AddPatternInfo(doc, domElement, piece); + AddGrainline(doc, domElement, piece); + + // nodes + AddNodes(doc, domElement, piece); + //custom seam allowance + AddCSARecords(doc, domElement, piece.GetCustomSARecords()); + AddInternalPaths(doc, domElement, piece.GetInternalPaths()); + + AddPiece *addDet = new AddPiece(domElement, doc, piece, m_drawName); + connect(addDet, &AddPiece::NeedFullParsing, doc, &VAbstractPattern::NeedFullParsing); + qApp->getUndoStack()->push(addDet); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::RefreshDataInFile() +{ + QDomElement domElement = doc->elementById(id); + if (domElement.isElement()) + { + // Refresh only parts that we possibly need to update + { + // TODO. Delete if minimal supported version is 0.4.0 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 4, 0), + "Time to refactor the code."); + + const uint version = doc->GetParametrUInt(domElement, VToolSeamAllowance::AttrVersion, "1"); + if (version == 1) + { + const VPiece piece = VAbstractTool::data.GetPiece(id); + + doc->SetAttribute(domElement, AttrVersion, QString().setNum(pieceVersion)); + + doc->RemoveAllChildren(domElement);//Very important to clear before rewrite + AddPatternPieceData(doc, domElement, piece); + AddPatternInfo(doc, domElement, piece); + AddGrainline(doc, domElement, piece); + AddNodes(doc, domElement, piece); + AddCSARecords(doc, domElement, piece.GetCustomSARecords()); + AddInternalPaths(doc, domElement, piece.GetInternalPaths()); + } + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +QVariant VToolSeamAllowance::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) +{ + if (change == ItemPositionChange && scene()) + { + // Each time we move something we call recalculation scene rect. In some cases this can cause moving + // objects positions. And this cause infinite redrawing. That's why we wait the finish of saving the last move. + static bool changeFinished = true; + if (changeFinished) + { + changeFinished = false; + + // value - this is new position. + const QPointF newPos = value.toPointF(); + + MovePiece *moveDet = new MovePiece(doc, newPos.x(), newPos.y(), id, scene()); + connect(moveDet, &MovePiece::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); + qApp->getUndoStack()->push(moveDet); + + const QList<QGraphicsView *> viewList = scene()->views(); + if (not viewList.isEmpty()) + { + if (QGraphicsView *view = viewList.at(0)) + { + const int xmargin = 50; + const int ymargin = 50; + + const QRectF viewRect = VMainGraphicsView::SceneVisibleArea(view); + const QRectF itemRect = mapToScene(boundingRect()|childrenBoundingRect()).boundingRect(); + + // If item's rect is bigger than view's rect ensureVisible works very unstable. + if (itemRect.height() + 2*ymargin < viewRect.height() && + itemRect.width() + 2*xmargin < viewRect.width()) + { + view->ensureVisible(itemRect, xmargin, ymargin); + } + else + { + // Ensure visible only small rect around a cursor + VMainGraphicsScene *currentScene = qobject_cast<VMainGraphicsScene *>(scene()); + SCASSERT(currentScene); + const QPointF cursorPosition = currentScene->getScenePos(); + view->ensureVisible(QRectF(cursorPosition.x()-5, cursorPosition.y()-5, 10, 10)); + } + } + } + // Don't forget to update geometry, because first change never call full parse + VPiece detail = VAbstractTool::data.GetPiece(id); + detail.SetMx(newPos.x()); + detail.SetMy(newPos.y()); + VAbstractTool::data.UpdatePiece(id, detail); + + RefreshGeometry(); + changeFinished = true; + } + } + + if (change == QGraphicsItem::ItemSelectedChange) + { + if (value == true) + { + // do stuff if selected + this->setFocus(); + } + else + { + // do stuff if not selected + } + } + + return QGraphicsPathItem::itemChange(change, value); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + // Special for not selectable item first need to call standard mousePressEvent then accept event + QGraphicsPathItem::mousePressEvent(event); + + // Somehow clicking on notselectable object do not clean previous selections. + if (not (flags() & ItemIsSelectable) && scene()) + { + scene()->clearSelection(); + } + + if (flags() & QGraphicsItem::ItemIsMovable) + { + if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick) + { + SetOverrideCursor(cursorArrowCloseHand, 1, 1); + } + } + + if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick) + { + doc->SelectedDetail(id); + emit ChoosedTool(id, SceneObject::Detail); + } + + event->accept();// Special for not selectable item first need to call standard mousePressEvent then accept event +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) + { + //Disable cursor-arrow-closehand + RestoreOverrideCursor(cursorArrowCloseHand); + } + QGraphicsPathItem::mouseReleaseEvent(event); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::hoverMoveEvent(QGraphicsSceneHoverEvent *event) +{ + Q_UNUSED(event); + if (flags() & QGraphicsItem::ItemIsMovable) + { + SetOverrideCursor(cursorArrowOpenHand, 1, 1); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::hoverEnterEvent(QGraphicsSceneHoverEvent *event) +{ + Q_UNUSED(event); + if (flags() & QGraphicsItem::ItemIsMovable) + { + SetOverrideCursor(cursorArrowOpenHand, 1, 1); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) +{ + Q_UNUSED(event); + //Disable cursor-arrow-openhand + if (flags() & QGraphicsItem::ItemIsMovable) + { + RestoreOverrideCursor(cursorArrowOpenHand); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) +{ + QMenu menu; + QAction *actionOption = menu.addAction(QIcon::fromTheme("preferences-other"), tr("Options")); + + QAction *inLayoutOption = menu.addAction(tr("In layout")); + inLayoutOption->setCheckable(true); + const VPiece detail = VAbstractTool::data.GetPiece(id); + inLayoutOption->setChecked(detail.IsInLayout()); + + QAction *actionRemove = menu.addAction(QIcon::fromTheme("edit-delete"), tr("Delete")); + _referens > 1 ? actionRemove->setEnabled(false) : actionRemove->setEnabled(true); + + QAction *selectedAction = menu.exec(event->screenPos()); + if (selectedAction == actionOption) + { + auto *dialog = new DialogSeamAllowance(getData(), id, qApp->getMainWindow()); + dialog->EnableApply(true); + m_dialog = dialog; + m_dialog->setModal(true); + connect(m_dialog.data(), &DialogTool::DialogClosed, this, &VToolSeamAllowance::FullUpdateFromGuiOk); + connect(m_dialog.data(), &DialogTool::DialogApplied, this, &VToolSeamAllowance::FullUpdateFromGuiApply); + SetDialog(); + m_dialog->show(); + } + else if (selectedAction == inLayoutOption) + { + TogglePieceInLayout *togglePrint = new TogglePieceInLayout(id, selectedAction->isChecked(), + &(VAbstractTool::data), doc); + connect(togglePrint, &TogglePieceInLayout::UpdateList, doc, &VAbstractPattern::CheckInLayoutList); + qApp->getUndoStack()->push(togglePrint); + } + else if (selectedAction == actionRemove) + { + try + { + DeleteTool(); + } + catch(const VExceptionToolWasDeleted &e) + { + Q_UNUSED(e); + return;//Leave this method immediately!!! + } + return; //Leave this method immediately after call!!! + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::keyReleaseEvent(QKeyEvent *event) +{ + switch (event->key()) + { + case Qt::Key_Delete: + try + { + DeleteTool(); + } + catch(const VExceptionToolWasDeleted &e) + { + Q_UNUSED(e); + return;//Leave this method immediately!!! + } + break; + default: + break; + } + + QGraphicsPathItem::keyReleaseEvent ( event ); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::SetDialog() +{ + SCASSERT(not m_dialog.isNull()); + DialogSeamAllowance *dialogTool = qobject_cast<DialogSeamAllowance*>(m_dialog); + SCASSERT(dialogTool != nullptr); + dialogTool->SetPiece(VAbstractTool::data.GetPiece(id)); + dialogTool->EnableApply(true); +} + +//--------------------------------------------------------------------------------------------------------------------- +VToolSeamAllowance::VToolSeamAllowance(VAbstractPattern *doc, VContainer *data, const quint32 &id, + const Source &typeCreation, VMainGraphicsScene *scene, + const QString &drawName, QGraphicsItem *parent) + : VAbstractTool(doc, data, id), + QGraphicsPathItem(parent), + m_dialog(), + m_sceneDetails(scene), + m_drawName(drawName), + m_seamAllowance(new VNoBrushScalePathItem(this)), + m_dataLabel(new VTextGraphicsItem(this)), + m_patternInfo(new VTextGraphicsItem(this)), + m_grainLine(new VGrainlineItem(this)) +{ + VPiece detail = data->GetPiece(id); + InitNodes(detail, scene); + InitCSAPaths(detail); + InitInternalPaths(detail); + this->setFlag(QGraphicsItem::ItemIsMovable, true); + this->setFlag(QGraphicsItem::ItemIsSelectable, true); + RefreshGeometry(); + + m_seamAllowance->setBrush(QBrush(Qt::FDiagPattern)); + + this->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); + this->setFlag(QGraphicsItem::ItemIsFocusable, true);// For keyboard input focus + + connect(scene, &VMainGraphicsScene::EnableToolMove, this, &VToolSeamAllowance::EnableToolMove); + connect(scene, &VMainGraphicsScene::ItemClicked, this, &VToolSeamAllowance::ResetChildren); + ToolCreation(typeCreation); + setAcceptHoverEvents(true); + + connect(m_dataLabel, &VTextGraphicsItem::SignalMoved, this, &VToolSeamAllowance::SaveMoveDetail); + connect(m_dataLabel, &VTextGraphicsItem::SignalResized, this, &VToolSeamAllowance::SaveResizeDetail); + connect(m_dataLabel, &VTextGraphicsItem::SignalRotated, this, &VToolSeamAllowance::SaveRotationDetail); + + connect(m_patternInfo, &VTextGraphicsItem::SignalMoved, this, &VToolSeamAllowance::SaveMovePattern); + connect(m_patternInfo, &VTextGraphicsItem::SignalResized, this, &VToolSeamAllowance::SaveResizePattern); + connect(m_patternInfo, &VTextGraphicsItem::SignalRotated, this, &VToolSeamAllowance::SaveRotationPattern); + + connect(m_grainLine, &VGrainlineItem::SignalMoved, this, &VToolSeamAllowance::SaveMoveGrainline); + connect(m_grainLine, &VGrainlineItem::SignalResized, this, &VToolSeamAllowance::SaveResizeGrainline); + connect(m_grainLine, &VGrainlineItem::SignalRotated, this, &VToolSeamAllowance::SaveRotateGrainline); + + connect(doc, &VAbstractPattern::patternChanged, this, &VToolSeamAllowance::UpdatePatternInfo); + connect(doc, &VAbstractPattern::CheckLayout, this, &VToolSeamAllowance::UpdateLabel); + connect(doc, &VAbstractPattern::CheckLayout, this, &VToolSeamAllowance::UpdatePatternInfo); + connect(doc, &VAbstractPattern::CheckLayout, this, &VToolSeamAllowance::UpdateGrainline); + + connect(m_sceneDetails, &VMainGraphicsScene::DimensionsChanged, this, &VToolSeamAllowance::UpdateLabel); + connect(m_sceneDetails, &VMainGraphicsScene::DimensionsChanged, this, &VToolSeamAllowance::UpdatePatternInfo); + connect(m_sceneDetails, &VMainGraphicsScene::LanguageChanged, this, &VToolSeamAllowance::retranslateUi); + + UpdateLabel(); + UpdatePatternInfo(); + UpdateGrainline(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::RefreshGeometry() +{ + this->setFlag(QGraphicsItem::ItemSendsGeometryChanges, false); + + const VPiece detail = VAbstractTool::data.GetPiece(id); + QPainterPath mainPath = detail.MainPathPath(this->getData()); + this->setPath(mainPath); + this->setPos(detail.GetMx(), detail.GetMy()); + + if (detail.IsSeamAllowance()) + { + mainPath.addPath(detail.SeamAllowancePath(this->getData())); + mainPath.setFillRule(Qt::OddEvenFill); + m_seamAllowance->setPath(mainPath); + } + else + { + m_seamAllowance->setPath(QPainterPath()); + } + + this->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::SaveDialogChange() +{ + SCASSERT(not m_dialog.isNull()); + DialogSeamAllowance *dialogTool = qobject_cast<DialogSeamAllowance*>(m_dialog.data()); + SCASSERT(dialogTool != nullptr); + const VPiece newDet = dialogTool->GetPiece(); + const VPiece oldDet = VAbstractTool::data.GetPiece(id); + + SavePieceOptions *saveCommand = new SavePieceOptions(oldDet, newDet, doc, id); + connect(saveCommand, &SavePieceOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); + qApp->getUndoStack()->push(saveCommand); + UpdateLabel(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::InitNodes(const VPiece &detail, VMainGraphicsScene *scene) +{ + for (int i = 0; i< detail.GetPath().CountNodes(); ++i) + { + switch (detail.GetPath().at(i).GetTypeTool()) + { + case (Tool::NodePoint): + { + VNodePoint *tool = InitTool<VNodePoint>(scene, detail.GetPath().at(i).GetId()); + connect(tool, &VNodePoint::ShowContextMenu, this, &VToolSeamAllowance::contextMenuEvent); + break; + } + case (Tool::NodeArc): + case (Tool::NodeElArc): + case (Tool::NodeSpline): + case (Tool::NodeSplinePath): + doc->IncrementReferens(VAbstractTool::data.GetGObject(detail.GetPath().at(i).GetId())->getIdTool()); + break; + default: + qDebug()<<"Get wrong tool type. Ignore."; + break; + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::InitCSAPaths(const VPiece &detail) +{ + QVector<CustomSARecord> records = detail.GetCustomSARecords(); + for (int i = 0; i < records.size(); ++i) + { + doc->IncrementReferens(records.at(i).path); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::InitInternalPaths(const VPiece &detail) +{ + QVector<quint32> records = detail.GetInternalPaths(); + for (int i = 0; i < records.size(); ++i) + { + VToolPiecePath *tool = qobject_cast<VToolPiecePath*>(doc->getTool(records.at(i))); + SCASSERT(tool != nullptr); + tool->setParentItem(this); + tool->SetParentType(ParentType::Item); + tool->show(); + doc->IncrementReferens(records.at(i)); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::DeleteTool(bool ask) +{ + DeletePiece *delDet = new DeletePiece(doc, id, VAbstractTool::data.GetPiece(id)); + if (ask) + { + if (ConfirmDeletion() == QMessageBox::No) + { + return; + } + /* If UnionDetails tool delete detail no need emit FullParsing.*/ + connect(delDet, &DeletePiece::NeedFullParsing, doc, &VAbstractPattern::NeedFullParsing); + } + + // If UnionDetails tool delete the detail this object will be deleted only after full parse. + // Deleting inside UnionDetails cause crash. + // Because this object should be inactive from no one we disconnect all signals that may cause a crash + // KEEP THIS LIST ACTUALL!!! + disconnect(doc, 0, this, 0); + if (QGraphicsScene *toolScene = scene()) + { + disconnect(toolScene, 0, this, 0); + } + disconnect(m_dataLabel, 0, this, 0); + disconnect(m_patternInfo, 0, this, 0); + disconnect(m_grainLine, 0, this, 0); + disconnect(m_sceneDetails, 0, this, 0); + + hide();// User shouldn't see this object + + qApp->getUndoStack()->push(delDet); + + // Throw exception, this will help prevent case when we forget to immediately quit function. + VExceptionToolWasDeleted e("Tool was used after deleting."); + throw e; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSeamAllowance::ToolCreation(const Source &typeCreation) +{ + if (typeCreation == Source::FromGui || typeCreation == Source::FromTool) + { + AddToFile(); + if (typeCreation != Source::FromTool) + { + qApp->getUndoStack()->endMacro(); + } + } + else + { + RefreshDataInFile(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +template <typename Tool> +/** + * @brief InitTool initial node item on scene + * @param scene pointer to scene. + * @param toolId if of tool object. + */ +Tool *VToolSeamAllowance::InitTool(VMainGraphicsScene *scene, quint32 toolId) +{ + Tool *tool = qobject_cast<Tool*>(doc->getTool(toolId)); + SCASSERT(tool != nullptr); + connect(tool, &Tool::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem); + tool->setParentItem(this); + tool->SetParentType(ParentType::Item); + doc->IncrementReferens(toolId); + return tool; +} diff --git a/src/libs/vtools/tools/vtoolseamallowance.h b/src/libs/vtools/tools/vtoolseamallowance.h new file mode 100644 index 000000000..304936fd3 --- /dev/null +++ b/src/libs/vtools/tools/vtoolseamallowance.h @@ -0,0 +1,159 @@ +/************************************************************************ + ** + ** @file + ** @author Roman Telezhynskyi <dismine(at)gmail.com> + ** @date 6 11, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2016 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#ifndef VTOOLSEAMALLOWANCE_H +#define VTOOLSEAMALLOWANCE_H + +#include <QtGlobal> +#include <qcompilerdetection.h> +#include <QObject> +#include <QGraphicsPathItem> + +#include "vabstracttool.h" +#include "../vwidgets/vtextgraphicsitem.h" +#include "../vwidgets/vgrainlineitem.h" + +class VMainGraphicsScene; +class DialogTool; +class VPiece; +class VNoBrushScalePathItem; + +class VToolSeamAllowance : public VAbstractTool, public QGraphicsPathItem +{ + Q_OBJECT +public: + virtual ~VToolSeamAllowance(); + + static VToolSeamAllowance* Create(DialogTool *m_dialog, VMainGraphicsScene *scene, VAbstractPattern *doc, + VContainer *data); + static VToolSeamAllowance* Create(quint32 id, VPiece newPiece, QString &width, VMainGraphicsScene *scene, + VAbstractPattern *doc, VContainer *data, const Document &parse, + const Source &typeCreation, const QString &m_drawName = QString()); + + static const quint8 pieceVersion; + + static const QString TagCSA; + static const QString TagRecord; + static const QString TagIPaths; + + static const QString AttrVersion; + static const QString AttrForbidFlipping; + static const QString AttrSeamAllowance; + static const QString AttrHeight; + static const QString AttrUnited; + static const QString AttrFont; + + void Remove(bool ask); + + static void AddAttributes(VAbstractPattern *doc, QDomElement &domElement, quint32 id, const VPiece &piece); + static void AddCSARecord(VAbstractPattern *doc, QDomElement &domElement, const CustomSARecord &record); + static void AddCSARecords(VAbstractPattern *doc, QDomElement &domElement, const QVector<CustomSARecord> &records); + static void AddInternalPaths(VAbstractPattern *doc, QDomElement &domElement, const QVector<quint32> &paths); + static void AddPatternPieceData(VAbstractPattern *doc, QDomElement &domElement, const VPiece &piece); + static void AddPatternInfo(VAbstractPattern *doc, QDomElement &domElement, const VPiece &piece); + static void AddGrainline(VAbstractPattern *doc, QDomElement &domElement, const VPiece &piece); + + virtual int type() const Q_DECL_OVERRIDE {return Type;} + enum { Type = UserType + static_cast<int>(Tool::Piece)}; + + virtual QString getTagName() const Q_DECL_OVERRIDE; + virtual void ShowVisualization(bool show) Q_DECL_OVERRIDE; + virtual void GroupVisibility(quint32 object, bool visible) Q_DECL_OVERRIDE; +public slots: + virtual void FullUpdateFromFile () Q_DECL_OVERRIDE; + virtual void FullUpdateFromGuiOk(int result); + void FullUpdateFromGuiApply(); + void EnableToolMove(bool move); + virtual void AllowHover(bool enabled) Q_DECL_OVERRIDE; + virtual void AllowSelecting(bool enabled) Q_DECL_OVERRIDE; + virtual void ResetChildren(QGraphicsItem* pItem); + virtual void UpdateAll(); + virtual void retranslateUi(); + void Highlight(quint32 id); +protected slots: + virtual void UpdateLabel(); + virtual void UpdatePatternInfo(); + virtual void UpdateGrainline(); + virtual void SaveMoveDetail(const QPointF &ptPos); + virtual void SaveResizeDetail(qreal dLabelW, int iFontSize); + virtual void SaveRotationDetail(qreal dRot); + virtual void SaveMovePattern(const QPointF& ptPos); + virtual void SaveResizePattern(qreal dLabelW, int iFontSize); + virtual void SaveRotationPattern(qreal dRot); + virtual void SaveMoveGrainline(const QPointF& ptPos); + virtual void SaveResizeGrainline(qreal dLength); + virtual void SaveRotateGrainline(qreal dRot, const QPointF& ptPos); +protected: + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, + QWidget *widget) Q_DECL_OVERRIDE; + virtual void AddToFile () Q_DECL_OVERRIDE; + virtual void RefreshDataInFile() Q_DECL_OVERRIDE; + virtual QVariant itemChange ( GraphicsItemChange change, const QVariant &value ) Q_DECL_OVERRIDE; + virtual void mousePressEvent( QGraphicsSceneMouseEvent * event) Q_DECL_OVERRIDE; + virtual void mouseReleaseEvent ( QGraphicsSceneMouseEvent * event ) Q_DECL_OVERRIDE; + virtual void hoverMoveEvent( QGraphicsSceneHoverEvent * event ) Q_DECL_OVERRIDE; + virtual void hoverEnterEvent ( QGraphicsSceneHoverEvent * event ) Q_DECL_OVERRIDE; + virtual void hoverLeaveEvent ( QGraphicsSceneHoverEvent * event ) Q_DECL_OVERRIDE; + virtual void contextMenuEvent ( QGraphicsSceneContextMenuEvent * event ) Q_DECL_OVERRIDE; + virtual void keyReleaseEvent(QKeyEvent * event) Q_DECL_OVERRIDE; + virtual void SetVisualization() Q_DECL_OVERRIDE {} + virtual void DeleteTool(bool ask = true) Q_DECL_OVERRIDE; + virtual void ToolCreation(const Source &typeCreation) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(VToolSeamAllowance) + + /** @brief dialog dialog options. */ + QPointer<DialogTool> m_dialog; + + /** @brief sceneDetails pointer to the scene. */ + VMainGraphicsScene *m_sceneDetails; + QString m_drawName; + + VNoBrushScalePathItem *m_seamAllowance; + VTextGraphicsItem *m_dataLabel; + VTextGraphicsItem *m_patternInfo; + VGrainlineItem *m_grainLine; + + void SetDialog(); + + VToolSeamAllowance(VAbstractPattern *doc, VContainer *data, const quint32 &id, const Source &typeCreation, + VMainGraphicsScene *scene, const QString &m_drawName, QGraphicsItem * parent = nullptr); + + void RefreshGeometry(); + void SaveDialogChange(); + + void InitNodes(const VPiece &detail, VMainGraphicsScene *scene); + void InitCSAPaths(const VPiece &detail); + void InitInternalPaths(const VPiece &detail); + + template <typename Tool> + Tool* InitTool(VMainGraphicsScene *scene, quint32 toolId); +}; + +#endif // VTOOLSEAMALLOWANCE_H diff --git a/src/libs/vtools/tools/vtooluniondetails.cpp b/src/libs/vtools/tools/vtooluniondetails.cpp index fc1b961ef..b2ebddbfc 100644 --- a/src/libs/vtools/tools/vtooluniondetails.cpp +++ b/src/libs/vtools/tools/vtooluniondetails.cpp @@ -58,15 +58,18 @@ #include "../vmisc/logging.h" #include "../vmisc/vabstractapplication.h" #include "../vpatterndb/vcontainer.h" +#include "../vpatterndb/vpiecepath.h" +#include "../vpatterndb/vpiecenode.h" #include "../dialogs/tools/dialogtool.h" #include "nodeDetails/vnodearc.h" #include "nodeDetails/vnodeellipticalarc.h" #include "nodeDetails/vnodepoint.h" #include "nodeDetails/vnodespline.h" #include "nodeDetails/vnodesplinepath.h" +#include "nodeDetails/vtoolpiecepath.h" #include "vdatatool.h" #include "vnodedetail.h" -#include "vtooldetail.h" +#include "vtoolseamallowance.h" class QDomElement; class QDomNode; @@ -92,1045 +95,115 @@ Q_LOGGING_CATEGORY(vToolUnion, "v.toolUnion") QT_WARNING_POP -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief VToolUnionDetails costructor. - * @param doc dom document container. - * @param data dom document container. - * @param id object id in container. - * @param d1 first detail. - * @param d2 second detail. - * @param indexD1 index edge in first detail. - * @param indexD2 index edge in second detail. - * @param typeCreation way we create this tool. - * @param parent parent object. - */ -VToolUnionDetails::VToolUnionDetails(VAbstractPattern *doc, VContainer *data, const quint32 &id, const VDetail &d1, - const VDetail &d2, const quint32 &indexD1, const quint32 &indexD2, - const Source &typeCreation, const QString &drawName, QObject *parent) - :VAbstractTool(doc, data, id, parent), d1(d1), d2(d2), indexD1(indexD1), indexD2(indexD2), drawName(drawName) +namespace { - _referens = 0; - ToolCreation(typeCreation); -} - //--------------------------------------------------------------------------------------------------------------------- -/** - * @brief AddToNewDetail create united detail adding one node per time. - * @param doc dom document container. - * @param data container with variables. - * @param newDetail united detail. - * @param det detail what we union. - * @param i index node in detail. - * @param idTool id tool union details. - * @param children list of children - * @param drawName name of pattern piece - * @param dx bias node x axis. - * @param dy bias node y axis. - * @param pRotate point rotation. - * @param angle angle rotation. - */ -void VToolUnionDetails::AddToNewDetail(VMainGraphicsScene *scene, VAbstractPattern *doc, - VContainer *data, VDetail &newDetail, const VDetail &det, const int &i, - const quint32 &idTool, QVector<quint32> &children, const QString &drawName, - const qreal &dx, const qreal &dy, const quint32 &pRotate, const qreal &angle) +VPiecePath GetPiecePath(int piece, VAbstractPattern *doc, quint32 id) { - quint32 id = 0, idObject = 0; - switch (det.at(i).getTypeTool()) + const QDomElement tool = doc->elementById(id); + if (tool.isNull()) { - case (Tool::NodePoint): + VException e(QString("Can't get tool by id='%1'.").arg(id)); + throw e; + } + + const QDomNodeList nodesList = tool.childNodes(); + for (qint32 i = 0; i < nodesList.size(); ++i) + { + const QDomElement element = nodesList.at(i).toElement(); + if (not element.isNull() && element.tagName() == VToolUnionDetails::TagDetail && i+1 == piece) { - VPointF *point = new VPointF(*data->GeometricObject<VPointF>(det.at(i).getId())); - point->setMode(Draw::Modeling); - - if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) + const QDomNodeList detList = element.childNodes(); + for (qint32 j = 0; j < detList.size(); ++j) { - BiasRotatePoint(point, dx, dy, *data->GeometricObject<VPointF>(pRotate), angle); - } - - idObject = data->AddGObject(point); - children.append(idObject); - VPointF *point1 = new VPointF(*point); - point1->setMode(Draw::Modeling); - id = data->AddGObject(point1); - VNodePoint::Create(doc, data, scene, id, idObject, Document::FullParse, Source::FromGui, drawName, idTool); - } - break; - case (Tool::NodeArc): - { - const QSharedPointer<VArc> arc = data->GeometricObject<VArc>(det.at(i).getId()); - VPointF p1 = VPointF(arc->GetP1(), "A", 0, 0); - VPointF p2 = VPointF(arc->GetP2(), "A", 0, 0); - VPointF *center = new VPointF(arc->GetCenter()); - - if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) - { - const QPointF p = *data->GeometricObject<VPointF>(pRotate); - - BiasRotatePoint(&p1, dx, dy, p, angle); - BiasRotatePoint(&p2, dx, dy, p, angle); - BiasRotatePoint(center, dx, dy, p, angle); - } - - QLineF l1(*center, p1); - QLineF l2(*center, p2); - center->setMode(Draw::Modeling); - quint32 idCenter = data->AddGObject(center); - Q_UNUSED(idCenter) - VArc *arc1 = new VArc(*center, arc->GetRadius(), arc->GetFormulaRadius(), l1.angle(), - QString().setNum(l1.angle()), l2.angle(), QString().setNum(l2.angle())); - arc1->setMode(Draw::Modeling); - idObject = data->AddGObject(arc1); - children.append(idObject); - - VArc *arc2 = new VArc(*arc1); - arc2->setMode(Draw::Modeling); - id = data->AddGObject(arc2); - - VNodeArc::Create(doc, data, id, idObject, Document::FullParse, Source::FromGui, drawName, idTool); - } - break; - case (Tool::NodeElArc): - { - const QSharedPointer<VEllipticalArc> arc = data->GeometricObject<VEllipticalArc>(det.at(i).getId()); - VPointF p1 = VPointF(arc->GetP1(), "A", 0, 0); - VPointF p2 = VPointF(arc->GetP2(), "A", 0, 0); - VPointF *center = new VPointF(arc->GetCenter()); - - if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) - { - const QPointF p = *data->GeometricObject<VPointF>(pRotate); - - BiasRotatePoint(&p1, dx, dy, p, angle); - BiasRotatePoint(&p2, dx, dy, p, angle); - BiasRotatePoint(center, dx, dy, p, angle); - } - - QLineF l1(*center, p1); - QLineF l2(*center, p2); - center->setMode(Draw::Modeling); - quint32 idCenter = data->AddGObject(center); - Q_UNUSED(idCenter) - VEllipticalArc *arc1 = new VEllipticalArc (*center, arc->GetRadius1(), arc->GetRadius2(), - arc->GetFormulaRadius1(), arc->GetFormulaRadius2(), - l1.angle(), QString().setNum(l1.angle()), l2.angle(), - QString().setNum(l2.angle()), 0, "0"); - arc1->setMode(Draw::Modeling); - idObject = data->AddGObject(arc1); - children.append(idObject); - - VEllipticalArc *arc2 = new VEllipticalArc(*arc1); - arc2->setMode(Draw::Modeling); - id = data->AddGObject(arc2); - - VNodeEllipticalArc::Create(doc, data, id, idObject, Document::FullParse, Source::FromGui, drawName, idTool); - } - break; - case (Tool::NodeSpline): - { - const QSharedPointer<VAbstractCubicBezier> spline = - data->GeometricObject<VAbstractCubicBezier>(det.at(i).getId()); - - QScopedPointer<VPointF> p1(new VPointF(spline->GetP1())); - VPointF p2 = VPointF(spline->GetP2()); - VPointF p3 = VPointF(spline->GetP3()); - QScopedPointer<VPointF> p4(new VPointF(spline->GetP4())); - - if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) - { - const QPointF p = *data->GeometricObject<VPointF>(pRotate); - - BiasRotatePoint(p1.data(), dx, dy, p, angle); - BiasRotatePoint(&p2, dx, dy, p, angle); - BiasRotatePoint(&p3, dx, dy, p, angle); - BiasRotatePoint(p4.data(), dx, dy, p, angle); - } - - VSpline *spl = new VSpline(*p1, p2, p3, *p4, 0, Draw::Modeling); - idObject = data->AddGObject(spl); - children.append(idObject); - - VSpline *spl1 = new VSpline(*spl); - spl1->setMode(Draw::Modeling); - id = data->AddGObject(spl1); - VNodeSpline::Create(doc, data, id, idObject, Document::FullParse, Source::FromGui, drawName, idTool); - } - break; - case (Tool::NodeSplinePath): - { - VSplinePath *path = new VSplinePath(); - path->setMode(Draw::Modeling); - const QSharedPointer<VAbstractCubicBezierPath> splinePath = - data->GeometricObject<VAbstractCubicBezierPath>(det.at(i).getId()); - for (qint32 i = 1; i <= splinePath->CountSubSpl(); ++i) - { - const VSpline spline = splinePath->GetSpline(i); - - VPointF *p1 = new VPointF(spline.GetP1()); - VPointF p2 = VPointF(spline.GetP2()); - VPointF p3 = VPointF(spline.GetP3()); - VPointF *p4 = new VPointF(spline.GetP4()); - if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) + const QDomElement element = detList.at(j).toElement(); + if (not element.isNull() && element.tagName() == VAbstractPattern::TagNodes) { - const QPointF p = *data->GeometricObject<VPointF>(pRotate); - - BiasRotatePoint(p1, dx, dy, p, angle); - BiasRotatePoint(&p2, dx, dy, p, angle); - BiasRotatePoint(&p3, dx, dy, p, angle); - BiasRotatePoint(p4, dx, dy, p, angle); - } - - VSpline spl = VSpline(*p1, p2, p3, *p4); - if (i==1) - { - const qreal angle1 = spl.GetStartAngle()+180; - const QString angle1F = QString().number(angle1); - - path->append(VSplinePoint(*p1, angle1, angle1F, spl.GetStartAngle(), spl.GetStartAngleFormula(), - 0, "0", spline.GetC1Length(), spline.GetC1LengthFormula())); - } - - const qreal angle2 = spl.GetEndAngle()+180; - const QString angle2F = QString().number(angle2); - qreal pL2 = 0; - QString pL2F("0"); - if (i+1 <= splinePath->CountSubSpl()) - { - const VSpline nextSpline = splinePath->GetSpline(i+1); - pL2 = nextSpline.GetC1Length(); - pL2F = nextSpline.GetC1LengthFormula(); - } - - path->append(VSplinePoint(*p4, spl.GetEndAngle(), spl.GetEndAngleFormula(), angle2, angle2F, - spline.GetC2Length(), spline.GetC2LengthFormula(), pL2, pL2F)); - - delete p4; - delete p1; - } - idObject = data->AddGObject(path); - children.append(idObject); - - VSplinePath *path1 = new VSplinePath(*path); - path1->setMode(Draw::Modeling); - id = data->AddGObject(path1); - VNodeSplinePath::Create(doc, data, id, idObject, Document::FullParse, Source::FromGui, drawName, idTool); - } - break; - default: - qDebug()<<"May be wrong tool type!!! Ignoring."<<Q_FUNC_INFO; - break; - } - newDetail.append(VNodeDetail(id, det.at(i).getTypeTool(), NodeDetail::Contour, 0, 0, det.at(i).getReverse())); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief UpdatePoints update data for united details. - * @param data container with variables. - * @param det detail what we union. - * @param i index node in detail. - * @param children list ids of all children. - * @param dx bias node x axis. - * @param dy bias node y axis. - * @param pRotate point rotation. - * @param angle angle rotation. - */ -void VToolUnionDetails::UpdatePoints(VContainer *data, const VDetail &det, const int &i, - QVector<quint32> &children, const qreal &dx, const qreal &dy, - const quint32 &pRotate, - const qreal &angle) -{ - switch (det.at(i).getTypeTool()) - { - case (Tool::NodePoint): - { - VPointF *point = new VPointF(*data->GeometricObject<VPointF>(det.at(i).getId())); - point->setMode(Draw::Modeling); - if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) - { - BiasRotatePoint(point, dx, dy, *data->GeometricObject<VPointF>(pRotate), angle); - } - data->UpdateGObject(TakeNextId(children), point); - } - break; - case (Tool::NodeArc): - { - const QSharedPointer<VArc> arc = data->GeometricObject<VArc>(det.at(i).getId()); - VPointF p1 = VPointF(arc->GetP1()); - VPointF p2 = VPointF(arc->GetP2()); - QScopedPointer<VPointF> center(new VPointF(arc->GetCenter())); - - if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) - { - const QPointF p = *data->GeometricObject<VPointF>(pRotate); - - BiasRotatePoint(&p1, dx, dy, p, angle); - BiasRotatePoint(&p2, dx, dy, p, angle); - BiasRotatePoint(center.data(), dx, dy, p, angle); - } - - QLineF l1(*center, p1); - QLineF l2(*center, p2); - - VArc *arc1 = new VArc(*center, arc->GetRadius(), arc->GetFormulaRadius(), l1.angle(), - QString().setNum(l1.angle()), l2.angle(), QString().setNum(l2.angle())); - arc1->setMode(Draw::Modeling); - data->UpdateGObject(TakeNextId(children), arc1); - } - break; - case (Tool::NodeElArc): - { - const QSharedPointer<VEllipticalArc> arc = data->GeometricObject<VEllipticalArc>(det.at(i).getId()); - VPointF p1 = VPointF(arc->GetP1()); - VPointF p2 = VPointF(arc->GetP2()); - QScopedPointer<VPointF> center(new VPointF(arc->GetCenter())); - - if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) - { - const QPointF p = *data->GeometricObject<VPointF>(pRotate); - - BiasRotatePoint(&p1, dx, dy, p, angle); - BiasRotatePoint(&p2, dx, dy, p, angle); - BiasRotatePoint(center.data(), dx, dy, p, angle); - } - - QLineF l1(*center, p1); - QLineF l2(*center, p2); - - VEllipticalArc *arc1 = new VEllipticalArc (*center, arc->GetRadius1(), arc->GetRadius2(), - arc->GetFormulaRadius1(), arc->GetFormulaRadius2(), - l1.angle(), QString().setNum(l1.angle()), l2.angle(), - QString().setNum(l2.angle()), 0, "0"); - arc1->setMode(Draw::Modeling); - data->UpdateGObject(TakeNextId(children), arc1); - } - break; - case (Tool::NodeSpline): - { - const QSharedPointer<VAbstractCubicBezier> spline = - data->GeometricObject<VAbstractCubicBezier>(det.at(i).getId()); - - QScopedPointer<VPointF> p1(new VPointF(spline->GetP1())); - VPointF p2 = VPointF(spline->GetP2()); - VPointF p3 = VPointF(spline->GetP3()); - QScopedPointer<VPointF> p4(new VPointF(spline->GetP4())); - - if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) - { - const QPointF p = *data->GeometricObject<VPointF>(pRotate); - - BiasRotatePoint(p1.data(), dx, dy, p, angle); - BiasRotatePoint(&p2, dx, dy, p, angle); - BiasRotatePoint(&p3, dx, dy, p, angle); - BiasRotatePoint(p4.data(), dx, dy, p, angle); - } - - VSpline *spl = new VSpline(*p1, p2, p3, *p4, 0, Draw::Modeling); - data->UpdateGObject(TakeNextId(children), spl); - } - break; - case (Tool::NodeSplinePath): - { - VSplinePath *path = new VSplinePath(); - path->setMode(Draw::Modeling); - const QSharedPointer<VAbstractCubicBezierPath> splinePath = - data->GeometricObject<VAbstractCubicBezierPath>(det.at(i).getId()); - SCASSERT(splinePath != nullptr) - for (qint32 i = 1; i <= splinePath->CountSubSpl(); ++i) - { - const VSpline spline = splinePath->GetSpline(i); - - QScopedPointer<VPointF> p1(new VPointF(spline.GetP1())); - VPointF p2 = VPointF(spline.GetP2()); - VPointF p3 = VPointF(spline.GetP3()); - QScopedPointer<VPointF> p4(new VPointF(spline.GetP4())); - - if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) - { - const QPointF p = *data->GeometricObject<VPointF>(pRotate); - - BiasRotatePoint(p1.data(), dx, dy, p, angle); - BiasRotatePoint(&p2, dx, dy, p, angle); - BiasRotatePoint(&p3, dx, dy, p, angle); - BiasRotatePoint(p4.data(), dx, dy, p, angle); - } - - VSpline spl = VSpline(*p1, p2, p3, *p4); - if (i==1) - { - const qreal angle1 = spl.GetStartAngle()+180; - const QString angle1F = QString().number(angle1); - - path->append(VSplinePoint(*p1, angle1, angle1F, spl.GetStartAngle(), spl.GetStartAngleFormula(), - 0, "0", spline.GetC1Length(), spline.GetC1LengthFormula())); - } - - const qreal angle2 = spl.GetEndAngle()+180; - const QString angle2F = QString().number(angle2); - - qreal pL2 = 0; - QString pL2F("0"); - if (i+1 <= splinePath->CountSubSpl()) - { - const VSpline nextSpline = splinePath->GetSpline(i+1); - pL2 = nextSpline.GetC1Length(); - pL2F = nextSpline.GetC1LengthFormula(); - } - - path->append(VSplinePoint(*p4, spl.GetEndAngle(), spl.GetEndAngleFormula(), angle2, angle2F, - spline.GetC2Length(), spline.GetC2LengthFormula(), pL2, pL2F)); - } - data->UpdateGObject(TakeNextId(children), path); - } - break; - default: - qDebug()<<"May be wrong tool type!!! Ignoring."<<Q_FUNC_INFO; - break; - } -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief BiasRotatePoint bias and rotate point. - * @param point point. - * @param dx bias x axis. - * @param dy bias y axis. - * @param pRotate point rotation. - * @param angle angle rotation. - */ -void VToolUnionDetails::BiasRotatePoint(VPointF *point, const qreal &dx, const qreal &dy, const QPointF &pRotate, - const qreal &angle) -{ - point->setX(point->x()+dx); - point->setY(point->y()+dy); - QLineF line(pRotate, *point); - line.setAngle(line.angle()+angle); - point->setX(line.p2().x()); - point->setY(line.p2().y()); -} - -//--------------------------------------------------------------------------------------------------------------------- -QString VToolUnionDetails::getTagName() const -{ - return VAbstractPattern::TagTools; -} - -//--------------------------------------------------------------------------------------------------------------------- -void VToolUnionDetails::ShowVisualization(bool show) -{ - Q_UNUSED(show) -} - -//--------------------------------------------------------------------------------------------------------------------- -void VToolUnionDetails::incrementReferens() -{ - ++_referens; - if (_referens == 1) - { - IncrementReferences(d1); - IncrementReferences(d2); - - QDomElement domElement = doc->elementById(id); - if (domElement.isElement()) - { - doc->SetParametrUsage(domElement, AttrInUse, NodeUsage::InUse); - } - } -} - -//--------------------------------------------------------------------------------------------------------------------- -void VToolUnionDetails::decrementReferens() -{ - if (_referens > 0) - { - --_referens; - } - if (_referens == 0) - { - DecrementReferences(d1); - DecrementReferences(d2); - - QDomElement domElement = doc->elementById(id); - if (domElement.isElement()) - { - doc->SetParametrUsage(domElement, AttrInUse, NodeUsage::NotInUse); - } - } -} - -//--------------------------------------------------------------------------------------------------------------------- -void VToolUnionDetails::GroupVisibility(quint32 object, bool visible) -{ - Q_UNUSED(object) - Q_UNUSED(visible) -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief Create help create tool from GUI. - * @param dialog dialog. - * @param doc dom document container. - * @param data container with variables. - */ -VToolUnionDetails* VToolUnionDetails::Create(DialogTool *dialog, VMainGraphicsScene *scene, VAbstractPattern *doc, - VContainer *data) -{ - SCASSERT(dialog != nullptr) - DialogUnionDetails *dialogTool = qobject_cast<DialogUnionDetails*>(dialog); - SCASSERT(dialogTool != nullptr) - VDetail d1 = data->GetDetail(dialogTool->getD1()); - VDetail d2 = data->GetDetail(dialogTool->getD2()); - quint32 indexD1 = static_cast<quint32>(dialogTool->getIndexD1()); - quint32 indexD2 = static_cast<quint32>(dialogTool->getIndexD2()); - const bool retainPieces = dialogTool->RetainPieces(); - qApp->getUndoStack()->beginMacro(tr("union details")); - VToolUnionDetails* tool = Create(0, d1, d2, dialogTool->getD1(), dialogTool->getD2(), indexD1, indexD2, scene, - doc, data, Document::FullParse, Source::FromGui, retainPieces); - qApp->getUndoStack()->endMacro(); - return tool; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief Create help create tool. - * @param _id tool id, 0 if tool doesn't exist yet. - * @param d1 first detail. - * @param d2 second detail. - * @param d1id id first detail. - * @param d2id id second detail. - * @param indexD1 index edge in first detail. - * @param indexD2 index edge in second detail. - * @param scene pointer to scene. - * @param doc dom document container. - * @param data container with variables. - * @param parse parser file mode. - * @param typeCreation way we create this tool. - */ -VToolUnionDetails* VToolUnionDetails::Create(const quint32 _id, const VDetail &d1, const VDetail &d2, - const quint32 &d1id, const quint32 &d2id, const quint32 &indexD1, - const quint32 &indexD2, VMainGraphicsScene *scene, VAbstractPattern *doc, - VContainer *data, const Document &parse, const Source &typeCreation, - bool retainPieces) -{ - VToolUnionDetails *unionDetails = nullptr; - quint32 id = _id; - QString drawName; - if (typeCreation == Source::FromGui) - { - id = data->getNextId(); - drawName = DrawName(doc, d1id, d2id); - SCASSERT(not drawName.isEmpty()) - } - else - { - if (parse != Document::FullParse) - { - doc->UpdateToolData(id, data); - } - } - - //First add tool to file - VAbstractTool::AddRecord(id, Tool::UnionDetails, doc); - if (parse == Document::FullParse) - { - //Scene doesn't show this tool, so doc will destroy this object. - unionDetails = new VToolUnionDetails(doc, data, id, d1, d2, indexD1, indexD2, typeCreation, drawName, doc); - doc->AddTool(id, unionDetails); - // Unfortunatelly doc will destroy all objects only in the end, but we should delete them before each FullParse - doc->AddToolOnRemove(unionDetails); - } - //Then create new details - VNodeDetail det1p1; - VNodeDetail det1p2; - d1.NodeOnEdge(indexD1, det1p1, det1p2); - Q_UNUSED(det1p2) - - VPointF point1; - VPointF point2; - PointsOnEdge(d1, indexD1, point1, point2, data); - - VPointF point3; - VPointF point4; - PointsOnEdge(d2, indexD2, point3, point4, data); - - const qreal dx = point1.x() - point4.x(); - const qreal dy = point1.y() - point4.y(); - - point3.setX(point3.x()+dx); - point3.setY(point3.y()+dy); - - point4.setX(point4.x()+dx); - point4.setY(point4.y()+dy); - - const QLineF p4p3 = QLineF(point4, point3); - const QLineF p1p2 = QLineF(point1, point2); - - const qreal angle = p4p3.angleTo(p1p2); - qint32 pointsD2 = 0; //Keeps number points the second detail, what we have already added. - - const qint32 countNodeD1 = d1.RemoveEdge(indexD1).CountNode(); - const qint32 countNodeD2 = d2.RemoveEdge(indexD2).CountNode(); - - if (typeCreation == Source::FromGui) - { - qint32 i = 0; - VDetail newDetail; - QVector<quint32> children; - do - { - AddToNewDetail(scene, doc, data, newDetail, d1.RemoveEdge(indexD1), i, id, children, drawName); - ++i; - if (i > d1.indexOfNode(det1p1.getId()) && pointsD2 < countNodeD2-1) - { - qint32 j = 0; - FindIndexJ(pointsD2, d2, indexD2, j); - do - { - if (j >= countNodeD2) - { - j=0; - } - AddToNewDetail(scene, doc, data, newDetail, d2.RemoveEdge(indexD2), j, id, children, drawName, - dx, dy, det1p1.getId(), angle); - ++pointsD2; - ++j; - } while (pointsD2 < countNodeD2-1); - } - } while (i < countNodeD1); - - newDetail.setName(tr("United detail")); - newDetail.setWidth(d1.getWidth()); - newDetail.setMx(d1.getMx()); - newDetail.setMy(d1.getMy()); - VToolDetail::Create(0, newDetail, scene, doc, data, parse, Source::FromTool, drawName); - QHash<quint32, VDataTool*>* tools = doc->getTools(); - SCASSERT(tools != nullptr) - - if (not retainPieces) - { - { - VToolDetail *toolDet = qobject_cast<VToolDetail*>(tools->value(d1id)); - SCASSERT(toolDet != nullptr) - bool ask = false; - toolDet->Remove(ask); - } - - { - VToolDetail *toolDet = qobject_cast<VToolDetail*>(tools->value(d2id)); - SCASSERT(toolDet != nullptr) - const bool ask = false; - toolDet->Remove(ask); - } - } - - SCASSERT(not children.isEmpty()) - SaveChildren(doc, id, children); - } - else - { - QVector<quint32> children = AllChildren(doc, id); - if (not children.isEmpty()) - { - // This check need for backward compatibility - // Remove check and "else" part if min version is 0.3.2 - Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 3, 2), - "Time to refactor the code."); - if (children.size() == countNodeD1 + countNodeD2-1) - { - qint32 i = 0; - do - { - UpdatePoints(data, d1.RemoveEdge(indexD1), i, children); - ++i; - if (i > d1.indexOfNode(det1p1.getId()) && pointsD2 < countNodeD2-1) - { - VDetail d2REdge = d2.RemoveEdge(indexD2); - qint32 j = 0; - FindIndexJ(pointsD2, d2, indexD2, j); - do - { - if (j >= countNodeD2) - { - j=0; - } - UpdatePoints(data, d2REdge, j, children, dx, dy, det1p1.getId(), angle); - ++pointsD2; - ++j; - } while (pointsD2 < countNodeD2-1); - } - } while (i<countNodeD1); - } - else // remove if min version is 0.3.2 - { - qint32 i = 0; - do - { - ++i; - if (i > d1.indexOfNode(det1p1.getId())) - { - const int childrenCount = children.size(); - VDetail d2REdge = d2.RemoveEdge(indexD2); - qint32 j = 0; - FindIndexJ(pointsD2, d2, indexD2, j); - do - { - if (j >= countNodeD2) - { - j=0; - } - UpdatePoints(data, d2REdge, j, children, dx, dy, det1p1.getId(), angle); - ++pointsD2; - ++j; - } while (pointsD2 < childrenCount); - break; - } - } while (i<countNodeD1); - } - } - } - return unionDetails; -} - -//--------------------------------------------------------------------------------------------------------------------- -void VToolUnionDetails::PointsOnEdge(const VDetail &d, const quint32 &index, VPointF &p1, VPointF &p2, VContainer *data) -{ - VNodeDetail det2p1; - VNodeDetail det2p2; - d.NodeOnEdge(index, det2p1, det2p2); - p1 = VPointF(*data->GeometricObject<VPointF>(det2p1.getId())); - p2 = VPointF(*data->GeometricObject<VPointF>(det2p2.getId())); -} - -//--------------------------------------------------------------------------------------------------------------------- -void VToolUnionDetails::FindIndexJ(const qint32 &pointsD2, const VDetail &d2, const quint32 &indexD2, qint32 &j) -{ - if (pointsD2 == 0) - { - VNodeDetail node1; - VNodeDetail node2; - d2.NodeOnEdge(indexD2, node1, node2); - const VDetail removedD2 = d2.RemoveEdge(indexD2); - const int k = removedD2.indexOfNode(node2.getId()); - SCASSERT(k != -1) - if (k == removedD2.CountNode()-1) - {//We have last node in detail, we wil begin from 0 - j = 0; - } - else - {// Continue from next node - j = k+1; - } - } -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief GetDetailFromFile parse detail from file. - * @param doc dom document container. - * @param domElement tag in xml tree. - * @return detail stored in file. - */ -QVector<VDetail> VToolUnionDetails::GetDetailFromFile(VAbstractPattern *doc, const QDomElement &domElement) -{ - QVector<VDetail> vector; - QDomNodeList detailList = domElement.childNodes(); - qint32 num = detailList.size(); - for (qint32 i = 0; i < num; ++i) - { - QDomElement element = detailList.at(i).toElement(); - if (element.isNull() == false) - { - if (element.tagName() == VToolUnionDetails::TagDetail) - { - VDetail d; - QDomNodeList nodeList = element.childNodes(); - qint32 num = nodeList.size(); - for (qint32 j = 0; j < num; ++j) - { - QDomElement element = nodeList.at(j).toElement(); - if (element.isNull() == false) - { - if (element.tagName() == VToolUnionDetails::TagNode) - { - quint32 id = doc->GetParametrUInt(element, AttrIdObject, NULL_ID_STR); - qreal mx = qApp->toPixel(doc->GetParametrDouble(element, AttrMx, "0.0")); - qreal my = qApp->toPixel(doc->GetParametrDouble(element, AttrMy, "0.0")); - const bool reversed = doc->GetParametrUInt(element, VToolDetail::AttrReverse, "0"); - Tool tool = Tool::NodePoint; - NodeDetail nodeType = NodeDetail::Contour; - QString t = doc->GetParametrString(element, "type", "NodePoint"); - if (t == QLatin1String("NodePoint")) - { - tool = Tool::NodePoint; - } - else if (t == QLatin1String("NodeArc")) - { - tool = Tool::NodeArc; - } - else if (t == QLatin1String("NodeElArc")) - { - tool = Tool::NodeElArc; - } - else if (t == QLatin1String("NodeSpline")) - { - tool = Tool::NodeSpline; - } - else if (t == QLatin1String("NodeSplinePath")) - { - tool = Tool::NodeSplinePath; - } - d.append(VNodeDetail(id, tool, nodeType, mx, my, reversed)); - } - } - } - vector.append(d); - } - } - } - return vector; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief AddToFile add tag with informations about tool into file. - */ -void VToolUnionDetails::AddToFile() -{ - QDomElement domElement = doc->createElement(getTagName()); - - doc->SetAttribute(domElement, VDomDocument::AttrId, id); - doc->SetAttribute(domElement, AttrType, ToolType); - doc->SetAttribute(domElement, AttrIndexD1, indexD1); - doc->SetAttribute(domElement, AttrIndexD2, indexD2); - - AddDetail(domElement, d1); - AddDetail(domElement, d2); - - AddToModeling(domElement); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief RefreshDataInFile refresh attributes in file. If attributes don't exist create them. - */ -void VToolUnionDetails::RefreshDataInFile() -{ - QDomElement domElement = doc->elementById(id); - if (domElement.isElement()) - { - doc->SetAttribute(domElement, AttrIndexD1, indexD1); - doc->SetAttribute(domElement, AttrIndexD2, indexD2); - - QDomNode domNode = domElement.firstChild(); - domNode = UpdateDetail(domNode, d1); - UpdateDetail(domNode, d2); - } -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief AddDetail add detail to xml file. - * @param domElement tag in xml tree. - * @param d detail. - */ -void VToolUnionDetails::AddDetail(QDomElement &domElement, VDetail &d) -{ - QDomElement det = doc->createElement(TagDetail); - - for (int i = 0; i < d.CountNode(); ++i) - { - AddNode(det, d.at(i)); - } - - domElement.appendChild(det); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief AddNode add node to xml file. - * @param domElement tag in xml tree. - * @param node node. - */ -void VToolUnionDetails::AddNode(QDomElement &domElement, const VNodeDetail &node) -{ - //Right now method similar to method in class VToolDetail. - VToolDetail::AddNode(doc, domElement, node); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief UpdateDetail update detail in xml tree. - * @param domNode dom node. - * @param d detail. - * @return return next detail tag in xml tree if exist. - */ -QDomNode VToolUnionDetails::UpdateDetail(const QDomNode &domNode, const VDetail &d) -{ - //QDomNode domNode = domElement.firstChild(); - while (domNode.isNull() == false) - { - if (domNode.isElement()) - { - QDomElement domElement = domNode.toElement(); - if (domElement.isNull() == false) - { - if (domElement.tagName() == VToolUnionDetails::TagDetail) - { - VDomDocument::RemoveAllChildren(domElement);//delete all nodes in detail - for (int i = 0; i < d.CountNode(); ++i) - { - AddNode(domElement, d.at(i));//rewrite nodes of detail - } - break; + return VAbstractPattern::ParsePieceNodes(element); } } } } - return domNode.nextSibling(); + + return VPiecePath(); } //--------------------------------------------------------------------------------------------------------------------- -/** - * @brief AddToModeling add tool to xml tree. - * @param domElement tag in xml tree. - */ -void VToolUnionDetails::AddToModeling(const QDomElement &domElement) +VPiecePath GetPiece1MainPath(VAbstractPattern *doc, quint32 id) { - QDomElement modeling = doc->GetDraw(drawName).firstChildElement(VAbstractPattern::TagModeling); - if (not modeling.isNull()) - { - modeling.appendChild(domElement); - } - else - { - qCDebug(vToolUnion, "Can't find tag %s.", qUtf8Printable(VAbstractPattern::TagModeling)); - return; - } + return GetPiecePath(1, doc, id); } //--------------------------------------------------------------------------------------------------------------------- -void VToolUnionDetails::IncrementReferences(const VDetail &d) const +VPiecePath GetPiece2MainPath(VAbstractPattern *doc, quint32 id) { - for (int i = 0; i < d.CountNode(); ++i) + return GetPiecePath(2, doc, id); +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<CustomSARecord> GetPiece2CSAPaths(VAbstractPattern *doc, quint32 id) +{ + const QDomElement tool = doc->elementById(id); + if (tool.isNull()) { - switch (d.at(i).getTypeTool()) + VException e(QString("Can't get tool by id='%1'.").arg(id)); + throw e; + } + + const QDomNodeList nodesList = tool.childNodes(); + for (qint32 i = 0; i < nodesList.size(); ++i) + { + const QDomElement element = nodesList.at(i).toElement(); + if (not element.isNull() && element.tagName() == VToolUnionDetails::TagDetail && i+1 == 2) { - case (Tool::NodePoint): + const QDomNodeList detList = element.childNodes(); + for (qint32 j = 0; j < detList.size(); ++j) { - const auto point = VAbstractTool::data.GeometricObject<VPointF>(d.at(i).getId()); - doc->IncrementReferens(point->getIdTool()); - break; + const QDomElement element = detList.at(j).toElement(); + if (not element.isNull() && element.tagName() == VToolSeamAllowance::TagCSA) + { + return VAbstractPattern::ParsePieceCSARecords(element); + } } - case (Tool::NodeArc): - case (Tool::NodeElArc): - case (Tool::NodeSpline): - case (Tool::NodeSplinePath): - doc->IncrementReferens(d.at(i).getId()); - break; - default: - qDebug()<<"Get wrong tool type. Ignore."; - break; } } + + return QVector<CustomSARecord>(); } //--------------------------------------------------------------------------------------------------------------------- -void VToolUnionDetails::DecrementReferences(const VDetail &d) const +QVector<quint32> GetPiece2InternalPaths(VAbstractPattern *doc, quint32 id) { - for (int i = 0; i < d.CountNode(); ++i) + const QDomElement tool = doc->elementById(id); + if (tool.isNull()) { - switch (d.at(i).getTypeTool()) + VException e(QString("Can't get tool by id='%1'.").arg(id)); + throw e; + } + + const QDomNodeList nodesList = tool.childNodes(); + for (qint32 i = 0; i < nodesList.size(); ++i) + { + const QDomElement element = nodesList.at(i).toElement(); + if (not element.isNull() && element.tagName() == VToolUnionDetails::TagDetail && i+1 == 2) { - case (Tool::NodePoint): + const QDomNodeList detList = element.childNodes(); + for (qint32 j = 0; j < detList.size(); ++j) { - const auto point = VAbstractTool::data.GeometricObject<VPointF>(d.at(i).getId()); - doc->DecrementReferens(point->getIdTool()); - break; + const QDomElement element = detList.at(j).toElement(); + if (not element.isNull() && element.tagName() == VToolSeamAllowance::TagIPaths) + { + return VAbstractPattern::ParsePieceInternalPaths(element); + } } - case (Tool::NodeArc): - case (Tool::NodeElArc): - case (Tool::NodeSpline): - case (Tool::NodeSplinePath): - doc->DecrementReferens(d.at(i).getId()); - break; - default: - qDebug()<<"Get wrong tool type. Ignore."; - break; } } + + return QVector<quint32>(); } //--------------------------------------------------------------------------------------------------------------------- -void VToolUnionDetails::SaveChildren(VAbstractPattern *doc, quint32 id, const QVector<quint32> &children) -{ - QDomElement toolUnion = doc->elementById(id); - if (toolUnion.isNull()) - { - return; - } - - QDomElement tagChildren = doc->createElement(TagChildren); - - for (int i=0; i<children.size(); ++i) - { - QDomElement tagChild = doc->createElement(TagChild); - tagChild.appendChild(doc->createTextNode(QString().setNum(children.at(i)))); - tagChildren.appendChild(tagChild); - } - - toolUnion.appendChild(tagChildren); -} - -//--------------------------------------------------------------------------------------------------------------------- -QVector<quint32> VToolUnionDetails::AllChildren(VAbstractPattern *doc, quint32 id) -{ - const QDomElement toolUnion = doc->elementById(id); - if (toolUnion.isNull()) - { - return QVector<quint32>(); - } - - const QDomElement tagChildren = toolUnion.firstChildElement(TagChildren); - if (tagChildren.isNull()) - { - return QVector<quint32>(); - } - - QVector<quint32> childrenId; - const QDomNodeList listChildren = tagChildren.elementsByTagName(TagChild); - for (int i=0; i < listChildren.size(); ++i) - { - const QDomElement domElement = listChildren.at(i).toElement(); - if (not domElement.isNull()) - { - childrenId.append(domElement.text().toUInt()); - } - } - return childrenId; -} - -//--------------------------------------------------------------------------------------------------------------------- -quint32 VToolUnionDetails::TakeNextId(QVector<quint32> &children) -{ - quint32 idChild = NULL_ID; - if (not children.isEmpty()) - { -#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) - idChild = children.takeFirst(); -#else - idChild = children.first(); - children.remove(0); -#endif - } - else - { - idChild = NULL_ID; - } - return idChild; -} - -//--------------------------------------------------------------------------------------------------------------------- -QString VToolUnionDetails::DrawName(VAbstractPattern *doc, quint32 d1id, quint32 d2id) +QString DrawName(VAbstractPattern *doc, quint32 d1id, quint32 d2id) { const QDomElement detail1 = doc->elementById(d1id); if (detail1.isNull()) @@ -1196,3 +269,1269 @@ QString VToolUnionDetails::DrawName(VAbstractPattern *doc, quint32 d1id, quint32 return draw2Name; } } + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief BiasRotatePoint bias and rotate point. + * @param point point. + * @param dx bias x axis. + * @param dy bias y axis. + * @param pRotate point rotation. + * @param angle angle rotation. + */ +void BiasRotatePoint(VPointF *point, qreal dx, qreal dy, const QPointF &pRotate, qreal angle) +{ + point->setX(point->x()+dx); + point->setY(point->y()+dy); + QLineF line(pRotate, *point); + line.setAngle(line.angle()+angle); + point->setX(line.p2().x()); + point->setY(line.p2().y()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void PointsOnEdge(const VPiecePath &path, quint32 index, VPointF &p1, VPointF &p2, VContainer *data) +{ + VPieceNode det2p1; + VPieceNode det2p2; + path.NodeOnEdge(index, det2p1, det2p2); + p1 = VPointF(*data->GeometricObject<VPointF>(det2p1.GetId())); + p2 = VPointF(*data->GeometricObject<VPointF>(det2p2.GetId())); +} + +//--------------------------------------------------------------------------------------------------------------------- +void UnionInitParameters(const VToolUnionDetailsInitData &initData, const VPiecePath &d1Path, const VPiecePath &d2Path, + VPieceNode &det1p1, qreal &dx, qreal &dy, qreal &angle) +{ + VPieceNode det1p2; + d1Path.NodeOnEdge(initData.indexD1, det1p1, det1p2); + Q_UNUSED(det1p2) + + VPointF point1; + VPointF point2; + PointsOnEdge(d1Path, initData.indexD1, point1, point2, initData.data); + + VPointF point3; + VPointF point4; + PointsOnEdge(d2Path, initData.indexD2, point3, point4, initData.data); + + dx = point1.x() - point4.x(); + dy = point1.y() - point4.y(); + + point3.setX(point3.x()+dx); + point3.setY(point3.y()+dy); + + point4.setX(point4.x()+dx); + point4.setY(point4.y()+dy); + + const QLineF p4p3 = QLineF(point4, point3); + const QLineF p1p2 = QLineF(point1, point2); + + angle = p4p3.angleTo(p1p2); +} + +//--------------------------------------------------------------------------------------------------------------------- +quint32 AddNodePoint(const VPieceNode &node, const VToolUnionDetailsInitData &initData, quint32 idTool, + QVector<quint32> &children, const QString &drawName, qreal dx, qreal dy, + quint32 pRotate, qreal angle) +{ + QScopedPointer<VPointF> point(new VPointF(*initData.data->GeometricObject<VPointF>(node.GetId()))); + point->setMode(Draw::Modeling); + + if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) + { + BiasRotatePoint(point.data(), dx, dy, *initData.data->GeometricObject<VPointF>(pRotate), angle); + } + + QScopedPointer<VPointF> point1(new VPointF(*point)); + + const quint32 idObject = initData.data->AddGObject(point.take()); + children.append(idObject); + point1->setMode(Draw::Modeling); + const quint32 id = initData.data->AddGObject(point1.take()); + VNodePoint::Create(initData.doc, initData.data, initData.scene, id, idObject, Document::FullParse, Source::FromGui, + drawName, idTool); + return id; +} + +//--------------------------------------------------------------------------------------------------------------------- +quint32 AddNodeArc(const VPieceNode &node, const VToolUnionDetailsInitData &initData, quint32 idTool, + QVector<quint32> &children, const QString &drawName, qreal dx, qreal dy, + quint32 pRotate, qreal angle) +{ + const QSharedPointer<VArc> arc = initData.data->GeometricObject<VArc>(node.GetId()); + VPointF p1 = VPointF(arc->GetP1(), "A", 0, 0); + VPointF p2 = VPointF(arc->GetP2(), "A", 0, 0); + QScopedPointer<VPointF> center(new VPointF(arc->GetCenter())); + + if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) + { + const QPointF p = *initData.data->GeometricObject<VPointF>(pRotate); + + BiasRotatePoint(&p1, dx, dy, p, angle); + BiasRotatePoint(&p2, dx, dy, p, angle); + BiasRotatePoint(center.data(), dx, dy, p, angle); + } + + QLineF l1(*center, p1); + QLineF l2(*center, p2); + center->setMode(Draw::Modeling); + VPointF *tmpCenter = center.take(); + const quint32 idCenter = initData.data->AddGObject(tmpCenter); + Q_UNUSED(idCenter) + QScopedPointer<VArc> arc1(new VArc(*tmpCenter, arc->GetRadius(), arc->GetFormulaRadius(), l1.angle(), + QString().setNum(l1.angle()), l2.angle(), QString().setNum(l2.angle()))); + arc1->setMode(Draw::Modeling); + + QScopedPointer<VArc>arc2(new VArc(*arc1)); + + const quint32 idObject = initData.data->AddGObject(arc1.take()); + children.append(idObject); + + arc2->setMode(Draw::Modeling); + const quint32 id = initData.data->AddGObject(arc2.take()); + + VNodeArc::Create(initData.doc, initData.data, id, idObject, Document::FullParse, Source::FromGui, drawName, idTool); + return id; +} + +//--------------------------------------------------------------------------------------------------------------------- +quint32 AddNodeElArc(const VPieceNode &node, const VToolUnionDetailsInitData &initData, quint32 idTool, + QVector<quint32> &children, const QString &drawName, qreal dx, qreal dy, + quint32 pRotate, qreal angle) +{ + const QSharedPointer<VEllipticalArc> arc = initData.data->GeometricObject<VEllipticalArc>(node.GetId()); + VPointF p1 = VPointF(arc->GetP1(), "A", 0, 0); + VPointF p2 = VPointF(arc->GetP2(), "A", 0, 0); + QScopedPointer<VPointF> center(new VPointF(arc->GetCenter())); + + if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) + { + const QPointF p = *initData.data->GeometricObject<VPointF>(pRotate); + + BiasRotatePoint(&p1, dx, dy, p, angle); + BiasRotatePoint(&p2, dx, dy, p, angle); + BiasRotatePoint(center.data(), dx, dy, p, angle); + } + + QLineF l1(*center, p1); + QLineF l2(*center, p2); + center->setMode(Draw::Modeling); + VPointF *tmpCenter = center.take(); + quint32 idCenter = initData.data->AddGObject(tmpCenter); + Q_UNUSED(idCenter) + QScopedPointer<VEllipticalArc> arc1(new VEllipticalArc (*tmpCenter, arc->GetRadius1(), arc->GetRadius2(), + arc->GetFormulaRadius1(), arc->GetFormulaRadius2(), + l1.angle(), QString().setNum(l1.angle()), l2.angle(), + QString().setNum(l2.angle()), 0, "0")); + arc1->setMode(Draw::Modeling); + + QScopedPointer<VEllipticalArc> arc2(new VEllipticalArc(*arc1)); + + const quint32 idObject = initData.data->AddGObject(arc1.take()); + children.append(idObject); + + arc2->setMode(Draw::Modeling); + const quint32 id = initData.data->AddGObject(arc2.take()); + + VNodeEllipticalArc::Create(initData.doc, initData.data, id, idObject, Document::FullParse, Source::FromGui, + drawName, idTool); + return id; +} + +//--------------------------------------------------------------------------------------------------------------------- +quint32 AddNodeSpline(const VPieceNode &node, const VToolUnionDetailsInitData &initData, quint32 idTool, + QVector<quint32> &children, const QString &drawName, qreal dx, qreal dy, + quint32 pRotate, qreal angle) +{ + const QSharedPointer<VAbstractCubicBezier> spline = + initData.data->GeometricObject<VAbstractCubicBezier>(node.GetId()); + + QScopedPointer<VPointF> p1(new VPointF(spline->GetP1())); + VPointF p2 = VPointF(spline->GetP2()); + VPointF p3 = VPointF(spline->GetP3()); + QScopedPointer<VPointF> p4(new VPointF(spline->GetP4())); + + if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) + { + const QPointF p = *initData.data->GeometricObject<VPointF>(pRotate); + + BiasRotatePoint(p1.data(), dx, dy, p, angle); + BiasRotatePoint(&p2, dx, dy, p, angle); + BiasRotatePoint(&p3, dx, dy, p, angle); + BiasRotatePoint(p4.data(), dx, dy, p, angle); + } + + VSpline *spl = new VSpline(*p1, p2, p3, *p4, 0, Draw::Modeling); + const quint32 idObject = initData.data->AddGObject(spl); + children.append(idObject); + + VSpline *spl1 = new VSpline(*spl); + spl1->setMode(Draw::Modeling); + const quint32 id = initData.data->AddGObject(spl1); + VNodeSpline::Create(initData.doc, initData.data, id, idObject, Document::FullParse, Source::FromGui, drawName, + idTool); + return id; +} + +//--------------------------------------------------------------------------------------------------------------------- +quint32 AddNodeSplinePath(const VPieceNode &node, const VToolUnionDetailsInitData &initData, quint32 idTool, + QVector<quint32> &children, const QString &drawName, qreal dx, qreal dy, + quint32 pRotate, qreal angle) +{ + QScopedPointer<VSplinePath> path(new VSplinePath()); + path->setMode(Draw::Modeling); + const QSharedPointer<VAbstractCubicBezierPath> splinePath = + initData.data->GeometricObject<VAbstractCubicBezierPath>(node.GetId()); + for (qint32 i = 1; i <= splinePath->CountSubSpl(); ++i) + { + const VSpline spline = splinePath->GetSpline(i); + + QScopedPointer<VPointF> p1(new VPointF(spline.GetP1())); + VPointF p2 = VPointF(spline.GetP2()); + VPointF p3 = VPointF(spline.GetP3()); + QScopedPointer<VPointF> p4(new VPointF(spline.GetP4())); + if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) + { + const QPointF p = *initData.data->GeometricObject<VPointF>(pRotate); + + BiasRotatePoint(p1.data(), dx, dy, p, angle); + BiasRotatePoint(&p2, dx, dy, p, angle); + BiasRotatePoint(&p3, dx, dy, p, angle); + BiasRotatePoint(p4.data(), dx, dy, p, angle); + } + + VSpline spl = VSpline(*p1, p2, p3, *p4); + if (i==1) + { + const qreal angle1 = spl.GetStartAngle()+180; + const QString angle1F = QString().number(angle1); + + path->append(VSplinePoint(*p1, angle1, angle1F, spl.GetStartAngle(), spl.GetStartAngleFormula(), + 0, "0", spline.GetC1Length(), spline.GetC1LengthFormula())); + } + + const qreal angle2 = spl.GetEndAngle()+180; + const QString angle2F = QString().number(angle2); + qreal pL2 = 0; + QString pL2F("0"); + if (i+1 <= splinePath->CountSubSpl()) + { + const VSpline nextSpline = splinePath->GetSpline(i+1); + pL2 = nextSpline.GetC1Length(); + pL2F = nextSpline.GetC1LengthFormula(); + } + + path->append(VSplinePoint(*p4, spl.GetEndAngle(), spl.GetEndAngleFormula(), angle2, angle2F, + spline.GetC2Length(), spline.GetC2LengthFormula(), pL2, pL2F)); + } + QScopedPointer<VSplinePath> path1(new VSplinePath(*path)); + + const quint32 idObject = initData.data->AddGObject(path.take()); + children.append(idObject); + + path1->setMode(Draw::Modeling); + const quint32 id = initData.data->AddGObject(path1.take()); + + VNodeSplinePath::Create(initData.doc, initData.data, id, idObject, Document::FullParse, Source::FromGui, drawName, + idTool); + return id; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief AddToNewDetail create united detail adding one node per time. + */ +void AddNodeToNewPath(const VToolUnionDetailsInitData &initData, VPiecePath &newPath, const VPieceNode &node, + quint32 idTool, QVector<quint32> &children, const QString &drawName, qreal dx = 0, qreal dy = 0, + quint32 pRotate = NULL_ID, qreal angle = 0); + +void AddNodeToNewPath(const VToolUnionDetailsInitData &initData, VPiecePath &newPath, const VPieceNode &node, + quint32 idTool, QVector<quint32> &children, const QString &drawName, qreal dx, qreal dy, + quint32 pRotate, qreal angle) +{ + quint32 id = 0; + switch (node.GetTypeTool()) + { + case (Tool::NodePoint): + id = AddNodePoint(node, initData, idTool, children, drawName, dx, dy, pRotate, angle); + break; + case (Tool::NodeArc): + id = AddNodeArc(node, initData, idTool, children, drawName, dx, dy, pRotate, angle); + break; + case (Tool::NodeElArc): + id = AddNodeElArc(node, initData, idTool, children, drawName, dx, dy, pRotate, angle); + break; + case (Tool::NodeSpline): + id = AddNodeSpline(node, initData, idTool, children, drawName, dx, dy, pRotate, angle); + break; + case (Tool::NodeSplinePath): + id = AddNodeSplinePath(node, initData, idTool, children, drawName, dx, dy, pRotate, angle); + break; + default: + qDebug()<<"May be wrong tool type!!! Ignoring."<<Q_FUNC_INFO; + break; + } + newPath.Append(VPieceNode(id, node.GetTypeTool(), node.GetReverse())); +} + +//--------------------------------------------------------------------------------------------------------------------- +void FindIndexJ(qint32 pointsD2, const VPiecePath &d2Path, quint32 indexD2, qint32 &j) +{ + if (pointsD2 == 0) + { + VPieceNode node1; + VPieceNode node2; + d2Path.NodeOnEdge(indexD2, node1, node2); + const VPiecePath removedD2 = d2Path.RemoveEdge(indexD2); + const int k = removedD2.indexOfNode(node2.GetId()); + SCASSERT(k != -1) + if (k == removedD2.CountNodes()-1) + {//We have last node in detail, we wil begin from 0 + j = 0; + } + else + {// Continue from next node + j = k+1; + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +QDomElement GetTagChildren(VAbstractPattern *doc, quint32 id) +{ + QDomElement toolUnion = doc->elementById(id); + if (toolUnion.isNull()) + { + VException e(QString("Can't get tool by id='%1'.").arg(id)); + throw e; + } + + QDomElement tagChildren = toolUnion.firstChildElement(VToolUnionDetails::TagChildren); + + if (tagChildren.isNull()) + { + tagChildren = doc->createElement(VToolUnionDetails::TagChildren); + toolUnion.appendChild(tagChildren); + } + + return tagChildren; +} + +//--------------------------------------------------------------------------------------------------------------------- +void SaveChildren(VAbstractPattern *doc, quint32 id, QDomElement section, const QVector<quint32> &children) +{ + for (int i=0; i<children.size(); ++i) + { + QDomElement tagChild = doc->createElement(VToolUnionDetails::TagChild); + tagChild.appendChild(doc->createTextNode(QString().setNum(children.at(i)))); + section.appendChild(tagChild); + } + + GetTagChildren(doc, id).appendChild(section); +} + +//--------------------------------------------------------------------------------------------------------------------- +void SaveNodesChildren(VAbstractPattern *doc, quint32 id, const QVector<quint32> &children) +{ + SaveChildren(doc, id, doc->createElement(VAbstractPattern::TagNodes), children); +} + +//--------------------------------------------------------------------------------------------------------------------- +void SaveCSAChildren(VAbstractPattern *doc, quint32 id, const QVector<quint32> &children) +{ + SaveChildren(doc, id, doc->createElement(VToolSeamAllowance::TagCSA), children); +} + +//--------------------------------------------------------------------------------------------------------------------- +void SaveInternalPathsChildren(VAbstractPattern *doc, quint32 id, const QVector<quint32> &children) +{ + SaveChildren(doc, id, doc->createElement(VToolSeamAllowance::TagIPaths), children); +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<quint32> GetChildren(VAbstractPattern *doc, quint32 id, const QString &tagName) +{ + const QDomElement toolUnion = doc->elementById(id); + if (toolUnion.isNull()) + { + return QVector<quint32>(); + } + + const QDomElement tagChildren = toolUnion.firstChildElement(VToolUnionDetails::TagChildren); + if (tagChildren.isNull()) + { + return QVector<quint32>(); + } + + const QDomElement tagNodes = tagChildren.firstChildElement(tagName); + if (tagNodes.isNull()) + { + return QVector<quint32>(); + } + + QVector<quint32> childrenId; + const QDomNodeList listChildren = tagNodes.elementsByTagName(VToolUnionDetails::TagChild); + for (int i=0; i < listChildren.size(); ++i) + { + const QDomElement domElement = listChildren.at(i).toElement(); + if (not domElement.isNull()) + { + childrenId.append(domElement.text().toUInt()); + } + } + return childrenId; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<quint32> GetNodesChildren(VAbstractPattern *doc, quint32 id) +{ + return GetChildren(doc, id, VAbstractPattern::TagNodes); +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<quint32> GetCSAChildren(VAbstractPattern *doc, quint32 id) +{ + return GetChildren(doc, id, VToolSeamAllowance::TagCSA); +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<quint32> GetInternalPathsChildren(VAbstractPattern *doc, quint32 id) +{ + return GetChildren(doc, id, VToolSeamAllowance::TagIPaths); +} + +//--------------------------------------------------------------------------------------------------------------------- +quint32 TakeNextId(QVector<quint32> &children) +{ + quint32 idChild = NULL_ID; + if (not children.isEmpty()) + { +#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) + idChild = children.takeFirst(); +#else + idChild = children.first(); + children.remove(0); +#endif + } + else + { + idChild = NULL_ID; + } + return idChild; +} + +//--------------------------------------------------------------------------------------------------------------------- +void UpdateNodePoint(VContainer *data, const VPieceNode &node, QVector<quint32> &children, qreal dx, qreal dy, + quint32 pRotate, qreal angle) +{ + QScopedPointer<VPointF> point(new VPointF(*data->GeometricObject<VPointF>(node.GetId()))); + point->setMode(Draw::Modeling); + if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) + { + BiasRotatePoint(point.data(), dx, dy, *data->GeometricObject<VPointF>(pRotate), angle); + } + data->UpdateGObject(TakeNextId(children), point.take()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void UpdateNodeArc(VContainer *data, const VPieceNode &node, QVector<quint32> &children, qreal dx, qreal dy, + quint32 pRotate, qreal angle) +{ + const QSharedPointer<VArc> arc = data->GeometricObject<VArc>(node.GetId()); + VPointF p1 = VPointF(arc->GetP1()); + VPointF p2 = VPointF(arc->GetP2()); + QScopedPointer<VPointF> center(new VPointF(arc->GetCenter())); + + if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) + { + const QPointF p = *data->GeometricObject<VPointF>(pRotate); + + BiasRotatePoint(&p1, dx, dy, p, angle); + BiasRotatePoint(&p2, dx, dy, p, angle); + BiasRotatePoint(center.data(), dx, dy, p, angle); + } + + QLineF l1(*center, p1); + QLineF l2(*center, p2); + + QScopedPointer<VArc> arc1(new VArc(*center, arc->GetRadius(), arc->GetFormulaRadius(), l1.angle(), + QString().setNum(l1.angle()), l2.angle(), QString().setNum(l2.angle()))); + arc1->setMode(Draw::Modeling); + data->UpdateGObject(TakeNextId(children), arc1.take()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void UpdateNodeElArc(VContainer *data, const VPieceNode &node, QVector<quint32> &children, qreal dx, qreal dy, + quint32 pRotate, qreal angle) +{ + const QSharedPointer<VEllipticalArc> arc = data->GeometricObject<VEllipticalArc>(node.GetId()); + VPointF p1 = VPointF(arc->GetP1()); + VPointF p2 = VPointF(arc->GetP2()); + QScopedPointer<VPointF> center(new VPointF(arc->GetCenter())); + + if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) + { + const QPointF p = *data->GeometricObject<VPointF>(pRotate); + + BiasRotatePoint(&p1, dx, dy, p, angle); + BiasRotatePoint(&p2, dx, dy, p, angle); + BiasRotatePoint(center.data(), dx, dy, p, angle); + } + + QLineF l1(*center, p1); + QLineF l2(*center, p2); + + QScopedPointer<VEllipticalArc> arc1(new VEllipticalArc (*center, arc->GetRadius1(), arc->GetRadius2(), + arc->GetFormulaRadius1(), arc->GetFormulaRadius2(), + l1.angle(), QString().setNum(l1.angle()), l2.angle(), + QString().setNum(l2.angle()), 0, "0")); + arc1->setMode(Draw::Modeling); + data->UpdateGObject(TakeNextId(children), arc1.take()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void UpdateNodeSpline(VContainer *data, const VPieceNode &node, QVector<quint32> &children, qreal dx, qreal dy, + quint32 pRotate, qreal angle) +{ + const QSharedPointer<VAbstractCubicBezier> spline = + data->GeometricObject<VAbstractCubicBezier>(node.GetId()); + + QScopedPointer<VPointF> p1(new VPointF(spline->GetP1())); + VPointF p2 = VPointF(spline->GetP2()); + VPointF p3 = VPointF(spline->GetP3()); + QScopedPointer<VPointF> p4(new VPointF(spline->GetP4())); + + if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) + { + const QPointF p = *data->GeometricObject<VPointF>(pRotate); + + BiasRotatePoint(p1.data(), dx, dy, p, angle); + BiasRotatePoint(&p2, dx, dy, p, angle); + BiasRotatePoint(&p3, dx, dy, p, angle); + BiasRotatePoint(p4.data(), dx, dy, p, angle); + } + + QScopedPointer<VSpline> spl(new VSpline(*p1, p2, p3, *p4, 0, Draw::Modeling)); + data->UpdateGObject(TakeNextId(children), spl.take()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void UpdateNodeSplinePath(VContainer *data, const VPieceNode &node, QVector<quint32> &children, qreal dx, qreal dy, + quint32 pRotate, qreal angle) +{ + QScopedPointer<VSplinePath> path(new VSplinePath()); + path->setMode(Draw::Modeling); + const QSharedPointer<VAbstractCubicBezierPath> splinePath = + data->GeometricObject<VAbstractCubicBezierPath>(node.GetId()); + SCASSERT(splinePath != nullptr) + for (qint32 i = 1; i <= splinePath->CountSubSpl(); ++i) + { + const VSpline spline = splinePath->GetSpline(i); + + QScopedPointer<VPointF> p1(new VPointF(spline.GetP1())); + VPointF p2 = VPointF(spline.GetP2()); + VPointF p3 = VPointF(spline.GetP3()); + QScopedPointer<VPointF> p4(new VPointF(spline.GetP4())); + + if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) + { + const QPointF p = *data->GeometricObject<VPointF>(pRotate); + + BiasRotatePoint(p1.data(), dx, dy, p, angle); + BiasRotatePoint(&p2, dx, dy, p, angle); + BiasRotatePoint(&p3, dx, dy, p, angle); + BiasRotatePoint(p4.data(), dx, dy, p, angle); + } + + VSpline spl = VSpline(*p1, p2, p3, *p4); + if (i==1) + { + const qreal angle1 = spl.GetStartAngle()+180; + const QString angle1F = QString().number(angle1); + + path->append(VSplinePoint(*p1, angle1, angle1F, spl.GetStartAngle(), spl.GetStartAngleFormula(), + 0, "0", spline.GetC1Length(), spline.GetC1LengthFormula())); + } + + const qreal angle2 = spl.GetEndAngle()+180; + const QString angle2F = QString().number(angle2); + + qreal pL2 = 0; + QString pL2F("0"); + if (i+1 <= splinePath->CountSubSpl()) + { + const VSpline nextSpline = splinePath->GetSpline(i+1); + pL2 = nextSpline.GetC1Length(); + pL2F = nextSpline.GetC1LengthFormula(); + } + + path->append(VSplinePoint(*p4, spl.GetEndAngle(), spl.GetEndAngleFormula(), angle2, angle2F, + spline.GetC2Length(), spline.GetC2LengthFormula(), pL2, pL2F)); + } + data->UpdateGObject(TakeNextId(children), path.take()); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief UpdateNodes update nodes of united detail. + * @param data container with variables. + * @param det detail's nodes. + * @param i index node in detail. + * @param children list ids of all children. + * @param dx bias node x axis. + * @param dy bias node y axis. + * @param pRotate point rotation. + * @param angle angle rotation. + */ +void UpdatePathNode(VContainer *data, const VPieceNode &node, QVector<quint32> &children, + qreal dx = 0, qreal dy = 0, quint32 pRotate = NULL_ID, qreal angle = 0); +void UpdatePathNode(VContainer *data, const VPieceNode &node, QVector<quint32> &children, qreal dx, qreal dy, + quint32 pRotate, qreal angle) +{ + switch (node.GetTypeTool()) + { + case (Tool::NodePoint): + UpdateNodePoint(data, node, children, dx, dy, pRotate, angle); + break; + case (Tool::NodeArc): + UpdateNodeArc(data, node, children, dx, dy, pRotate, angle); + break; + case (Tool::NodeElArc): + UpdateNodeElArc(data, node, children, dx, dy, pRotate, angle); + break; + case (Tool::NodeSpline): + UpdateNodeSpline(data, node, children, dx, dy, pRotate, angle); + break; + case (Tool::NodeSplinePath): + UpdateNodeSplinePath(data, node, children, dx, dy, pRotate, angle); + break; + default: + qDebug()<<"May be wrong tool type!!! Ignoring."<<Q_FUNC_INFO; + break; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void CreateUnitedNodes(VPiece &newDetail, const VPiece &d1, const VPiece &d2, quint32 id, const QString &drawName, + const VToolUnionDetailsInitData &initData, qreal dx, qreal dy, quint32 pRotate, qreal angle) +{ + const VPiecePath d1Path = d1.GetPath().RemoveEdge(initData.indexD1); + const VPiecePath d2Path = d2.GetPath().RemoveEdge(initData.indexD2); + + const qint32 countNodeD1 = d1Path.CountNodes(); + const qint32 countNodeD2 = d2Path.CountNodes(); + + qint32 pointsD2 = 0; //Keeps number points the second detail, what we have already added. + qint32 i = 0; + QVector<quint32> children; + VPiecePath newPath; + const int det1P1Index = d1.GetPath().indexOfNode(pRotate); + do + { + AddNodeToNewPath(initData, newPath, d1Path.at(i), id, children, drawName); + ++i; + if (i > det1P1Index && pointsD2 < countNodeD2-1) + { + qint32 j = 0; + FindIndexJ(pointsD2, d2.GetPath(), initData.indexD2, j); + do + { + if (j >= countNodeD2) + { + j=0; + } + AddNodeToNewPath(initData, newPath, d2Path.at(j), id, children, drawName, dx, dy, pRotate, angle); + ++pointsD2; + ++j; + } while (pointsD2 < countNodeD2-1); + } + } while (i < countNodeD1); + + newDetail.SetPath(newPath); + + SCASSERT(not children.isEmpty()) + SaveNodesChildren(initData.doc, id, children); +} + +//--------------------------------------------------------------------------------------------------------------------- +void CreateUnitedDetailCSA(VPiece &newDetail, const VPiece &d, QVector<quint32> &children, quint32 id, + const QString &drawName, const VToolUnionDetailsInitData &initData, qreal dx, qreal dy, + quint32 pRotate, qreal angle) +{ + QVector<CustomSARecord> newList = newDetail.GetCustomSARecords(); + const QVector<CustomSARecord> oldList = d.GetCustomSARecords(); + QVector<quint32> nodeChildren; + for(int i=0; i < oldList.size(); ++i) + { + CustomSARecord record = oldList.at(i); + const VPiecePath path = initData.data->GetPiecePath(record.path); + VPiecePath newPath = path; + newPath.Clear();//Clear nodes + for (int i=0; i < path.CountNodes(); ++i) + { + AddNodeToNewPath(initData, newPath, path.at(i), id, nodeChildren, drawName, dx, dy, pRotate, angle); + } + const quint32 idPath = initData.data->AddPiecePath(newPath); + VToolPiecePath::Create(idPath, newPath, NULL_ID, initData.scene, initData.doc, initData.data, initData.parse, + Source::FromTool, drawName, id); + record.path = idPath; + newList.append(record); + nodeChildren.prepend(idPath); + } + children += nodeChildren; + newDetail.SetCustomSARecords(newList); +} + +//--------------------------------------------------------------------------------------------------------------------- +void CreateUnitedCSA(VPiece &newDetail, const VPiece &d1, const VPiece &d2, quint32 id, const QString &drawName, + const VToolUnionDetailsInitData &initData, qreal dx, qreal dy, quint32 pRotate, qreal angle) +{ + const QVector<CustomSARecord> d1Records = d1.GetCustomSARecords(); + for (int i = 0; i < d1Records.size(); ++i) + { + newDetail.AppendCustomSARecord(d1Records.at(i)); + } + + QVector<quint32> children; + CreateUnitedDetailCSA(newDetail, d2, children, id, drawName, initData, dx, dy, pRotate, angle); + + SCASSERT(not children.isEmpty()) + SaveCSAChildren(initData.doc, id, children); +} + +//--------------------------------------------------------------------------------------------------------------------- +void CreateUnitedDetailInternalPaths(VPiece &newDetail, const VPiece &d, QVector<quint32> &children, quint32 id, + const QString &drawName, const VToolUnionDetailsInitData &initData, qreal dx, + qreal dy, quint32 pRotate, qreal angle) +{ + QVector<quint32> newList = newDetail.GetInternalPaths(); + const QVector<quint32> oldList = d.GetInternalPaths(); + QVector<quint32> nodeChildren; + for(int i=0; i < oldList.size(); ++i) + { + const VPiecePath path = initData.data->GetPiecePath(oldList.at(i)); + VPiecePath newPath = path; + newPath.Clear();//Clear nodes + + for (int i=0; i < path.CountNodes(); ++i) + { + AddNodeToNewPath(initData, newPath, path.at(i), id, nodeChildren, drawName, dx, dy, pRotate, angle); + } + const quint32 idPath = initData.data->AddPiecePath(newPath); + VToolPiecePath::Create(idPath, newPath, NULL_ID, initData.scene, initData.doc, initData.data, initData.parse, + Source::FromTool, drawName, id); + newList.append(idPath); + nodeChildren.prepend(idPath); + } + children += nodeChildren; + newDetail.SetInternalPaths(newList); +} + +//--------------------------------------------------------------------------------------------------------------------- +void CreateUnitedInternalPaths(VPiece &newDetail, const VPiece &d1, const VPiece &d2, quint32 id, + const QString &drawName, const VToolUnionDetailsInitData &initData, qreal dx, qreal dy, + quint32 pRotate, qreal angle) +{ + const QVector<quint32> d1Internal = d1.GetInternalPaths(); + for (int i = 0; i < d1Internal.size(); ++i) + { + newDetail.AppendInternalPath(d1Internal.at(i)); + } + + QVector<quint32> children; + CreateUnitedDetailInternalPaths(newDetail, d2, children, id, drawName, initData, dx, dy, pRotate, angle); + + SCASSERT(not children.isEmpty()) + SaveInternalPathsChildren(initData.doc, id, children); +} + +//--------------------------------------------------------------------------------------------------------------------- +void UpdateUnitedNodes(quint32 id, const VToolUnionDetailsInitData &initData, qreal dx, qreal dy, quint32 pRotate, + qreal angle) +{ + const VPiecePath d1Path = GetPiece1MainPath(initData.doc, id); + const VPiecePath d1REPath = d1Path.RemoveEdge(initData.indexD1); + + const VPiecePath d2Path = GetPiece2MainPath(initData.doc, id); + const VPiecePath d2REPath = d2Path.RemoveEdge(initData.indexD2); + + const qint32 countNodeD1 = d1REPath.CountNodes(); + const qint32 countNodeD2 = d2REPath.CountNodes(); + + QVector<quint32> children = GetNodesChildren(initData.doc, id); + if (not children.isEmpty()) + { + // This check need for backward compatibility + // Remove check and "else" part if min version is 0.3.2 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 3, 2), + "Time to refactor the code."); + if (children.size() == countNodeD1 + countNodeD2-1) + { + qint32 pointsD2 = 0; //Keeps number points the second detail, what we have already added. + qint32 i = 0; + const int indexOfNode = d1Path.indexOfNode(pRotate); + do + { + UpdatePathNode(initData.data, d1REPath.at(i), children); + ++i; + if (i > indexOfNode && pointsD2 < countNodeD2-1) + { + qint32 j = 0; + FindIndexJ(pointsD2, d2Path, initData.indexD2, j); + do + { + if (j >= countNodeD2) + { + j=0; + } + UpdatePathNode(initData.data, d2REPath.at(j), children, dx, dy, pRotate, angle); + ++pointsD2; + ++j; + } while (pointsD2 < countNodeD2-1); + } + } while (i<countNodeD1); + } + else // remove if min version is 0.3.2 + { + qint32 pointsD2 = 0; //Keeps number points the second detail, what we have already added. + qint32 i = 0; + const int indexOfNode = d1Path.indexOfNode(pRotate); + do + { + ++i; + if (i > indexOfNode) + { + const int childrenCount = children.size(); + qint32 j = 0; + FindIndexJ(pointsD2, d2Path, initData.indexD2, j); + do + { + if (j >= countNodeD2) + { + j=0; + } + UpdatePathNode(initData.data, d2REPath.at(j), children, dx, dy, pRotate, angle); + ++pointsD2; + ++j; + } while (pointsD2 < childrenCount); + break; + } + } while (i<countNodeD1); + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void UpdateUnitedDetailPaths(const VToolUnionDetailsInitData &initData, qreal dx, qreal dy, quint32 pRotate, + qreal angle, const QVector<quint32> &records, QVector<quint32> children) +{ + for (int i=0; i < records.size(); ++i) + { + const VPiecePath path = initData.data->GetPiecePath(records.at(i)); + const quint32 updatedId = TakeNextId(children); + + VPiecePath updatedPath(path); + updatedPath.Clear(); + + for (int j=0; j < path.CountNodes(); ++j) + { + const VPieceNode &node = path.at(j); + const quint32 id = TakeNextId(children); + updatedPath.Append(VPieceNode(id, node.GetTypeTool(), node.GetReverse())); + QVector<quint32> nodeChildren = {id}; + UpdatePathNode(initData.data, path.at(j), nodeChildren, dx, dy, pRotate, angle); + } + initData.data->UpdatePiecePath(updatedId, updatedPath); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void UpdateUnitedDetailCSA(quint32 id, const VToolUnionDetailsInitData &initData, qreal dx, qreal dy, quint32 pRotate, + qreal angle, const QVector<CustomSARecord> &records) +{ + QVector<quint32> idRecords; + for (int i = 0; i < records.size(); ++i) + { + idRecords.append(records.at(i).path); + } + UpdateUnitedDetailPaths(initData, dx, dy, pRotate, angle, idRecords, GetCSAChildren(initData.doc, id)); +} + +//--------------------------------------------------------------------------------------------------------------------- +void UpdateUnitedDetailInternalPaths(quint32 id, const VToolUnionDetailsInitData &initData, qreal dx, qreal dy, + quint32 pRotate, qreal angle, const QVector<quint32> &records) +{ + UpdateUnitedDetailPaths(initData, dx, dy, pRotate, angle, records, GetInternalPathsChildren(initData.doc, id)); +} + +//--------------------------------------------------------------------------------------------------------------------- +void CreateUnitedDetail(quint32 id, const VToolUnionDetailsInitData &initData, qreal dx, qreal dy, quint32 pRotate, + qreal angle) +{ + const QString drawName = DrawName(initData.doc, initData.d1id, initData.d2id); + SCASSERT(not drawName.isEmpty()) + + const VPiece d1 = initData.data->GetPiece(initData.d1id); + const VPiece d2 = initData.data->GetPiece(initData.d2id); + + VPiece newDetail; + + CreateUnitedNodes(newDetail, d1, d2, id, drawName, initData, dx, dy, pRotate, angle); + CreateUnitedCSA(newDetail, d1, d2, id, drawName, initData, dx, dy, pRotate, angle); + CreateUnitedInternalPaths(newDetail, d1, d2, id, drawName, initData, dx, dy, pRotate, angle); + + newDetail.SetName(QObject::tr("United detail")); + QString formulaSAWidth = d1.GetFormulaSAWidth(); + newDetail.SetFormulaSAWidth(formulaSAWidth, d1.GetSAWidth()); + newDetail.SetMx(d1.GetMx()); + newDetail.SetMy(d1.GetMy()); + newDetail.SetUnited(true); + VToolSeamAllowance::Create(0, newDetail, formulaSAWidth, initData.scene, initData.doc, initData.data, + initData.parse, Source::FromTool, drawName); + + auto RemoveDetail = [initData](quint32 id) + { + VToolSeamAllowance *toolDet = qobject_cast<VToolSeamAllowance*>(initData.doc->getTool(id)); + SCASSERT(toolDet != nullptr); + bool ask = false; + toolDet->Remove(ask); + // We do not call full parse, so will need more to do more cleaning than usually + initData.doc->RemoveTool(id); + initData.data->RemovePiece(id); + }; + + if (not initData.retainPieces) + { + RemoveDetail(initData.d1id); + RemoveDetail(initData.d2id); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void UpdateUnitedDetail(quint32 id, const VToolUnionDetailsInitData &initData, qreal dx, qreal dy, quint32 pRotate, + qreal angle) +{ + UpdateUnitedNodes(id, initData, dx, dy, pRotate, angle); + UpdateUnitedDetailCSA(id, initData, dx, dy, pRotate, angle, GetPiece2CSAPaths(initData.doc, id)); + UpdateUnitedDetailInternalPaths(id, initData, dx, dy, pRotate, angle, GetPiece2InternalPaths(initData.doc, id)); +} + +//--------------------------------------------------------------------------------------------------------------------- +void UniteDetails(quint32 id, const VToolUnionDetailsInitData &initData) +{ + VPieceNode det1p1; + qreal dx = 0; + qreal dy = 0; + qreal angle = 0; + + if (initData.typeCreation == Source::FromGui) + { + const VPiece d1 = initData.data->GetPiece(initData.d1id); + const VPiece d2 = initData.data->GetPiece(initData.d2id); + UnionInitParameters(initData, d1.GetPath(), d2.GetPath(), det1p1, dx, dy, angle); + CreateUnitedDetail(id, initData, dx, dy, det1p1.GetId(), angle); + } + else + { + const VPiecePath d1Path = GetPiece1MainPath(initData.doc, id); + const VPiecePath d2Path = GetPiece2MainPath(initData.doc, id); + UnionInitParameters(initData, d1Path, d2Path, det1p1, dx, dy, angle); + UpdateUnitedDetail(id, initData, dx, dy, det1p1.GetId(), angle); + } +} +} // static functions + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VToolUnionDetails costructor. + * @param id object id in container. + * @param initData global init data. + * @param parent parent object. + */ +VToolUnionDetails::VToolUnionDetails(quint32 id, const VToolUnionDetailsInitData &initData, + QObject *parent) + : VAbstractTool(initData.doc, initData.data, id, parent), + d1id(initData.d1id), + d2id(initData.d2id), + indexD1(initData.indexD1), + indexD2(initData.indexD2) +{ + _referens = 0; + ToolCreation(initData.typeCreation); +} + +//--------------------------------------------------------------------------------------------------------------------- +QString VToolUnionDetails::getTagName() const +{ + return VAbstractPattern::TagTools; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolUnionDetails::ShowVisualization(bool show) +{ + Q_UNUSED(show) +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolUnionDetails::incrementReferens() +{ + VDataTool::incrementReferens(); + if (_referens == 1) + { + const QVector<quint32> objects = GetReferenceObjects(); + for(int i = 0; i < objects.size(); ++i) + { + doc->IncrementReferens(objects.at(i)); + } + + QDomElement domElement = doc->elementById(id); + if (domElement.isElement()) + { + doc->SetParametrUsage(domElement, AttrInUse, NodeUsage::InUse); + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolUnionDetails::decrementReferens() +{ + VDataTool::decrementReferens(); + if (_referens == 0) + { + const QVector<quint32> objects = GetReferenceObjects(); + for(int i = 0; i < objects.size(); ++i) + { + doc->DecrementReferens(objects.at(i)); + } + + QDomElement domElement = doc->elementById(id); + if (domElement.isElement()) + { + doc->SetParametrUsage(domElement, AttrInUse, NodeUsage::NotInUse); + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolUnionDetails::GroupVisibility(quint32 object, bool visible) +{ + Q_UNUSED(object) + Q_UNUSED(visible) +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Create help create tool from GUI. + * @param dialog dialog. + * @param doc dom document container. + * @param data container with variables. + */ +VToolUnionDetails* VToolUnionDetails::Create(DialogTool *dialog, VMainGraphicsScene *scene, VAbstractPattern *doc, + VContainer *data) +{ + SCASSERT(dialog != nullptr) + const DialogUnionDetails *dialogTool = qobject_cast<DialogUnionDetails*>(dialog); + SCASSERT(dialogTool != nullptr) + + VToolUnionDetailsInitData initData; + initData.d1id = dialogTool->getD1(); + initData.d2id = dialogTool->getD2(); + initData.indexD1 = static_cast<quint32>(dialogTool->getIndexD1()); + initData.indexD2 = static_cast<quint32>(dialogTool->getIndexD2()); + initData.scene = scene; + initData.doc = doc; + initData.data = data; + initData.parse = Document::FullParse; + initData.typeCreation = Source::FromGui; + initData.retainPieces = dialogTool->RetainPieces(); + + qApp->getUndoStack()->beginMacro(tr("union details")); + VToolUnionDetails* tool = Create(0, initData); + qApp->getUndoStack()->endMacro(); + return tool; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Create help create tool. + * @param _id tool id, 0 if tool doesn't exist yet. + * @param d1 first detail. + * @param d2 second detail. + * @param d1id id first detail. + * @param d2id id second detail. + * @param indexD1 index edge in first detail. + * @param indexD2 index edge in second detail. + * @param scene pointer to scene. + * @param doc dom document container. + * @param data container with variables. + * @param parse parser file mode. + * @param typeCreation way we create this tool. + */ +VToolUnionDetails* VToolUnionDetails::Create(const quint32 _id, const VToolUnionDetailsInitData &initData) +{ + VToolUnionDetails *unionDetails = nullptr; + quint32 id = _id; + if (initData.typeCreation == Source::FromGui) + { + id = initData.data->getNextId(); + } + else + { + if (initData.parse != Document::FullParse) + { + initData.doc->UpdateToolData(id, initData.data); + } + } + + //First add tool to file + VAbstractTool::AddRecord(id, Tool::UnionDetails, initData.doc); + if (initData.parse == Document::FullParse) + { + //Scene doesn't show this tool, so doc will destroy this object. + unionDetails = new VToolUnionDetails(id, initData); + initData.doc->AddTool(id, unionDetails); + // Unfortunatelly doc will destroy all objects only in the end, but we should delete them before each FullParse + initData.doc->AddToolOnRemove(unionDetails); + } + UniteDetails(id, initData); + return unionDetails; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief AddToFile add tag with informations about tool into file. + */ +void VToolUnionDetails::AddToFile() +{ + QDomElement domElement = doc->createElement(getTagName()); + + doc->SetAttribute(domElement, VDomDocument::AttrId, id); + doc->SetAttribute(domElement, AttrType, ToolType); + doc->SetAttribute(domElement, AttrIndexD1, indexD1); + doc->SetAttribute(domElement, AttrIndexD2, indexD2); + + AddDetail(domElement, data.GetPiece(d1id)); + AddDetail(domElement, data.GetPiece(d2id)); + + AddToModeling(domElement); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief RefreshDataInFile refresh attributes in file. If attributes don't exist create them. + */ +void VToolUnionDetails::RefreshDataInFile() +{ + // do nothing +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief AddDetail add detail to xml file. + * @param domElement tag in xml tree. + * @param d detail. + */ +void VToolUnionDetails::AddDetail(QDomElement &domElement, const VPiece &d) const +{ + QDomElement det = doc->createElement(TagDetail); + + // nodes + VToolSeamAllowance::AddNodes(doc, det, d); + //custom seam allowance + VToolSeamAllowance::AddCSARecords(doc, det, d.GetCustomSARecords()); + VToolSeamAllowance::AddInternalPaths(doc, det, d.GetInternalPaths()); + + domElement.appendChild(det); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief AddToModeling add tool to xml tree. + * @param domElement tag in xml tree. + */ +void VToolUnionDetails::AddToModeling(const QDomElement &domElement) +{ + const QString drawName = DrawName(doc, d1id, d2id); + SCASSERT(not drawName.isEmpty()) + + QDomElement modeling = doc->GetDraw(drawName).firstChildElement(VAbstractPattern::TagModeling); + if (not modeling.isNull()) + { + modeling.appendChild(domElement); + } + else + { + qCCritical(vToolUnion, "Can't find tag %s.", qUtf8Printable(VAbstractPattern::TagModeling)); + return; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<quint32> VToolUnionDetails::GetReferenceObjects() const +{ + QVector<quint32> list; + const QDomElement tool = doc->elementById(id); + if (tool.isNull()) + { + return list; + } + + const QStringList parts = QStringList() << VAbstractPattern::TagNodes /*0*/ + << VToolSeamAllowance::TagCSA /*1*/ + << VToolSeamAllowance::TagIPaths; /*2*/ + + const QDomNodeList nodesList = tool.childNodes(); + for (qint32 i = 0; i < nodesList.size(); ++i) + { + const QDomElement element = nodesList.at(i).toElement(); + if (not element.isNull() && element.tagName() == VToolUnionDetails::TagDetail) + { + const QDomNodeList detList = element.childNodes(); + for (qint32 j = 0; j < detList.size(); ++j) + { + const QDomElement element = detList.at(j).toElement(); + if (not element.isNull()) + { + switch (parts.indexOf(element.tagName())) + { + case 0://VAbstractPattern::TagNodes + list += ReferenceObjects(element, TagNode, AttrIdObject); + break; + case 1://VToolSeamAllowance::TagCSA + case 2://VToolSeamAllowance::TagIPaths + list += ReferenceObjects(element, VToolSeamAllowance::TagRecord, + VAbstractPattern::AttrPath); + break; + default: + break; + } + } + } + } + } + return list; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<quint32> VToolUnionDetails::ReferenceObjects(const QDomElement &root, const QString &tag, + const QString &attribute) const +{ + QVector<quint32> objects; + + const QDomNodeList list = root.childNodes(); + for (qint32 i = 0; i < list.size(); ++i) + { + const QDomElement element = list.at(i).toElement(); + if (not element.isNull() && element.tagName() == tag) + { + const quint32 id = doc->GetParametrUInt(element, attribute, NULL_ID_STR); + if (id > NULL_ID) + { + objects.append(id); + } + } + } + + return objects; +} diff --git a/src/libs/vtools/tools/vtooluniondetails.h b/src/libs/vtools/tools/vtooluniondetails.h index fae483cda..a0d652bbe 100644 --- a/src/libs/vtools/tools/vtooluniondetails.h +++ b/src/libs/vtools/tools/vtooluniondetails.h @@ -43,7 +43,7 @@ #include "../ifc/xml/vabstractpattern.h" #include "../vmisc/def.h" #include "vabstracttool.h" -#include "vdetail.h" +#include "../vpatterndb/vpiece.h" class DialogTool; class QDomElement; @@ -51,9 +51,35 @@ class QDomNode; class QPointF; class VContainer; class VMainGraphicsScene; -class VNodeDetail; class VPointF; +struct VToolUnionDetailsInitData +{ + VToolUnionDetailsInitData() + : d1id(NULL_ID), + d2id(NULL_ID), + indexD1(NULL_ID), + indexD2(NULL_ID), + scene(nullptr), + doc(nullptr), + data(nullptr), + parse(Document::FullParse), + typeCreation(Source::FromFile), + retainPieces(false) + {} + + quint32 d1id; + quint32 d2id; + quint32 indexD1; + quint32 indexD2; + VMainGraphicsScene *scene; + VAbstractPattern *doc; + VContainer *data; + Document parse; + Source typeCreation; + bool retainPieces; +}; + /** * @brief The VToolUnionDetails class tool union details. */ @@ -67,15 +93,7 @@ public: virtual void setDialog() {} static VToolUnionDetails *Create(DialogTool *dialog, VMainGraphicsScene *scene, VAbstractPattern *doc, VContainer *data); - static VToolUnionDetails *Create(const quint32 _id, const VDetail &d1, const VDetail &d2, const quint32 &d1id, - const quint32 &d2id, const quint32 &indexD1, const quint32 &indexD2, - VMainGraphicsScene *scene, VAbstractPattern *doc, VContainer *data, - const Document &parse, - const Source &typeCreation, - bool retainPieces = false); - static void PointsOnEdge(const VDetail &d, const quint32 &index, VPointF &p1, VPointF &p2, VContainer *data); - static void FindIndexJ(const qint32 &pointsD2, const VDetail &d2, const quint32 &indexD2, qint32 &j); - static QVector<VDetail> GetDetailFromFile(VAbstractPattern *doc, const QDomElement &domElement); + static VToolUnionDetails *Create(const quint32 _id, const VToolUnionDetailsInitData &initData); static const QString ToolType; static const QString TagDetail; @@ -88,15 +106,7 @@ public: static const QString AttrNodeType; static const QString NodeTypeContour; static const QString NodeTypeModeling; - static void AddToNewDetail(VMainGraphicsScene *scene, VAbstractPattern *doc, VContainer *data, - VDetail &newDetail, const VDetail &det, const int &i, const quint32 &idTool, - QVector<quint32> &children, const QString &drawName, const qreal &dx = 0, - const qreal &dy = 0, const quint32 &pRotate = NULL_ID, const qreal &angle = 0); - static void UpdatePoints(VContainer *data, const VDetail &det, const int &i, - QVector<quint32> &children, const qreal &dx = 0, const qreal &dy = 0, - const quint32 &pRotate = NULL_ID, const qreal &angle = 0); - static void BiasRotatePoint(VPointF *point, const qreal &dx, const qreal &dy, const QPointF &pRotate, - const qreal &angle); + virtual QString getTagName() const Q_DECL_OVERRIDE; virtual void ShowVisualization(bool show) Q_DECL_OVERRIDE; virtual void incrementReferens() Q_DECL_OVERRIDE; @@ -115,35 +125,24 @@ protected: virtual void SetVisualization() Q_DECL_OVERRIDE {} private: Q_DISABLE_COPY(VToolUnionDetails) - /** @brief d1 first detail. */ - VDetail d1; + /** @brief d1 first detail id. */ + quint32 d1id; - /** @brief d2 second detail. */ - VDetail d2; + /** @brief d2 second detail id. */ + quint32 d2id; /** @brief indexD1 index edge in first detail. */ - quint32 indexD1; + quint32 indexD1; /** @brief indexD2 index edge in second detail. */ - quint32 indexD2; + quint32 indexD2; - QString drawName; + VToolUnionDetails(quint32 id, const VToolUnionDetailsInitData &initData, QObject *parent = nullptr); - VToolUnionDetails(VAbstractPattern *doc, VContainer *data, const quint32 &id, const VDetail &d1, const VDetail &d2, - const quint32 &indexD1, const quint32 &indexD2, const Source &typeCreation, - const QString &drawName, QObject *parent = nullptr); - - void AddDetail(QDomElement &domElement, VDetail &d); - void AddNode(QDomElement &domElement, const VNodeDetail &node); - QDomNode UpdateDetail(const QDomNode &domNode, const VDetail &d); - void AddToModeling(const QDomElement &domElement); - void IncrementReferences(const VDetail &d) const; - void DecrementReferences(const VDetail &d) const; - - static void SaveChildren(VAbstractPattern *doc, quint32 id, const QVector<quint32> &children); - static QVector<quint32> AllChildren(VAbstractPattern *doc, quint32 id); - static quint32 TakeNextId(QVector<quint32> &children); - static QString DrawName(VAbstractPattern *doc, quint32 d1id, quint32 d2id); + void AddDetail(QDomElement &domElement, const VPiece &d) const; + void AddToModeling(const QDomElement &domElement); + QVector<quint32> GetReferenceObjects() const; + QVector<quint32> ReferenceObjects(const QDomElement &root, const QString &tag, const QString &attribute) const; }; #endif // VTOOLUNIONDETAILS_H diff --git a/src/libs/vtools/undocommands/adddet.cpp b/src/libs/vtools/undocommands/addpiece.cpp similarity index 77% rename from src/libs/vtools/undocommands/adddet.cpp rename to src/libs/vtools/undocommands/addpiece.cpp index c2b9d4efe..9f4ccc2ff 100644 --- a/src/libs/vtools/undocommands/adddet.cpp +++ b/src/libs/vtools/undocommands/addpiece.cpp @@ -1,14 +1,14 @@ /************************************************************************ ** - ** @file adddet.cpp + ** @file ** @author Roman Telezhynskyi <dismine(at)gmail.com> - ** @date 15 6, 2014 + ** @date 6 11, 2016 ** ** @brief ** @copyright ** This source code is part of the Valentine project, a pattern making ** program, whose allow create and modeling patterns of clothing. - ** Copyright (C) 2013-2015 Valentina project + ** Copyright (C) 2016 Valentina project ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. ** ** Valentina is free software: you can redistribute it and/or modify @@ -26,34 +26,27 @@ ** *************************************************************************/ -#include "adddet.h" - -#include <QByteArray> -#include <QDomNode> - -#include "../ifc/xml/vabstractpattern.h" -#include "../vmisc/logging.h" -#include "vundocommand.h" - -class QDomElement; -class QUndoCommand; +#include "addpiece.h" +#include "../vpatterndb/vpiecenode.h" +#include "../vpatterndb/vpiecepath.h" //--------------------------------------------------------------------------------------------------------------------- -AddDet::AddDet(const QDomElement &xml, VAbstractPattern *doc, const VDetail &detail, const QString &drawName, - QUndoCommand *parent) - : VUndoCommand(xml, doc, parent), detail(detail), drawName(drawName) +AddPiece::AddPiece(const QDomElement &xml, VAbstractPattern *doc, const VPiece &detail, const QString &drawName, + QUndoCommand *parent) + : VUndoCommand(xml, doc, parent), + m_detail(detail), + m_drawName(drawName) { setText(tr("add detail")); nodeId = doc->GetParametrId(xml); } //--------------------------------------------------------------------------------------------------------------------- -AddDet::~AddDet() +AddPiece::~AddPiece() {} //--------------------------------------------------------------------------------------------------------------------- -// cppcheck-suppress unusedFunction -void AddDet::undo() +void AddPiece::undo() { qCDebug(vUndo, "Undo."); @@ -69,7 +62,9 @@ void AddDet::undo() return; } - DecrementReferences(detail.getNodes()); + DecrementReferences(m_detail.GetPath().GetNodes()); + DecrementReferences(m_detail.GetCustomSARecords()); + DecrementReferences(m_detail.GetInternalPaths()); } else { @@ -86,8 +81,7 @@ void AddDet::undo() } //--------------------------------------------------------------------------------------------------------------------- -// cppcheck-suppress unusedFunction -void AddDet::redo() +void AddPiece::redo() { qCDebug(vUndo, "Redo."); @@ -105,16 +99,16 @@ void AddDet::redo() } //--------------------------------------------------------------------------------------------------------------------- -QDomElement AddDet::GetDetailsSection() const +QDomElement AddPiece::GetDetailsSection() const { QDomElement details; - if (drawName.isEmpty()) + if (m_drawName.isEmpty()) { doc->GetActivNodeElement(VAbstractPattern::TagDetails, details); } else { - details = doc->GetDraw(drawName).firstChildElement(VAbstractPattern::TagDetails); + details = doc->GetDraw(m_drawName).firstChildElement(VAbstractPattern::TagDetails); } return details; } diff --git a/src/libs/vtools/undocommands/adddet.h b/src/libs/vtools/undocommands/addpiece.h similarity index 76% rename from src/libs/vtools/undocommands/adddet.h rename to src/libs/vtools/undocommands/addpiece.h index a6583cf6e..f04c6c7a6 100644 --- a/src/libs/vtools/undocommands/adddet.h +++ b/src/libs/vtools/undocommands/addpiece.h @@ -1,14 +1,14 @@ /************************************************************************ ** - ** @file adddet.h + ** @file ** @author Roman Telezhynskyi <dismine(at)gmail.com> - ** @date 15 6, 2014 + ** @date 6 11, 2016 ** ** @brief ** @copyright ** This source code is part of the Valentine project, a pattern making ** program, whose allow create and modeling patterns of clothing. - ** Copyright (C) 2013-2015 Valentina project + ** Copyright (C) 2016 Valentina project ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. ** ** Valentina is free software: you can redistribute it and/or modify @@ -26,8 +26,8 @@ ** *************************************************************************/ -#ifndef ADDDET_H -#define ADDDET_H +#ifndef ADDPIECE_H +#define ADDPIECE_H #include <qcompilerdetection.h> #include <QDomElement> @@ -36,31 +36,34 @@ #include <QString> #include <QtGlobal> -#include "../tools/vtooldetail.h" -#include "vdetail.h" +#include "../tools/vtoolseamallowance.h" +#include "vpiece.h" #include "vundocommand.h" class QDomElement; class QUndoCommand; class VAbstractPattern; -class AddDet : public VUndoCommand + +class AddPiece : public VUndoCommand { Q_OBJECT public: - AddDet(const QDomElement &xml, VAbstractPattern *doc, const VDetail &detail, const QString &drawName = QString(), - QUndoCommand *parent = 0); - virtual ~AddDet() Q_DECL_OVERRIDE; + AddPiece(const QDomElement &xml, VAbstractPattern *doc, const VPiece &detail, const QString &drawName = QString(), + QUndoCommand *parent = nullptr); + virtual ~AddPiece(); + // cppcheck-suppress unusedFunction virtual void undo() Q_DECL_OVERRIDE; // cppcheck-suppress unusedFunction virtual void redo() Q_DECL_OVERRIDE; private: - Q_DISABLE_COPY(AddDet) - VDetail detail; - QString drawName; + Q_DISABLE_COPY(AddPiece) + + VPiece m_detail; + QString m_drawName; QDomElement GetDetailsSection() const; }; -#endif // ADDDET_H +#endif // ADDPIECE_H diff --git a/src/libs/vtools/undocommands/deletedetail.cpp b/src/libs/vtools/undocommands/deletepiece.cpp similarity index 73% rename from src/libs/vtools/undocommands/deletedetail.cpp rename to src/libs/vtools/undocommands/deletepiece.cpp index a9f375b26..fba723c2f 100644 --- a/src/libs/vtools/undocommands/deletedetail.cpp +++ b/src/libs/vtools/undocommands/deletepiece.cpp @@ -1,14 +1,14 @@ /************************************************************************ ** - ** @file deletedetail.cpp + ** @file ** @author Roman Telezhynskyi <dismine(at)gmail.com> - ** @date 16 6, 2014 + ** @date 9 11, 2016 ** ** @brief ** @copyright ** This source code is part of the Valentine project, a pattern making ** program, whose allow create and modeling patterns of clothing. - ** Copyright (C) 2013-2015 Valentina project + ** Copyright (C) 2016 Valentina project ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. ** ** Valentina is free software: you can redistribute it and/or modify @@ -26,12 +26,11 @@ ** *************************************************************************/ -#include "deletedetail.h" +#include "deletepiece.h" #include <QDomElement> #include <QHash> -#include "../tools/vtooldetail.h" #include "../ifc/ifcdef.h" #include "../ifc/xml/vabstractpattern.h" #include "../ifc/xml/vdomdocument.h" @@ -39,12 +38,17 @@ #include "../vmisc/def.h" #include "../tools/vdatatool.h" #include "vundocommand.h" +#include "../vpatterndb/vpiecenode.h" +#include "../vpatterndb/vpiecepath.h" class QUndoCommand; //--------------------------------------------------------------------------------------------------------------------- -DeleteDetail::DeleteDetail(VAbstractPattern *doc, quint32 id, const VDetail &detail, QUndoCommand *parent) - : VUndoCommand(QDomElement(), doc, parent), parentNode(QDomNode()), siblingId(NULL_ID), detail(detail) +DeletePiece::DeletePiece(VAbstractPattern *doc, quint32 id, const VPiece &detail, QUndoCommand *parent) + : VUndoCommand(QDomElement(), doc, parent), + m_parentNode(), + m_siblingId(NULL_ID), + m_detail(detail) { setText(tr("delete tool")); nodeId = id; @@ -52,16 +56,16 @@ DeleteDetail::DeleteDetail(VAbstractPattern *doc, quint32 id, const VDetail &det if (domElement.isElement()) { xml = domElement.cloneNode().toElement(); - parentNode = domElement.parentNode(); + m_parentNode = domElement.parentNode(); QDomNode previousDetail = domElement.previousSibling(); if (previousDetail.isNull()) { - siblingId = NULL_ID; + m_siblingId = NULL_ID; } else { // Better save id of previous detail instead of reference to node. - siblingId = doc->GetParametrUInt(previousDetail.toElement(), VAbstractPattern::AttrId, NULL_ID_STR); + m_siblingId = doc->GetParametrUInt(previousDetail.toElement(), VAbstractPattern::AttrId, NULL_ID_STR); } } else @@ -72,37 +76,37 @@ DeleteDetail::DeleteDetail(VAbstractPattern *doc, quint32 id, const VDetail &det } //--------------------------------------------------------------------------------------------------------------------- -DeleteDetail::~DeleteDetail() +DeletePiece::~DeletePiece() {} //--------------------------------------------------------------------------------------------------------------------- -void DeleteDetail::undo() +void DeletePiece::undo() { qCDebug(vUndo, "Undo."); - UndoDeleteAfterSibling(parentNode, siblingId); + UndoDeleteAfterSibling(m_parentNode, m_siblingId); emit NeedFullParsing(); } //--------------------------------------------------------------------------------------------------------------------- -void DeleteDetail::redo() +void DeletePiece::redo() { qCDebug(vUndo, "Redo."); QDomElement domElement = doc->elementById(nodeId); if (domElement.isElement()) { - parentNode.removeChild(domElement); + m_parentNode.removeChild(domElement); // UnionDetails delete two old details and create one new. // So when UnionDetail delete detail we can't use FullParsing. So we hide detail on scene directly. - QHash<quint32, VDataTool*>* tools = doc->getTools(); - SCASSERT(tools != nullptr) - VToolDetail *toolDet = qobject_cast<VToolDetail*>(tools->value(nodeId)); - SCASSERT(toolDet != nullptr) + VToolSeamAllowance *toolDet = qobject_cast<VToolSeamAllowance*>(doc->getTool(nodeId)); + SCASSERT(toolDet != nullptr); toolDet->hide(); - DecrementReferences(detail.getNodes()); + DecrementReferences(m_detail.GetPath().GetNodes()); + DecrementReferences(m_detail.GetCustomSARecords()); + DecrementReferences(m_detail.GetInternalPaths()); emit NeedFullParsing(); // Doesn't work when UnionDetail delete detail. } else diff --git a/src/libs/vtools/undocommands/deletedetail.h b/src/libs/vtools/undocommands/deletepiece.h similarity index 68% rename from src/libs/vtools/undocommands/deletedetail.h rename to src/libs/vtools/undocommands/deletepiece.h index abbe30b7e..b06a77613 100644 --- a/src/libs/vtools/undocommands/deletedetail.h +++ b/src/libs/vtools/undocommands/deletepiece.h @@ -1,14 +1,14 @@ /************************************************************************ ** - ** @file deletedetail.h + ** @file ** @author Roman Telezhynskyi <dismine(at)gmail.com> - ** @date 16 6, 2014 + ** @date 9 11, 2016 ** ** @brief ** @copyright ** This source code is part of the Valentine project, a pattern making ** program, whose allow create and modeling patterns of clothing. - ** Copyright (C) 2013-2015 Valentina project + ** Copyright (C) 2016 Valentina project ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. ** ** Valentina is free software: you can redistribute it and/or modify @@ -26,37 +26,34 @@ ** *************************************************************************/ -#ifndef DELETEDETAIL_H -#define DELETEDETAIL_H +#ifndef DELETEPIECE_H +#define DELETEPIECE_H -#include <qcompilerdetection.h> -#include <QDomNode> -#include <QMetaObject> -#include <QObject> -#include <QString> #include <QtGlobal> -#include "../tools/vtooldetail.h" -#include "vdetail.h" +#include "../tools/vtoolseamallowance.h" +#include "vpiece.h" #include "vundocommand.h" class QGraphicsItem; class QUndoCommand; class VAbstractPattern; -class DeleteDetail : public VUndoCommand +class DeletePiece : public VUndoCommand { Q_OBJECT public: - DeleteDetail(VAbstractPattern *doc, quint32 id, const VDetail &detail, QUndoCommand *parent = 0); - virtual ~DeleteDetail() Q_DECL_OVERRIDE; + DeletePiece(VAbstractPattern *doc, quint32 id, const VPiece &m_detail, QUndoCommand *parent = nullptr); + virtual ~DeletePiece(); + virtual void undo() Q_DECL_OVERRIDE; virtual void redo() Q_DECL_OVERRIDE; private: - Q_DISABLE_COPY(DeleteDetail) - QDomNode parentNode; - quint32 siblingId; - VDetail detail; + Q_DISABLE_COPY(DeletePiece) + + QDomNode m_parentNode; + quint32 m_siblingId; + VPiece m_detail; }; -#endif // DELETEDETAIL_H +#endif // DELETEPIECE_H diff --git a/src/libs/vtools/undocommands/movedetail.cpp b/src/libs/vtools/undocommands/movepiece.cpp similarity index 77% rename from src/libs/vtools/undocommands/movedetail.cpp rename to src/libs/vtools/undocommands/movepiece.cpp index 333c331a0..ac5b324ac 100644 --- a/src/libs/vtools/undocommands/movedetail.cpp +++ b/src/libs/vtools/undocommands/movepiece.cpp @@ -26,7 +26,7 @@ ** *************************************************************************/ -#include "movedetail.h" +#include "movepiece.h" #include <QDomElement> @@ -42,9 +42,14 @@ class QDomElement; class QUndoCommand; //--------------------------------------------------------------------------------------------------------------------- -MoveDetail::MoveDetail(VAbstractPattern *doc, const double &x, const double &y, const quint32 &id, - QGraphicsScene *scene, QUndoCommand *parent) - : VUndoCommand(QDomElement(), doc, parent), oldX(0.0), oldY(0.0), newX(x), newY(y), scene(scene) +MovePiece::MovePiece(VAbstractPattern *doc, const double &x, const double &y, const quint32 &id, + QGraphicsScene *scene, QUndoCommand *parent) + : VUndoCommand(QDomElement(), doc, parent), + m_oldX(0.0), + m_oldY(0.0), + m_newX(x), + m_newY(y), + m_scene(scene) { setText(QObject::tr("move detail")); nodeId = id; @@ -53,8 +58,8 @@ MoveDetail::MoveDetail(VAbstractPattern *doc, const double &x, const double &y, QDomElement domElement = doc->elementById(id); if (domElement.isElement()) { - oldX = qApp->toPixel(doc->GetParametrDouble(domElement, AttrMx, "0.0")); - oldY = qApp->toPixel(doc->GetParametrDouble(domElement, AttrMy, "0.0")); + m_oldX = qApp->toPixel(doc->GetParametrDouble(domElement, AttrMx, "0.0")); + m_oldY = qApp->toPixel(doc->GetParametrDouble(domElement, AttrMy, "0.0")); } else { @@ -64,18 +69,18 @@ MoveDetail::MoveDetail(VAbstractPattern *doc, const double &x, const double &y, } //--------------------------------------------------------------------------------------------------------------------- -MoveDetail::~MoveDetail() +MovePiece::~MovePiece() {} //--------------------------------------------------------------------------------------------------------------------- -void MoveDetail::undo() +void MovePiece::undo() { qCDebug(vUndo, "Undo."); QDomElement domElement = doc->elementById(nodeId); if (domElement.isElement()) { - SaveCoordinates(domElement, oldX, oldY); + SaveCoordinates(domElement, m_oldX, m_oldY); emit NeedLiteParsing(Document::LiteParse); } @@ -87,14 +92,14 @@ void MoveDetail::undo() } //--------------------------------------------------------------------------------------------------------------------- -void MoveDetail::redo() +void MovePiece::redo() { qCDebug(vUndo, "Redo."); QDomElement domElement = doc->elementById(nodeId); if (domElement.isElement()) { - SaveCoordinates(domElement, newX, newY); + SaveCoordinates(domElement, m_newX, m_newY); if (redoFlag) { @@ -102,7 +107,7 @@ void MoveDetail::redo() } else { - VMainGraphicsView::NewSceneRect(scene, qApp->getSceneView()); + VMainGraphicsView::NewSceneRect(m_scene, qApp->getSceneView()); } redoFlag = true; } @@ -115,9 +120,9 @@ void MoveDetail::redo() //--------------------------------------------------------------------------------------------------------------------- // cppcheck-suppress unusedFunction -bool MoveDetail::mergeWith(const QUndoCommand *command) +bool MovePiece::mergeWith(const QUndoCommand *command) { - const MoveDetail *moveCommand = static_cast<const MoveDetail *>(command); + const MovePiece *moveCommand = static_cast<const MovePiece *>(command); SCASSERT(moveCommand != nullptr) const quint32 id = moveCommand->getDetId(); @@ -126,19 +131,19 @@ bool MoveDetail::mergeWith(const QUndoCommand *command) return false; } - newX = moveCommand->getNewX(); - newY = moveCommand->getNewY(); + m_newX = moveCommand->getNewX(); + m_newY = moveCommand->getNewY(); return true; } //--------------------------------------------------------------------------------------------------------------------- -int MoveDetail::id() const +int MovePiece::id() const { - return static_cast<int>(UndoCommand::MoveDetail); + return static_cast<int>(UndoCommand::MovePiece); } //--------------------------------------------------------------------------------------------------------------------- -void MoveDetail::SaveCoordinates(QDomElement &domElement, double x, double y) +void MovePiece::SaveCoordinates(QDomElement &domElement, double x, double y) { doc->SetAttribute(domElement, AttrMx, QString().setNum(qApp->fromPixel(x))); doc->SetAttribute(domElement, AttrMy, QString().setNum(qApp->fromPixel(y))); diff --git a/src/libs/vtools/undocommands/movedetail.h b/src/libs/vtools/undocommands/movepiece.h similarity index 78% rename from src/libs/vtools/undocommands/movedetail.h rename to src/libs/vtools/undocommands/movepiece.h index 37c0d1db2..95d0b5535 100644 --- a/src/libs/vtools/undocommands/movedetail.h +++ b/src/libs/vtools/undocommands/movepiece.h @@ -42,13 +42,14 @@ class QGraphicsScene; class QUndoCommand; class VAbstractPattern; -class MoveDetail : public VUndoCommand +class MovePiece : public VUndoCommand { Q_OBJECT public: - MoveDetail(VAbstractPattern *doc, const double &x, const double &y, const quint32 &id, QGraphicsScene *scene, - QUndoCommand *parent = 0); - virtual ~MoveDetail() Q_DECL_OVERRIDE; + MovePiece(VAbstractPattern *doc, const double &x, const double &y, const quint32 &id, QGraphicsScene *scene, + QUndoCommand *parent = nullptr); + virtual ~MovePiece(); + virtual void undo() Q_DECL_OVERRIDE; virtual void redo() Q_DECL_OVERRIDE; // cppcheck-suppress unusedFunction @@ -58,31 +59,33 @@ public: double getNewX() const; double getNewY() const; private: - Q_DISABLE_COPY(MoveDetail) - double oldX; - double oldY; - double newX; - double newY; - QGraphicsScene *scene; - void SaveCoordinates(QDomElement &domElement, double x, double y); + Q_DISABLE_COPY(MovePiece) + + double m_oldX; + double m_oldY; + double m_newX; + double m_newY; + QGraphicsScene *m_scene; + + void SaveCoordinates(QDomElement &domElement, double x, double y); }; //--------------------------------------------------------------------------------------------------------------------- -inline quint32 MoveDetail::getDetId() const +inline quint32 MovePiece::getDetId() const { return nodeId; } //--------------------------------------------------------------------------------------------------------------------- -inline double MoveDetail::getNewX() const +inline double MovePiece::getNewX() const { - return newX; + return m_newX; } //--------------------------------------------------------------------------------------------------------------------- -inline double MoveDetail::getNewY() const +inline double MovePiece::getNewY() const { - return newY; + return m_newY; } #endif // MOVEDETAIL_H diff --git a/src/libs/vtools/undocommands/savedetailoptions.cpp b/src/libs/vtools/undocommands/savedetailoptions.cpp deleted file mode 100644 index fa8ae38e9..000000000 --- a/src/libs/vtools/undocommands/savedetailoptions.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/************************************************************************ - ** - ** @file savedetailoptions.cpp - ** @author Roman Telezhynskyi <dismine(at)gmail.com> - ** @date 12 6, 2014 - ** - ** @brief - ** @copyright - ** This source code is part of the Valentine project, a pattern making - ** program, whose allow create and modeling patterns of clothing. - ** Copyright (C) 2013-2015 Valentina project - ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. - ** - ** Valentina is free software: you can redistribute it and/or modify - ** it under the terms of the GNU General Public License as published by - ** the Free Software Foundation, either version 3 of the License, or - ** (at your option) any later version. - ** - ** Valentina is distributed in the hope that it will be useful, - ** but WITHOUT ANY WARRANTY; without even the implied warranty of - ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - ** GNU General Public License for more details. - ** - ** You should have received a copy of the GNU General Public License - ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. - ** - *************************************************************************/ - -#include "savedetailoptions.h" - -#include <QDomElement> -#include <QPointF> -#include <QUndoCommand> -#include <QDebug> - -#include "../ifc/xml/vabstractpattern.h" -#include "../ifc/ifcdef.h" -#include "../vmisc/logging.h" -#include "../vmisc/def.h" -#include "../vpatterndb/vpatterninfogeometry.h" -#include "../vpatterndb/vpatternpiecedata.h" -#include "../vpatterndb/vgrainlinegeometry.h" -#include "../tools/vtooldetail.h" -#include "vundocommand.h" - -class QDomElement; -class QUndoCommand; - -//--------------------------------------------------------------------------------------------------------------------- -SaveDetailOptions::SaveDetailOptions(const VDetail &oldDet, const VDetail &newDet, VAbstractPattern *doc, - const quint32 &id, QGraphicsScene *scene, QUndoCommand *parent) - : VUndoCommand(QDomElement(), doc, parent), oldDet(oldDet), newDet(newDet), scene(scene) -{ - setText(tr("save detail option")); - nodeId = id; -} - -//--------------------------------------------------------------------------------------------------------------------- -SaveDetailOptions::~SaveDetailOptions() -{} - -//--------------------------------------------------------------------------------------------------------------------- -void SaveDetailOptions::undo() -{ - qCDebug(vUndo, "Undo."); - - QDomElement domElement = doc->elementById(nodeId); - if (domElement.isElement()) - { - SaveDet(domElement, oldDet); - doc->RemoveAllChildren(domElement); - SavePatternPieceData(domElement, oldDet); - SavePatternInfo(domElement, oldDet); - SaveGrainline(domElement, oldDet); - - for (int i = 0; i < oldDet.CountNode(); ++i) - { - VToolDetail::AddNode(doc, domElement, oldDet.at(i)); - } - IncrementReferences(oldDet.Missing(newDet)); - emit NeedLiteParsing(Document::LiteParse); - } - else - { - qCDebug(vUndo, "Can't find detail with id = %u.", nodeId); - return; - } -} - -//--------------------------------------------------------------------------------------------------------------------- -void SaveDetailOptions::redo() -{ - qCDebug(vUndo, "Redo."); - - QDomElement domElement = doc->elementById(nodeId); - if (domElement.isElement()) - { - SaveDet(domElement, newDet); - doc->RemoveAllChildren(domElement); - SavePatternPieceData(domElement, newDet); - SavePatternInfo(domElement, newDet); - SaveGrainline(domElement, newDet); - - for (int i = 0; i < newDet.CountNode(); ++i) - { - VToolDetail::AddNode(doc, domElement, newDet.at(i)); - } - - DecrementReferences(oldDet.Missing(newDet)); - emit NeedLiteParsing(Document::LiteParse); - } - else - { - qCDebug(vUndo, "Can't find detail with id = %u.", nodeId); - return; - } -} - -//--------------------------------------------------------------------------------------------------------------------- -bool SaveDetailOptions::mergeWith(const QUndoCommand *command) -{ - const SaveDetailOptions *saveCommand = static_cast<const SaveDetailOptions *>(command); - SCASSERT(saveCommand != nullptr) - const quint32 id = saveCommand->getDetId(); - - if (id != nodeId || text() != command->text()) - { - return false; - } - - newDet = saveCommand->getNewDet(); - return true; -} - -//--------------------------------------------------------------------------------------------------------------------- -int SaveDetailOptions::id() const -{ - return static_cast<int>(UndoCommand::SaveDetailOptions); -} - -//--------------------------------------------------------------------------------------------------------------------- -void SaveDetailOptions::SaveDet(QDomElement &domElement, const VDetail &det) -{ - doc->SetAttribute(domElement, AttrName, det.getName()); - doc->SetAttribute(domElement, VToolDetail::AttrSupplement, QString().setNum(det.getSeamAllowance())); - doc->SetAttribute(domElement, VToolDetail::AttrClosed, QString().setNum(det.getClosed())); - doc->SetAttribute(domElement, VToolDetail::AttrWidth, QString().setNum(det.getWidth())); - doc->SetAttribute(domElement, VToolDetail::AttrForbidFlipping, QString().setNum(det.getForbidFlipping())); -} - -//--------------------------------------------------------------------------------------------------------------------- -void SaveDetailOptions::SavePatternPieceData(QDomElement &domElement, const VDetail &det) -{ - QDomElement domData = doc->createElement(VAbstractPattern::TagData); - const VPatternPieceData& data = det.GetPatternPieceData(); - doc->SetAttribute(domData, VAbstractPattern::AttrLetter, data.GetLetter()); - doc->SetAttribute(domData, VAbstractPattern::AttrVisible, data.IsVisible() == true? trueStr : falseStr); - doc->SetAttribute(domData, AttrMx, data.GetPos().x()); - doc->SetAttribute(domData, AttrMy, data.GetPos().y()); - doc->SetAttribute(domData, VToolDetail::AttrWidth, data.GetLabelWidth()); - doc->SetAttribute(domData, VToolDetail::AttrHeight, data.GetLabelHeight()); - doc->SetAttribute(domData, VToolDetail::AttrFont, data.GetFontSize()); - doc->SetAttribute(domData, VToolDetail::AttrRotation, data.GetRotation()); - - for (int i = 0; i < data.GetMCPCount(); ++i) - { - MaterialCutPlacement mcp = data.GetMCP(i); - QDomElement domMCP = doc->createElement(VAbstractPattern::TagMCP); - doc->SetAttribute(domMCP, VAbstractPattern::AttrMaterial, int(mcp.m_eMaterial)); - if (mcp.m_eMaterial == MaterialType::mtUserDefined) - { - qDebug() << "USER DEFINED MATERIAL"; - doc->SetAttribute(domMCP, VAbstractPattern::AttrUserDefined, mcp.m_qsMaterialUserDef); - } - else - { - qDebug() << "PREDEFINED MATERIAL"; - domMCP.removeAttribute(VAbstractPattern::AttrUserDefined); - } - doc->SetAttribute(domMCP, VAbstractPattern::AttrCutNumber, mcp.m_iCutNumber); - doc->SetAttribute(domMCP, VAbstractPattern::AttrPlacement, int(mcp.m_ePlacement)); - domData.appendChild(domMCP); - } - domElement.appendChild(domData); -} - -//--------------------------------------------------------------------------------------------------------------------- -void SaveDetailOptions::SavePatternInfo(QDomElement &domElement, const VDetail &det) -{ - QDomElement domData = doc->createElement(VAbstractPattern::TagPatternInfo); - const VPatternInfoGeometry& data = det.GetPatternInfo(); - doc->SetAttribute(domData, VAbstractPattern::AttrVisible, data.IsVisible() == true? trueStr : falseStr); - doc->SetAttribute(domData, AttrMx, data.GetPos().x()); - doc->SetAttribute(domData, AttrMy, data.GetPos().y()); - doc->SetAttribute(domData, VToolDetail::AttrWidth, data.GetLabelWidth()); - doc->SetAttribute(domData, VToolDetail::AttrHeight, data.GetLabelHeight()); - doc->SetAttribute(domData, VToolDetail::AttrFont, data.GetFontSize()); - doc->SetAttribute(domData, VToolDetail::AttrRotation, data.GetRotation()); - - domElement.appendChild(domData); -} - -//--------------------------------------------------------------------------------------------------------------------- -void SaveDetailOptions::SaveGrainline(QDomElement &domElement, const VDetail &det) -{ - QDomElement domData = doc->createElement(VAbstractPattern::TagGrainline); - const VGrainlineGeometry& glGeom = det.GetGrainlineGeometry(); - doc->SetAttribute(domData, VAbstractPattern::AttrVisible, glGeom.IsVisible() == true? trueStr : falseStr); - doc->SetAttribute(domData, AttrMx, glGeom.GetPos().x()); - doc->SetAttribute(domData, AttrMy, glGeom.GetPos().y()); - doc->SetAttribute(domData, AttrLength, glGeom.GetLength()); - doc->SetAttribute(domData, VToolDetail::AttrRotation, glGeom.GetRotation()); - doc->SetAttribute(domData, VAbstractPattern::AttrArrows, int(glGeom.GetArrowType())); - - domElement.appendChild(domData); -} diff --git a/src/libs/vtools/undocommands/savepieceoptions.cpp b/src/libs/vtools/undocommands/savepieceoptions.cpp new file mode 100644 index 000000000..daeef8aab --- /dev/null +++ b/src/libs/vtools/undocommands/savepieceoptions.cpp @@ -0,0 +1,144 @@ +/************************************************************************ + ** + ** @file + ** @author Roman Telezhynskyi <dismine(at)gmail.com> + ** @date 9 11, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2016 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#include "savepieceoptions.h" + +#include <QDomElement> +#include <QPointF> +#include <QUndoCommand> +#include <QDebug> + +#include "../ifc/xml/vabstractpattern.h" +#include "../ifc/ifcdef.h" +#include "../vmisc/logging.h" +#include "../vmisc/def.h" +#include "../vpatterndb/vpiecenode.h" +#include "../vpatterndb/vpatterninfogeometry.h" +#include "../vpatterndb/vpatternpiecedata.h" +#include "../vpatterndb/vgrainlinegeometry.h" +#include "../tools/vtoolseamallowance.h" +#include "vundocommand.h" + +class QDomElement; +class QUndoCommand; + +//--------------------------------------------------------------------------------------------------------------------- +SavePieceOptions::SavePieceOptions(const VPiece &oldDet, const VPiece &newDet, VAbstractPattern *doc, quint32 id, + QUndoCommand *parent) + : VUndoCommand(QDomElement(), doc, parent), + m_oldDet(oldDet), + m_newDet(newDet) +{ + setText(tr("save detail option")); + nodeId = id; +} + +//--------------------------------------------------------------------------------------------------------------------- +SavePieceOptions::~SavePieceOptions() +{} + +//--------------------------------------------------------------------------------------------------------------------- +void SavePieceOptions::undo() +{ + qCDebug(vUndo, "Undo."); + + QDomElement domElement = doc->elementById(nodeId); + if (domElement.isElement()) + { + VToolSeamAllowance::AddAttributes(doc, domElement, nodeId, m_oldDet); + doc->RemoveAllChildren(domElement);//Very important to clear before rewrite + VToolSeamAllowance::AddPatternPieceData(doc, domElement, m_oldDet); + VToolSeamAllowance::AddPatternInfo(doc, domElement, m_oldDet); + VToolSeamAllowance::AddGrainline(doc, domElement, m_oldDet); + VToolSeamAllowance::AddNodes(doc, domElement, m_oldDet); + VToolSeamAllowance::AddCSARecords(doc, domElement, m_oldDet.GetCustomSARecords()); + VToolSeamAllowance::AddInternalPaths(doc, domElement, m_oldDet.GetInternalPaths()); + + IncrementReferences(m_oldDet.MissingNodes(m_newDet)); + IncrementReferences(m_oldDet.MissingCSAPath(m_newDet)); + IncrementReferences(m_oldDet.MissingInternalPaths(m_newDet)); + emit NeedLiteParsing(Document::LiteParse); + } + else + { + qCDebug(vUndo, "Can't find detail with id = %u.", nodeId); + return; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void SavePieceOptions::redo() +{ + qCDebug(vUndo, "Redo."); + + QDomElement domElement = doc->elementById(nodeId); + if (domElement.isElement()) + { + VToolSeamAllowance::AddAttributes(doc, domElement, nodeId, m_newDet); + doc->RemoveAllChildren(domElement);//Very important to clear before rewrite + VToolSeamAllowance::AddPatternPieceData(doc, domElement, m_newDet); + VToolSeamAllowance::AddPatternInfo(doc, domElement, m_newDet); + VToolSeamAllowance::AddGrainline(doc, domElement, m_newDet); + VToolSeamAllowance::AddNodes(doc, domElement, m_newDet); + VToolSeamAllowance::AddCSARecords(doc, domElement, m_newDet.GetCustomSARecords()); + VToolSeamAllowance::AddInternalPaths(doc, domElement, m_newDet.GetInternalPaths()); + + DecrementReferences(m_oldDet.MissingNodes(m_newDet)); + DecrementReferences(m_oldDet.MissingCSAPath(m_newDet)); + DecrementReferences(m_oldDet.MissingInternalPaths(m_newDet)); + + emit NeedLiteParsing(Document::LiteParse); + } + else + { + qCDebug(vUndo, "Can't find detail with id = %u.", nodeId); + return; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +bool SavePieceOptions::mergeWith(const QUndoCommand *command) +{ + const SavePieceOptions *saveCommand = static_cast<const SavePieceOptions *>(command); + SCASSERT(saveCommand != nullptr); + const quint32 id = saveCommand->DetId(); + + if (id != nodeId) + { + return false; + } + + m_newDet = saveCommand->NewDet(); + return true; +} + +//--------------------------------------------------------------------------------------------------------------------- +int SavePieceOptions::id() const +{ + return static_cast<int>(UndoCommand::SavePieceOptions); +} diff --git a/src/libs/vtools/undocommands/savedetailoptions.h b/src/libs/vtools/undocommands/savepieceoptions.h similarity index 56% rename from src/libs/vtools/undocommands/savedetailoptions.h rename to src/libs/vtools/undocommands/savepieceoptions.h index 5b4cbc058..dd4b7f8cb 100644 --- a/src/libs/vtools/undocommands/savedetailoptions.h +++ b/src/libs/vtools/undocommands/savepieceoptions.h @@ -1,14 +1,14 @@ /************************************************************************ ** - ** @file savedetailoptions.h + ** @file ** @author Roman Telezhynskyi <dismine(at)gmail.com> - ** @date 12 6, 2014 + ** @date 9 11, 2016 ** ** @brief ** @copyright ** This source code is part of the Valentine project, a pattern making ** program, whose allow create and modeling patterns of clothing. - ** Copyright (C) 2013-2015 Valentina project + ** Copyright (C) 2016 Valentina project ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. ** ** Valentina is free software: you can redistribute it and/or modify @@ -26,58 +26,47 @@ ** *************************************************************************/ -#ifndef SAVEDETAILOPTIONS_H -#define SAVEDETAILOPTIONS_H +#ifndef SAVEPIECEOPTIONS_H +#define SAVEPIECEOPTIONS_H -#include <qcompilerdetection.h> -#include <QMetaObject> -#include <QObject> -#include <QString> #include <QtGlobal> -#include "../tools/vtooldetail.h" -#include "vdetail.h" +#include "vpiece.h" #include "vundocommand.h" -class QDomElement; -class QGraphicsScene; class QUndoCommand; class VAbstractPattern; -class SaveDetailOptions : public VUndoCommand +class SavePieceOptions : public VUndoCommand { - Q_OBJECT public: - SaveDetailOptions(const VDetail &oldDet, const VDetail &newDet, VAbstractPattern *doc, const quint32 &id, - QGraphicsScene *scene, QUndoCommand *parent = 0); - virtual ~SaveDetailOptions() Q_DECL_OVERRIDE; + SavePieceOptions(const VPiece &m_oldDet, const VPiece &m_newDet, VAbstractPattern *doc, quint32 id, + QUndoCommand *parent = nullptr); + virtual ~SavePieceOptions(); + virtual void undo() Q_DECL_OVERRIDE; virtual void redo() Q_DECL_OVERRIDE; virtual bool mergeWith(const QUndoCommand *command) Q_DECL_OVERRIDE; virtual int id() const Q_DECL_OVERRIDE; - quint32 getDetId() const; - VDetail getNewDet() const; + quint32 DetId() const; + VPiece NewDet() const; private: - Q_DISABLE_COPY(SaveDetailOptions) - const VDetail oldDet; - VDetail newDet; - QGraphicsScene *scene; - void SaveDet(QDomElement &domElement, const VDetail &det); - void SavePatternPieceData(QDomElement &domElement, const VDetail &det); - void SavePatternInfo(QDomElement &domElement, const VDetail &det); - void SaveGrainline(QDomElement &domElement, const VDetail &det); + Q_DISABLE_COPY(SavePieceOptions) + + const VPiece m_oldDet; + VPiece m_newDet; }; //--------------------------------------------------------------------------------------------------------------------- -inline quint32 SaveDetailOptions::getDetId() const +inline quint32 SavePieceOptions::DetId() const { return nodeId; } //--------------------------------------------------------------------------------------------------------------------- -inline VDetail SaveDetailOptions::getNewDet() const +inline VPiece SavePieceOptions::NewDet() const { - return newDet; + return m_newDet; } -#endif // SAVEDETAILOPTIONS_H +#endif // SAVEPIECEOPTIONS_H diff --git a/src/libs/vtools/undocommands/savepiecepathoptions.cpp b/src/libs/vtools/undocommands/savepiecepathoptions.cpp new file mode 100644 index 000000000..0c1520d76 --- /dev/null +++ b/src/libs/vtools/undocommands/savepiecepathoptions.cpp @@ -0,0 +1,139 @@ +/************************************************************************ + ** + ** @file + ** @author Roman Telezhynskyi <dismine(at)gmail.com> + ** @date 26 11, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2016 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#include "savepiecepathoptions.h" + +#include <QDomElement> +#include <QUndoCommand> +#include <QDebug> + +#include "../ifc/xml/vabstractpattern.h" +#include "../vmisc/logging.h" +#include "../tools/nodeDetails/vtoolpiecepath.h" + +class QDomElement; +class QUndoCommand; + +//--------------------------------------------------------------------------------------------------------------------- +SavePiecePathOptions::SavePiecePathOptions(const VPiecePath &oldPath, const VPiecePath &newPath, + VAbstractPattern *doc, VContainer *data, quint32 id, + QUndoCommand *parent) + : VUndoCommand(QDomElement(), doc, parent), + m_oldPath(oldPath), + m_newPath(newPath), + m_data(data) +{ + setText(tr("save path options")); + nodeId = id; +} + +//--------------------------------------------------------------------------------------------------------------------- +SavePiecePathOptions::~SavePiecePathOptions() +{} + +//--------------------------------------------------------------------------------------------------------------------- +void SavePiecePathOptions::undo() +{ + qCDebug(vUndo, "Undo."); + + QDomElement domElement = doc->elementById(nodeId); + if (domElement.isElement()) + { + VToolPiecePath::AddAttributes(doc, domElement, nodeId, m_oldPath); + doc->RemoveAllChildren(domElement);//Very important to clear before rewrite + VToolPiecePath::AddNodes(doc, domElement, m_oldPath); + + IncrementReferences(m_oldPath.MissingNodes(m_newPath)); + + SCASSERT(m_data); + m_data->UpdatePiecePath(nodeId, m_oldPath); + } + else + { + qCDebug(vUndo, "Can't find path with id = %u.", nodeId); + return; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void SavePiecePathOptions::redo() +{ + qCDebug(vUndo, "Redo."); + + QDomElement domElement = doc->elementById(nodeId); + if (domElement.isElement()) + { + VToolPiecePath::AddAttributes(doc, domElement, nodeId, m_newPath); + doc->RemoveAllChildren(domElement);//Very important to clear before rewrite + VToolPiecePath::AddNodes(doc, domElement, m_newPath); + + DecrementReferences(m_oldPath.MissingNodes(m_newPath)); + + SCASSERT(m_data); + m_data->UpdatePiecePath(nodeId, m_newPath); + } + else + { + qCDebug(vUndo, "Can't find path with id = %u.", nodeId); + return; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +bool SavePiecePathOptions::mergeWith(const QUndoCommand *command) +{ + const SavePiecePathOptions *saveCommand = static_cast<const SavePiecePathOptions *>(command); + SCASSERT(saveCommand != nullptr); + const quint32 id = saveCommand->PathId(); + + if (id != nodeId) + { + return false; + } + + m_newPath = saveCommand->NewPath(); + return true; +} + +//--------------------------------------------------------------------------------------------------------------------- +int SavePiecePathOptions::id() const +{ + return static_cast<int>(UndoCommand::SavePiecePathOptions); +} + +//--------------------------------------------------------------------------------------------------------------------- +quint32 SavePiecePathOptions::PathId() const +{ + return nodeId; +} + +//--------------------------------------------------------------------------------------------------------------------- +VPiecePath SavePiecePathOptions::NewPath() const +{ + return m_newPath; +} diff --git a/src/libs/vtools/undocommands/savepiecepathoptions.h b/src/libs/vtools/undocommands/savepiecepathoptions.h new file mode 100644 index 000000000..f869df012 --- /dev/null +++ b/src/libs/vtools/undocommands/savepiecepathoptions.h @@ -0,0 +1,62 @@ +/************************************************************************ + ** + ** @file + ** @author Roman Telezhynskyi <dismine(at)gmail.com> + ** @date 26 11, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2016 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#ifndef SAVEPIECEPATHOPTIONS_H +#define SAVEPIECEPATHOPTIONS_H + +#include <QtGlobal> + +#include "../vpatterndb/vpiecepath.h" +#include "vundocommand.h" + +class QUndoCommand; +class VAbstractPattern; + +class SavePiecePathOptions : public VUndoCommand +{ +public: + SavePiecePathOptions(const VPiecePath &oldPath, const VPiecePath &newPath, VAbstractPattern *doc, + VContainer *data, quint32 id, QUndoCommand *parent = nullptr); + virtual ~SavePiecePathOptions(); + + virtual void undo() Q_DECL_OVERRIDE; + virtual void redo() Q_DECL_OVERRIDE; + virtual bool mergeWith(const QUndoCommand *command) Q_DECL_OVERRIDE; + virtual int id() const Q_DECL_OVERRIDE; + quint32 PathId() const; + VPiecePath NewPath() const; +private: + Q_DISABLE_COPY(SavePiecePathOptions) + + const VPiecePath m_oldPath; + VPiecePath m_newPath; + + VContainer *m_data; +}; + +#endif // SAVEPIECEPATHOPTIONS_H diff --git a/src/libs/vtools/undocommands/toggledetailinlayout.cpp b/src/libs/vtools/undocommands/togglepieceinlayout.cpp similarity index 83% rename from src/libs/vtools/undocommands/toggledetailinlayout.cpp rename to src/libs/vtools/undocommands/togglepieceinlayout.cpp index 88aa7daf2..7a3b65016 100644 --- a/src/libs/vtools/undocommands/toggledetailinlayout.cpp +++ b/src/libs/vtools/undocommands/togglepieceinlayout.cpp @@ -26,7 +26,7 @@ ** *************************************************************************/ -#include "toggledetailinlayout.h" +#include "togglepieceinlayout.h" #include <QDomElement> #include <QHash> @@ -38,30 +38,30 @@ #include "../vmisc/def.h" #include "../vmisc/logging.h" #include "../vpatterndb/vcontainer.h" -#include "../vpatterndb/vdetail.h" +#include "../vpatterndb/vpiece.h" #include "vundocommand.h" class QUndoCommand; //--------------------------------------------------------------------------------------------------------------------- -ToggleDetailInLayout::ToggleDetailInLayout(quint32 id, bool state, VContainer *data, VAbstractPattern *doc, +TogglePieceInLayout::TogglePieceInLayout(quint32 id, bool state, VContainer *data, VAbstractPattern *doc, QUndoCommand *parent) : VUndoCommand(QDomElement(), doc, parent), m_id(id), m_data(data), - m_oldState(m_data->DataDetails()->value(m_id).IsInLayout()), + m_oldState(m_data->DataPieces()->value(m_id).IsInLayout()), m_newState(state) { setText(tr("detail in layout list")); } //--------------------------------------------------------------------------------------------------------------------- -ToggleDetailInLayout::~ToggleDetailInLayout() +TogglePieceInLayout::~TogglePieceInLayout() { } //--------------------------------------------------------------------------------------------------------------------- -void ToggleDetailInLayout::undo() +void TogglePieceInLayout::undo() { qCDebug(vUndo, "ToggleDetailInLayout::undo()."); @@ -72,7 +72,7 @@ void ToggleDetailInLayout::undo() } //--------------------------------------------------------------------------------------------------------------------- -void ToggleDetailInLayout::redo() +void TogglePieceInLayout::redo() { qCDebug(vUndo, "ToggleDetailInLayout::redo()."); @@ -83,25 +83,25 @@ void ToggleDetailInLayout::redo() } //--------------------------------------------------------------------------------------------------------------------- -int ToggleDetailInLayout::id() const +int TogglePieceInLayout::id() const { - return static_cast<int>(UndoCommand::ToggleDetailInLayout); + return static_cast<int>(UndoCommand::TogglePieceInLayout); } //--------------------------------------------------------------------------------------------------------------------- -quint32 ToggleDetailInLayout::getDetId() const +quint32 TogglePieceInLayout::getDetId() const { return m_id; } //--------------------------------------------------------------------------------------------------------------------- -bool ToggleDetailInLayout::getNewState() const +bool TogglePieceInLayout::getNewState() const { return m_newState; } //--------------------------------------------------------------------------------------------------------------------- -void ToggleDetailInLayout::Do(bool state) +void TogglePieceInLayout::Do(bool state) { QDomElement detail = doc->elementById(m_id); if (detail.isElement()) @@ -115,9 +115,9 @@ void ToggleDetailInLayout::Do(bool state) detail.removeAttribute(AttrInLayout); } - VDetail det = m_data->DataDetails()->value(m_id); + VPiece det = m_data->DataPieces()->value(m_id); det.SetInLayout(state); - m_data->UpdateDetail(m_id, det); + m_data->UpdatePiece(m_id, det); emit UpdateList(); } else diff --git a/src/libs/vtools/undocommands/toggledetailinlayout.h b/src/libs/vtools/undocommands/togglepieceinlayout.h similarity index 87% rename from src/libs/vtools/undocommands/toggledetailinlayout.h rename to src/libs/vtools/undocommands/togglepieceinlayout.h index 9ba65da8c..d4879968e 100644 --- a/src/libs/vtools/undocommands/toggledetailinlayout.h +++ b/src/libs/vtools/undocommands/togglepieceinlayout.h @@ -41,13 +41,13 @@ class QUndoCommand; class VAbstractPattern; class VContainer; -class ToggleDetailInLayout : public VUndoCommand +class TogglePieceInLayout : public VUndoCommand { Q_OBJECT public: - ToggleDetailInLayout(quint32 id, bool state, VContainer *data, VAbstractPattern *doc, - QUndoCommand *parent = nullptr); - virtual ~ToggleDetailInLayout(); + TogglePieceInLayout(quint32 id, bool state, VContainer *data, VAbstractPattern *doc, + QUndoCommand *parent = nullptr); + virtual ~TogglePieceInLayout(); virtual void undo() Q_DECL_OVERRIDE; virtual void redo() Q_DECL_OVERRIDE; virtual int id() const Q_DECL_OVERRIDE; @@ -57,7 +57,7 @@ public: signals: void UpdateList(); private: - Q_DISABLE_COPY(ToggleDetailInLayout) + Q_DISABLE_COPY(TogglePieceInLayout) quint32 m_id; VContainer *m_data; bool m_oldState; diff --git a/src/libs/vtools/undocommands/undocommands.pri b/src/libs/vtools/undocommands/undocommands.pri index 216944bb2..b77b22ae9 100644 --- a/src/libs/vtools/undocommands/undocommands.pri +++ b/src/libs/vtools/undocommands/undocommands.pri @@ -8,13 +8,9 @@ HEADERS += \ $$PWD/movespline.h \ $$PWD/movesplinepath.h \ $$PWD/savetooloptions.h \ - $$PWD/savedetailoptions.h \ - $$PWD/movedetail.h \ $$PWD/deltool.h \ $$PWD/deletepatternpiece.h \ $$PWD/adddetnode.h \ - $$PWD/adddet.h \ - $$PWD/deletedetail.h \ $$PWD/vundocommand.h \ $$PWD/renamepp.h \ $$PWD/label/movelabel.h \ @@ -22,8 +18,13 @@ HEADERS += \ $$PWD/addgroup.h \ $$PWD/delgroup.h \ $$PWD/label/moveabstractlabel.h \ - $$PWD/toggledetailinlayout.h \ - $$PWD/label/operationmovelabel.h + $$PWD/label/operationmovelabel.h \ + $$PWD/addpiece.h \ + $$PWD/deletepiece.h \ + $$PWD/movepiece.h \ + $$PWD/savepieceoptions.h \ + $$PWD/togglepieceinlayout.h \ + $$PWD/savepiecepathoptions.h SOURCES += \ $$PWD/addtocalc.cpp \ @@ -32,13 +33,9 @@ SOURCES += \ $$PWD/movespline.cpp \ $$PWD/movesplinepath.cpp \ $$PWD/savetooloptions.cpp \ - $$PWD/savedetailoptions.cpp \ - $$PWD/movedetail.cpp \ $$PWD/deltool.cpp \ $$PWD/deletepatternpiece.cpp \ $$PWD/adddetnode.cpp \ - $$PWD/adddet.cpp \ - $$PWD/deletedetail.cpp \ $$PWD/vundocommand.cpp \ $$PWD/renamepp.cpp \ $$PWD/label/movelabel.cpp \ @@ -46,5 +43,10 @@ SOURCES += \ $$PWD/addgroup.cpp \ $$PWD/delgroup.cpp \ $$PWD/label/moveabstractlabel.cpp \ - $$PWD/toggledetailinlayout.cpp \ - $$PWD/label/operationmovelabel.cpp + $$PWD/label/operationmovelabel.cpp \ + $$PWD/addpiece.cpp \ + $$PWD/deletepiece.cpp \ + $$PWD/movepiece.cpp \ + $$PWD/savepieceoptions.cpp \ + $$PWD/togglepieceinlayout.cpp \ + $$PWD/savepiecepathoptions.cpp diff --git a/src/libs/vtools/undocommands/vundocommand.cpp b/src/libs/vtools/undocommands/vundocommand.cpp index 2e52a502c..cd430d377 100644 --- a/src/libs/vtools/undocommands/vundocommand.cpp +++ b/src/libs/vtools/undocommands/vundocommand.cpp @@ -33,6 +33,7 @@ #include "../ifc/ifcdef.h" #include "../vmisc/def.h" #include "../vpatterndb/vnodedetail.h" +#include "../vpatterndb/vpiecenode.h" class QDomElement; class QDomNode; @@ -76,19 +77,71 @@ void VUndoCommand::UndoDeleteAfterSibling(QDomNode &parentNode, const quint32 &s } //--------------------------------------------------------------------------------------------------------------------- -void VUndoCommand::IncrementReferences(const QVector<VNodeDetail> &nodes) const +void VUndoCommand::IncrementReferences(const QVector<quint32> &nodes) const { for (qint32 i = 0; i < nodes.size(); ++i) { - doc->IncrementReferens(nodes.at(i).getId()); + doc->IncrementReferens(nodes.at(i)); } } //--------------------------------------------------------------------------------------------------------------------- -void VUndoCommand::DecrementReferences(const QVector<VNodeDetail> &nodes) const +void VUndoCommand::DecrementReferences(const QVector<quint32> &nodes) const { for (qint32 i = 0; i < nodes.size(); ++i) { - doc->DecrementReferens(nodes.at(i).getId()); + doc->DecrementReferens(nodes.at(i)); } } + +//--------------------------------------------------------------------------------------------------------------------- +void VUndoCommand::IncrementReferences(const QVector<CustomSARecord> &nodes) const +{ + QVector<quint32> n; + + for (qint32 i = 0; i < nodes.size(); ++i) + { + n.append(nodes.at(i).path); + } + + IncrementReferences(n); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VUndoCommand::DecrementReferences(const QVector<CustomSARecord> &nodes) const +{ + QVector<quint32> n; + + for (qint32 i = 0; i < nodes.size(); ++i) + { + n.append(nodes.at(i).path); + } + + DecrementReferences(n); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VUndoCommand::IncrementReferences(const QVector<VPieceNode> &nodes) const +{ + QVector<quint32> n; + + for (qint32 i = 0; i < nodes.size(); ++i) + { + n.append(nodes.at(i).GetId()); + } + + IncrementReferences(n); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VUndoCommand::DecrementReferences(const QVector<VPieceNode> &nodes) const +{ + QVector<quint32> n; + + for (qint32 i = 0; i < nodes.size(); ++i) + { + n.append(nodes.at(i).GetId()); + } + + DecrementReferences(n); +} diff --git a/src/libs/vtools/undocommands/vundocommand.h b/src/libs/vtools/undocommands/vundocommand.h index 31cd57570..58f5c1d32 100644 --- a/src/libs/vtools/undocommands/vundocommand.h +++ b/src/libs/vtools/undocommands/vundocommand.h @@ -54,17 +54,19 @@ enum class UndoCommand: char { AddPatternPiece, MoveSPoint, SaveToolOptions, SaveDetailOptions, - MoveDetail, + SavePieceOptions, + SavePiecePathOptions, + MovePiece, DeleteTool, DeletePatternPiece, RenamePP, MoveLabel, MoveDoubleLabel, RotationMoveLabel, - ToggleDetailInLayout + TogglePieceInLayout }; -class VNodeDetail; +class VPieceNode; class VPattern; class VUndoCommand : public QObject, public QUndoCommand @@ -85,8 +87,14 @@ protected: virtual void RedoFullParsing(); void UndoDeleteAfterSibling(QDomNode &parentNode, const quint32 &siblingId) const; - void IncrementReferences(const QVector<VNodeDetail> &nodes) const; - void DecrementReferences(const QVector<VNodeDetail> &nodes) const; + void IncrementReferences(const QVector<quint32> &nodes) const; + void DecrementReferences(const QVector<quint32> &nodes) const; + + void IncrementReferences(const QVector<CustomSARecord> &nodes) const; + void DecrementReferences(const QVector<CustomSARecord> &nodes) const; + + void IncrementReferences(const QVector<VPieceNode> &nodes) const; + void DecrementReferences(const QVector<VPieceNode> &nodes) const; private: Q_DISABLE_COPY(VUndoCommand) }; diff --git a/src/libs/vtools/visualization/line/operation/visoperation.cpp b/src/libs/vtools/visualization/line/operation/visoperation.cpp index 4cc52b06e..a9566bb1d 100644 --- a/src/libs/vtools/visualization/line/operation/visoperation.cpp +++ b/src/libs/vtools/visualization/line/operation/visoperation.cpp @@ -78,17 +78,7 @@ void VisOperation::VisualMode(const quint32 &pointId) //--------------------------------------------------------------------------------------------------------------------- QGraphicsEllipseItem *VisOperation::GetPoint(quint32 i, const QColor &color) { - if (not points.isEmpty() && static_cast<quint32>(points.size() - 1) >= i) - { - return points.at(static_cast<int>(i)); - } - else - { - auto point = InitPoint(color, this); - points.append(point); - return point; - } - return nullptr; + return GetPointItem(Visualization::data, factor, points, i, color, this); } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/vtools/visualization/path/vistoolpiece.cpp b/src/libs/vtools/visualization/path/vistoolpiece.cpp new file mode 100644 index 000000000..8895dacaa --- /dev/null +++ b/src/libs/vtools/visualization/path/vistoolpiece.cpp @@ -0,0 +1,111 @@ +/************************************************************************ + ** + ** @file + ** @author Roman Telezhynskyi <dismine(at)gmail.com> + ** @date 5 11, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2016 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#include "vistoolpiece.h" +#include "../vpatterndb/vpiecepath.h" +#include "../vgeometry/vpointf.h" + +//--------------------------------------------------------------------------------------------------------------------- +VisToolPiece::VisToolPiece(const VContainer *data, QGraphicsItem *parent) + : VisPath(data, parent), + m_points(), + m_line1(nullptr), + m_line2(nullptr), + m_piece() +{ + m_line1 = InitItem<QGraphicsLineItem>(supportColor, this); + m_line2 = InitItem<QGraphicsLineItem>(supportColor, this); +} + +//--------------------------------------------------------------------------------------------------------------------- +VisToolPiece::~VisToolPiece() +{} + +//--------------------------------------------------------------------------------------------------------------------- +void VisToolPiece::RefreshGeometry() +{ + HideAllItems(); + + if (m_piece.GetPath().CountNodes() > 0) + { + DrawPath(this, m_piece.MainPathPath(Visualization::data), mainColor, Qt::SolidLine, Qt::RoundCap); + + const QVector<VPointF> nodes = m_piece.MainPathNodePoints(Visualization::data); + + for (int i = 0; i < nodes.size(); ++i) + { + QGraphicsEllipseItem *point = GetPoint(static_cast<quint32>(i), supportColor); + DrawPoint(point, nodes.at(i).toQPointF(), supportColor); + } + + if (mode == Mode::Creation) + { + const QVector<QPointF> points = m_piece.MainPathPoints(Visualization::data); + DrawLine(m_line1, QLineF(points.first(), Visualization::scenePos), supportColor, Qt::DashLine); + + if (points.size() > 1) + { + DrawLine(m_line2, QLineF(points.last(), Visualization::scenePos), supportColor, Qt::DashLine); + } + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VisToolPiece::SetPiece(const VPiece &piece) +{ + m_piece = piece; +} + +//--------------------------------------------------------------------------------------------------------------------- +QGraphicsEllipseItem *VisToolPiece::GetPoint(quint32 i, const QColor &color) +{ + return GetPointItem(Visualization::data, factor, m_points, i, color, this); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VisToolPiece::HideAllItems() +{ + if (m_line1) + { + m_line1->setVisible(false); + } + + if (m_line2) + { + m_line2->setVisible(false); + } + + for (int i=0; i < m_points.size(); ++i) + { + if (QGraphicsEllipseItem *item = m_points.at(i)) + { + item->setVisible(false); + } + } +} diff --git a/src/libs/vtools/visualization/path/vistoolpiece.h b/src/libs/vtools/visualization/path/vistoolpiece.h new file mode 100644 index 000000000..a9071d5e4 --- /dev/null +++ b/src/libs/vtools/visualization/path/vistoolpiece.h @@ -0,0 +1,62 @@ +/************************************************************************ + ** + ** @file + ** @author Roman Telezhynskyi <dismine(at)gmail.com> + ** @date 5 11, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2016 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#ifndef VISTOOLPIECE_H +#define VISTOOLPIECE_H + +#include <QtCore/QObject> +#include <QtGlobal> + +#include "vispath.h" +#include "../vpatterndb/vpiece.h" + +class VisToolPiece : public VisPath +{ + Q_OBJECT +public: + VisToolPiece(const VContainer *data, QGraphicsItem *parent = nullptr); + virtual ~VisToolPiece(); + + virtual void RefreshGeometry() Q_DECL_OVERRIDE; + void SetPiece(const VPiece &piece); + virtual int type() const Q_DECL_OVERRIDE {return Type;} + enum { Type = UserType + static_cast<int>(Vis::ToolPiece)}; +private: + Q_DISABLE_COPY(VisToolPiece) + QVector<QGraphicsEllipseItem *> m_points; + + QGraphicsLineItem *m_line1; + QGraphicsLineItem *m_line2; + VPiece m_piece; + + QGraphicsEllipseItem* GetPoint(quint32 i, const QColor &color); + + void HideAllItems(); +}; + +#endif // VISTOOLPIECE_H diff --git a/src/libs/vtools/visualization/path/vistoolpiecepath.cpp b/src/libs/vtools/visualization/path/vistoolpiecepath.cpp new file mode 100644 index 000000000..a5e294f2a --- /dev/null +++ b/src/libs/vtools/visualization/path/vistoolpiecepath.cpp @@ -0,0 +1,126 @@ +/************************************************************************ + ** + ** @file + ** @author Roman Telezhynskyi <dismine(at)gmail.com> + ** @date 22 11, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2016 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#include "vistoolpiecepath.h" +#include "../vwidgets/vsimplepoint.h" +#include "../vgeometry/vpointf.h" + +#include <QGraphicsSceneMouseEvent> + +//--------------------------------------------------------------------------------------------------------------------- +VisToolPiecePath::VisToolPiecePath(const VContainer *data, QGraphicsItem *parent) + : VisPath(data, parent), + m_points(), + m_line(nullptr), + m_path() +{ + m_line = InitItem<QGraphicsLineItem>(supportColor, this); +} + +//--------------------------------------------------------------------------------------------------------------------- +VisToolPiecePath::~VisToolPiecePath() +{} + +//--------------------------------------------------------------------------------------------------------------------- +void VisToolPiecePath::RefreshGeometry() +{ + HideAllItems(); + + if (m_path.CountNodes() > 0) + { + DrawPath(this, m_path.PainterPath(Visualization::data), mainColor, Qt::SolidLine, Qt::RoundCap); + + const QVector<VPointF> nodes = m_path.PathNodePoints(Visualization::data); + + for (int i = 0; i < nodes.size(); ++i) + { + VSimplePoint *point = GetPoint(static_cast<quint32>(i), supportColor); + point->SetOnlyPoint(mode == Mode::Creation); + point->RefreshGeometry(nodes.at(i)); + point->setVisible(true); + } + + if (mode == Mode::Creation) + { + const QVector<QPointF> points = m_path.PathPoints(Visualization::data); + if (points.size() > 0) + { + DrawLine(m_line, QLineF(points.last(), Visualization::scenePos), supportColor, Qt::DashLine); + } + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VisToolPiecePath::SetPath(const VPiecePath &path) +{ + m_path = path; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VisToolPiecePath::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + event->ignore(); +} + +//--------------------------------------------------------------------------------------------------------------------- +VSimplePoint *VisToolPiecePath::GetPoint(quint32 i, const QColor &color) +{ + if (not m_points.isEmpty() && static_cast<quint32>(m_points.size() - 1) >= i) + { + return m_points.at(static_cast<int>(i)); + } + else + { + VSimplePoint *point = new VSimplePoint(NULL_ID, color, *Visualization::data->GetPatternUnit(), &factor); + point->SetPointHighlight(true); + point->setParentItem(this); + point->SetVisualizationMode(true); + m_points.append(point); + + return point; + } + return nullptr; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VisToolPiecePath::HideAllItems() +{ + if (m_line) + { + m_line->setVisible(false); + } + + for (int i=0; i < m_points.size(); ++i) + { + if (QGraphicsEllipseItem *item = m_points.at(i)) + { + item->setVisible(false); + } + } +} diff --git a/src/libs/vtools/visualization/path/vistoolpiecepath.h b/src/libs/vtools/visualization/path/vistoolpiecepath.h new file mode 100644 index 000000000..591561059 --- /dev/null +++ b/src/libs/vtools/visualization/path/vistoolpiecepath.h @@ -0,0 +1,68 @@ +/************************************************************************ + ** + ** @file + ** @author Roman Telezhynskyi <dismine(at)gmail.com> + ** @date 22 11, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2016 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#ifndef VISTOOLPIECEPATH_H +#define VISTOOLPIECEPATH_H + +#include <QtCore/QObject> +#include <QtGlobal> + +#include "vispath.h" +#include "../vpatterndb/vpiecepath.h" + +class VSimplePoint; + +class VisToolPiecePath : public VisPath +{ + Q_OBJECT +public: + VisToolPiecePath(const VContainer *data, QGraphicsItem *parent = nullptr); + virtual ~VisToolPiecePath(); + + virtual void RefreshGeometry() Q_DECL_OVERRIDE; + void SetPath(const VPiecePath &piece); + virtual int type() const Q_DECL_OVERRIDE {return Type;} + enum { Type = UserType + static_cast<int>(Vis::ToolPiecePath)}; + +protected: + virtual void mousePressEvent( QGraphicsSceneMouseEvent * event ) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(VisToolPiecePath) + QVector<VSimplePoint *> m_points; + + QGraphicsLineItem *m_line; + + VPiecePath m_path; + + VSimplePoint *GetPoint(quint32 i, const QColor &color); + + void HideAllItems(); +}; + +#endif // VISTOOLPIECEPATH_H diff --git a/src/libs/vtools/visualization/visualization.cpp b/src/libs/vtools/visualization/visualization.cpp index d6bd123e7..c20ece212 100644 --- a/src/libs/vtools/visualization/visualization.cpp +++ b/src/libs/vtools/visualization/visualization.cpp @@ -141,20 +141,11 @@ void Visualization::MousePos(const QPointF &scenePos) //--------------------------------------------------------------------------------------------------------------------- QGraphicsEllipseItem *Visualization::InitPoint(const QColor &color, QGraphicsItem *parent, qreal z) const { - QGraphicsEllipseItem *point = new QGraphicsEllipseItem(parent); - point->setZValue(1); - point->setBrush(QBrush(Qt::NoBrush)); - point->setPen(QPen(color, qApp->toPixel(WidthMainLine(*Visualization::data->GetPatternUnit()))/factor)); - point->setRect(PointRect(ToPixel(DefPointRadius/*mm*/, Unit::Mm))); - point->setPos(QPointF()); - point->setFlags(QGraphicsItem::ItemStacksBehindParent); - point->setZValue(z); - point->setVisible(false); - return point; + return InitPointItem(Visualization::data, factor, color, parent, z); } //--------------------------------------------------------------------------------------------------------------------- -QRectF Visualization::PointRect(const qreal &radius) const +QRectF Visualization::PointRect(qreal radius) { QRectF rec = QRectF(0, 0, radius*2, radius*2); rec.translate(-rec.center().x(), -rec.center().y()); @@ -236,6 +227,39 @@ void Visualization::DrawPath(QGraphicsPathItem *pathItem, const QPainterPath &pa pathItem->setVisible(true); } +//--------------------------------------------------------------------------------------------------------------------- +QGraphicsEllipseItem *Visualization::GetPointItem(const VContainer *data, qreal factor, + QVector<QGraphicsEllipseItem *> &points, quint32 i, + const QColor &color, QGraphicsItem *parent) +{ + if (not points.isEmpty() && static_cast<quint32>(points.size() - 1) >= i) + { + return points.at(static_cast<int>(i)); + } + else + { + auto point = InitPointItem(data, factor, color, parent); + points.append(point); + return point; + } + return nullptr; +} + +//--------------------------------------------------------------------------------------------------------------------- +QGraphicsEllipseItem *Visualization::InitPointItem(const VContainer *data, qreal factor, const QColor &color, + QGraphicsItem *parent, qreal z) +{ + QGraphicsEllipseItem *point = new QGraphicsEllipseItem(parent); + point->setZValue(1); + point->setBrush(QBrush(Qt::NoBrush)); + point->setPen(QPen(color, qApp->toPixel(WidthMainLine(*data->GetPatternUnit()))/factor)); + point->setRect(PointRect(ToPixel(DefPointRadius/*mm*/, Unit::Mm))); + point->setPos(QPointF()); + point->setFlags(QGraphicsItem::ItemStacksBehindParent); + point->setZValue(z); + point->setVisible(false); + return point; +} //--------------------------------------------------------------------------------------------------------------------- Mode Visualization::GetMode() const diff --git a/src/libs/vtools/visualization/visualization.h b/src/libs/vtools/visualization/visualization.h index 13124732b..15b2d0ee3 100644 --- a/src/libs/vtools/visualization/visualization.h +++ b/src/libs/vtools/visualization/visualization.h @@ -84,7 +84,6 @@ protected: virtual void AddOnScene()=0; QGraphicsEllipseItem *InitPoint(const QColor &color, QGraphicsItem *parent, qreal z = 0) const; - QRectF PointRect(const qreal &radius) const; void DrawPoint(QGraphicsEllipseItem *point, const QPointF &pos, const QColor &color, Qt::PenStyle style = Qt::SolidLine); virtual void DrawLine(QGraphicsLineItem *lineItem, const QLineF &line, const QColor &color, @@ -97,8 +96,16 @@ protected: template <class Item> Item *InitItem(const QColor &color, QGraphicsItem *parent); + + static QRectF PointRect(qreal radius); + static QGraphicsEllipseItem* GetPointItem(const VContainer *data, qreal factor, + QVector<QGraphicsEllipseItem *> &points, quint32 i, const QColor &color, + QGraphicsItem *parent); private: Q_DISABLE_COPY(Visualization) + + static QGraphicsEllipseItem* InitPointItem(const VContainer *data, qreal factor, const QColor &color, + QGraphicsItem *parent, qreal z = 0); }; //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/vtools/visualization/visualization.pri b/src/libs/vtools/visualization/visualization.pri index 5a02ea230..6231eacf9 100644 --- a/src/libs/vtools/visualization/visualization.pri +++ b/src/libs/vtools/visualization/visualization.pri @@ -1,80 +1,84 @@ -# ADD TO EACH PATH $$PWD VARIABLE!!!!!! -# This need for corect working file translations.pro - -HEADERS += \ - $$PWD/visualization.h \ - $$PWD/line/visline.h \ - $$PWD/line/vistoolline.h \ - $$PWD/line/vistoolendline.h \ - $$PWD/line/vistoolalongline.h \ - $$PWD/line/vistoolbisector.h \ - $$PWD/line/vistoolshoulderpoint.h \ - $$PWD/line/vistoolnormal.h \ - $$PWD/line/vistoolheight.h \ - $$PWD/line/vistoolpointofintersection.h \ - $$PWD/line/vistooltriangle.h \ - $$PWD/line/vistoolpointofcontact.h \ - $$PWD/line/vistoollineintersect.h \ - $$PWD/line/vistoollineintersectaxis.h \ - $$PWD/line/vistooltruedarts.h \ - $$PWD/line/vistoolcurveintersectaxis.h \ - $$PWD/line/vistoolpointofintersectionarcs.h \ - $$PWD/line/vistoolpointofintersectioncircles.h \ - $$PWD/line/vistoolpointfromcircleandtangent.h \ - $$PWD/line/vistoolpointfromarcandtangent.h \ - $$PWD/line/operation/vistoolrotation.h \ - $$PWD/line/operation/vistoolflippingbyline.h \ - $$PWD/path/vispath.h \ - $$PWD/path/vistoolarc.h \ - $$PWD/path/vistoolcutarc.h \ - $$PWD/path/vistoolspline.h \ - $$PWD/path/vistoolcutspline.h \ - $$PWD/path/vistoolsplinepath.h \ - $$PWD/path/vistoolcutsplinepath.h \ - $$PWD/path/vistoolarcwithlength.h \ - $$PWD/path/vistoolpointofintersectioncurves.h \ - $$PWD/path/vistoolcubicbezier.h \ - $$PWD/path/vistoolcubicbezierpath.h \ - $$PWD/line/operation/visoperation.h \ - $$PWD/line/operation/vistoolflippingbyaxis.h \ - $$PWD/line/operation/vistoolmove.h \ - $$PWD/path/vistoolellipticalarc.h - -SOURCES += \ - $$PWD/visualization.cpp \ - $$PWD/line/visline.cpp \ - $$PWD/line/vistoolline.cpp \ - $$PWD/line/vistoolendline.cpp \ - $$PWD/line/vistoolalongline.cpp \ - $$PWD/line/vistoolbisector.cpp \ - $$PWD/line/vistoolshoulderpoint.cpp \ - $$PWD/line/vistoolnormal.cpp \ - $$PWD/line/vistoolheight.cpp \ - $$PWD/line/vistoolpointofintersection.cpp \ - $$PWD/line/vistooltriangle.cpp \ - $$PWD/line/vistoolpointofcontact.cpp \ - $$PWD/line/vistoollineintersect.cpp \ - $$PWD/line/vistoollineintersectaxis.cpp \ - $$PWD/line/vistooltruedarts.cpp \ - $$PWD/line/vistoolcurveintersectaxis.cpp \ - $$PWD/line/vistoolpointofintersectionarcs.cpp \ - $$PWD/line/vistoolpointofintersectioncircles.cpp \ - $$PWD/line/vistoolpointfromcircleandtangent.cpp \ - $$PWD/line/vistoolpointfromarcandtangent.cpp \ - $$PWD/line/operation/vistoolrotation.cpp \ - $$PWD/line/operation/vistoolflippingbyline.cpp \ - $$PWD/path/vispath.cpp \ - $$PWD/path/vistoolarc.cpp \ - $$PWD/path/vistoolcutarc.cpp \ - $$PWD/path/vistoolspline.cpp \ - $$PWD/path/vistoolcutspline.cpp \ - $$PWD/path/vistoolsplinepath.cpp \ - $$PWD/path/vistoolcutsplinepath.cpp \ - $$PWD/path/vistoolarcwithlength.cpp \ - $$PWD/path/vistoolpointofintersectioncurves.cpp \ - $$PWD/path/vistoolcubicbezier.cpp \ - $$PWD/path/vistoolcubicbezierpath.cpp \ - $$PWD/line/operation/visoperation.cpp \ - $$PWD/line/operation/vistoolflippingbyaxis.cpp \ - $$PWD/line/operation/vistoolmove.cpp \ - $$PWD/path/vistoolellipticalarc.cpp +# ADD TO EACH PATH $$PWD VARIABLE!!!!!! +# This need for corect working file translations.pro + +HEADERS += \ + $$PWD/visualization.h \ + $$PWD/line/visline.h \ + $$PWD/line/vistoolline.h \ + $$PWD/line/vistoolendline.h \ + $$PWD/line/vistoolalongline.h \ + $$PWD/line/vistoolbisector.h \ + $$PWD/line/vistoolshoulderpoint.h \ + $$PWD/line/vistoolnormal.h \ + $$PWD/line/vistoolheight.h \ + $$PWD/line/vistoolpointofintersection.h \ + $$PWD/line/vistooltriangle.h \ + $$PWD/line/vistoolpointofcontact.h \ + $$PWD/line/vistoollineintersect.h \ + $$PWD/line/vistoollineintersectaxis.h \ + $$PWD/line/vistooltruedarts.h \ + $$PWD/line/vistoolcurveintersectaxis.h \ + $$PWD/line/vistoolpointofintersectionarcs.h \ + $$PWD/line/vistoolpointofintersectioncircles.h \ + $$PWD/line/vistoolpointfromcircleandtangent.h \ + $$PWD/line/vistoolpointfromarcandtangent.h \ + $$PWD/line/operation/vistoolrotation.h \ + $$PWD/line/operation/vistoolflippingbyline.h \ + $$PWD/path/vispath.h \ + $$PWD/path/vistoolarc.h \ + $$PWD/path/vistoolcutarc.h \ + $$PWD/path/vistoolspline.h \ + $$PWD/path/vistoolcutspline.h \ + $$PWD/path/vistoolsplinepath.h \ + $$PWD/path/vistoolcutsplinepath.h \ + $$PWD/path/vistoolarcwithlength.h \ + $$PWD/path/vistoolpointofintersectioncurves.h \ + $$PWD/path/vistoolcubicbezier.h \ + $$PWD/path/vistoolcubicbezierpath.h \ + $$PWD/line/operation/visoperation.h \ + $$PWD/line/operation/vistoolflippingbyaxis.h \ + $$PWD/line/operation/vistoolmove.h \ + $$PWD/path/vistoolellipticalarc.h \ + $$PWD/path/vistoolpiece.h \ + $$PWD/path/vistoolpiecepath.h + +SOURCES += \ + $$PWD/visualization.cpp \ + $$PWD/line/visline.cpp \ + $$PWD/line/vistoolline.cpp \ + $$PWD/line/vistoolendline.cpp \ + $$PWD/line/vistoolalongline.cpp \ + $$PWD/line/vistoolbisector.cpp \ + $$PWD/line/vistoolshoulderpoint.cpp \ + $$PWD/line/vistoolnormal.cpp \ + $$PWD/line/vistoolheight.cpp \ + $$PWD/line/vistoolpointofintersection.cpp \ + $$PWD/line/vistooltriangle.cpp \ + $$PWD/line/vistoolpointofcontact.cpp \ + $$PWD/line/vistoollineintersect.cpp \ + $$PWD/line/vistoollineintersectaxis.cpp \ + $$PWD/line/vistooltruedarts.cpp \ + $$PWD/line/vistoolcurveintersectaxis.cpp \ + $$PWD/line/vistoolpointofintersectionarcs.cpp \ + $$PWD/line/vistoolpointofintersectioncircles.cpp \ + $$PWD/line/vistoolpointfromcircleandtangent.cpp \ + $$PWD/line/vistoolpointfromarcandtangent.cpp \ + $$PWD/line/operation/vistoolrotation.cpp \ + $$PWD/line/operation/vistoolflippingbyline.cpp \ + $$PWD/path/vispath.cpp \ + $$PWD/path/vistoolarc.cpp \ + $$PWD/path/vistoolcutarc.cpp \ + $$PWD/path/vistoolspline.cpp \ + $$PWD/path/vistoolcutspline.cpp \ + $$PWD/path/vistoolsplinepath.cpp \ + $$PWD/path/vistoolcutsplinepath.cpp \ + $$PWD/path/vistoolarcwithlength.cpp \ + $$PWD/path/vistoolpointofintersectioncurves.cpp \ + $$PWD/path/vistoolcubicbezier.cpp \ + $$PWD/path/vistoolcubicbezierpath.cpp \ + $$PWD/line/operation/visoperation.cpp \ + $$PWD/line/operation/vistoolflippingbyaxis.cpp \ + $$PWD/line/operation/vistoolmove.cpp \ + $$PWD/path/vistoolellipticalarc.cpp \ + $$PWD/path/vistoolpiece.cpp \ + $$PWD/path/vistoolpiecepath.cpp diff --git a/src/libs/vtools/tools/vgrainlineitem.cpp b/src/libs/vwidgets/vgrainlineitem.cpp similarity index 89% rename from src/libs/vtools/tools/vgrainlineitem.cpp rename to src/libs/vwidgets/vgrainlineitem.cpp index 4fea3b503..954216651 100644 --- a/src/libs/vtools/tools/vgrainlineitem.cpp +++ b/src/libs/vwidgets/vgrainlineitem.cpp @@ -44,7 +44,6 @@ #define RESIZE_RECT_SIZE 10 #define ROTATE_CIRC_R 7 #define ACTIVE_Z 10 -#define INACTIVE_Z 5 //--------------------------------------------------------------------------------------------------------------------- /** @@ -52,13 +51,10 @@ * @param pParent pointer to the parent item */ VGrainlineItem::VGrainlineItem(QGraphicsItem* pParent) - : QGraphicsObject(pParent), - m_eMode(VGrainlineItem::mNormal), - m_bReleased(false), + : VPieceItem(pParent), m_dRotation(0), m_dStartRotation(0), m_dLength(0), - m_rectBoundingBox(), m_polyBound(), m_ptStartPos(), m_ptStartMove(), @@ -68,12 +64,10 @@ VGrainlineItem::VGrainlineItem(QGraphicsItem* pParent) m_ptStart(), m_ptFinish(), m_ptCenter(), - m_ptRotCenter(), m_dAngle(0), m_eArrowType(VGrainlineGeometry::atBoth) { - m_rectBoundingBox.setTopLeft(QPointF(0, 0)); - setAcceptHoverEvents(true); + m_inactiveZ = 5; Reset(); UpdateRectangle(); } @@ -211,39 +205,7 @@ void VGrainlineItem::UpdateGeometry(const QPointF& ptPos, qreal dRotation, qreal m_eArrowType = eAT; UpdateRectangle(); - UpdateBox(); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief VGrainlineItem::boundingRect returns the bounding rect around the grainline - * @return bounding rect - */ -QRectF VGrainlineItem::boundingRect() const -{ - return m_rectBoundingBox; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief VGrainlineItem::Reset resets the item parameters. - */ -void VGrainlineItem::Reset() -{ - m_bReleased = false; - m_eMode = mNormal; - setZValue(INACTIVE_Z); - UpdateBox(); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief VGrainlineItem::IsIdle returns the idle flag. - * @return true, if item mode is normal and false otherwise. - */ -bool VGrainlineItem::IsIdle() const -{ - return m_eMode == mNormal; + Update(); } //--------------------------------------------------------------------------------------------------------------------- @@ -318,7 +280,7 @@ void VGrainlineItem::SetScale(qreal dScale) { m_dScale = dScale; UpdateRectangle(); - UpdateBox(); + Update(); } //--------------------------------------------------------------------------------------------------------------------- @@ -355,7 +317,7 @@ void VGrainlineItem::mousePressEvent(QGraphicsSceneMouseEvent* pME) SetOverrideCursor(cursorArrowCloseHand, 1, 1); } setZValue(ACTIVE_Z); - UpdateBox(); + Update(); } } @@ -378,7 +340,7 @@ void VGrainlineItem::mouseMoveEvent(QGraphicsSceneMouseEvent* pME) pt.setY(pt.y() + dY); } setPos(pt); - UpdateBox(); + Update(); } else if (m_eMode == mResize) { @@ -395,7 +357,7 @@ void VGrainlineItem::mouseMoveEvent(QGraphicsSceneMouseEvent* pME) m_dLength = dPrevLen; } UpdateRectangle(); - UpdateBox(); + Update(); } else if (m_eMode == mRotate) { @@ -419,7 +381,7 @@ void VGrainlineItem::mouseMoveEvent(QGraphicsSceneMouseEvent* pME) setPos(ptNewPos); m_dRotation = m_dStartRotation + dAng; UpdateRectangle(); - UpdateBox(); + Update(); } } } @@ -454,7 +416,7 @@ void VGrainlineItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* pME) if (m_bReleased == true) { m_eMode = mRotate; - UpdateBox(); + Update(); } } else @@ -467,7 +429,7 @@ void VGrainlineItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* pME) { emit SignalResized(m_dLength); } - UpdateBox(); + Update(); } } else @@ -480,7 +442,7 @@ void VGrainlineItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* pME) { emit SignalRotated(m_dRotation, m_ptStart); } - UpdateBox(); + Update(); } m_bReleased = true; } @@ -490,7 +452,7 @@ void VGrainlineItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* pME) /** * @brief VGrainlineItem::UpdateBox updates the item */ -void VGrainlineItem::UpdateBox() +void VGrainlineItem::Update() { update(m_rectBoundingBox); } @@ -549,28 +511,6 @@ void VGrainlineItem::UpdateRectangle() prepareGeometryChange(); } -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief VGrainlineItem::GetAngle calculates the angle between the line, which goes from - * rotation center to pt and x axis - * @param pt point of interest - * @return the angle between line from rotation center and point of interest and x axis - */ -qreal VGrainlineItem::GetAngle(const QPointF& pt) const -{ - double dX = pt.x() - m_ptRotCenter.x(); - double dY = pt.y() - m_ptRotCenter.y(); - - if (fabs(dX) < 1 && fabs(dY) < 1) - { - return 0; - } - else - { - return qAtan2(-dY, dX); - } -} - //--------------------------------------------------------------------------------------------------------------------- /** * @brief VGrainlineItem::Rotate rotates point pt around ptCenter by angle dAng [rad] diff --git a/src/libs/vwidgets/vgrainlineitem.h b/src/libs/vwidgets/vgrainlineitem.h new file mode 100644 index 000000000..7f4217d54 --- /dev/null +++ b/src/libs/vwidgets/vgrainlineitem.h @@ -0,0 +1,86 @@ +/************************************************************************ + ** + ** @file vgrainlineitem.h + ** @author Bojan Kverh + ** @date September 10, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2013-2015 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#ifndef VGRAINLINEITEM_H +#define VGRAINLINEITEM_H + +#include "vpieceitem.h" +#include "../vpatterndb/vgrainlinegeometry.h" + +class QGraphicsObject; +class QPainter; +class QStyleOptionGraphicsItem; +class QWidget; + +class VGrainlineItem : public VPieceItem +{ + Q_OBJECT +public: + explicit VGrainlineItem(QGraphicsItem* pParent = nullptr); + virtual ~VGrainlineItem(); + + virtual void paint(QPainter* pP, const QStyleOptionGraphicsItem* pOption, QWidget* pWidget) Q_DECL_OVERRIDE; + void UpdateGeometry(const QPointF& ptPos, qreal dRotation, qreal dLength, + VGrainlineGeometry::ArrowType eAT); + + bool IsContained(const QPointF &pt, qreal dRot, qreal &dX, qreal &dY) const; + void SetScale(qreal dScale); + +signals: + void SignalResized(qreal dLength); + void SignalRotated(qreal dRot, const QPointF& ptNewPos); + +protected: + virtual void mousePressEvent(QGraphicsSceneMouseEvent* pME) Q_DECL_OVERRIDE; + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent* pME) Q_DECL_OVERRIDE; + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent* pME) Q_DECL_OVERRIDE; + virtual void Update() Q_DECL_OVERRIDE; + void UpdateRectangle(); + + QPointF Rotate(const QPointF& pt, const QPointF& ptCenter, qreal dAng) const; + QPointF GetInsideCorner(int i, qreal dDist) const; + +private: + Q_DISABLE_COPY(VGrainlineItem) + qreal m_dRotation; + qreal m_dStartRotation; + qreal m_dLength; + QPolygonF m_polyBound; + QPointF m_ptStartPos; + QPointF m_ptStartMove; + qreal m_dScale; + QPolygonF m_polyResize; + qreal m_dStartLength; + QPointF m_ptStart; + QPointF m_ptFinish; + QPointF m_ptCenter; + qreal m_dAngle; + VGrainlineGeometry::ArrowType m_eArrowType; +}; + +#endif // VGRAINLINEITEM_H diff --git a/src/libs/vwidgets/vmaingraphicsscene.cpp b/src/libs/vwidgets/vmaingraphicsscene.cpp index 8bae83fbe..f87a1648a 100644 --- a/src/libs/vwidgets/vmaingraphicsscene.cpp +++ b/src/libs/vwidgets/vmaingraphicsscene.cpp @@ -51,8 +51,13 @@ class QRectF; /** * @brief VMainGraphicsScene default constructor. */ -VMainGraphicsScene::VMainGraphicsScene() - :QGraphicsScene(), horScrollBar(0), verScrollBar(0), scaleFactor(1), _transform(QTransform()), scenePos(QPointF()), +VMainGraphicsScene::VMainGraphicsScene(QObject *parent) + : QGraphicsScene(parent), + horScrollBar(0), + verScrollBar(0), + scaleFactor(1), + _transform(QTransform()), + scenePos(QPointF()), origins() {} diff --git a/src/libs/vwidgets/vmaingraphicsscene.h b/src/libs/vwidgets/vmaingraphicsscene.h index 5cf079636..fc581bd1e 100644 --- a/src/libs/vwidgets/vmaingraphicsscene.h +++ b/src/libs/vwidgets/vmaingraphicsscene.h @@ -54,7 +54,7 @@ class VMainGraphicsScene : public QGraphicsScene { Q_OBJECT public: - VMainGraphicsScene(); + explicit VMainGraphicsScene(QObject *parent = nullptr); explicit VMainGraphicsScene(const QRectF & sceneRect, QObject * parent = nullptr); qint32 getHorScrollBar() const; void setHorScrollBar(const qint32 &value); diff --git a/src/libs/vwidgets/vpieceitem.cpp b/src/libs/vwidgets/vpieceitem.cpp new file mode 100644 index 000000000..f7f969fed --- /dev/null +++ b/src/libs/vwidgets/vpieceitem.cpp @@ -0,0 +1,108 @@ +/************************************************************************ + ** + ** @file + ** @author Roman Telezhynskyi <dismine(at)gmail.com> + ** @date 18 1, 2017 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2017 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#include "vpieceitem.h" +#include "../vmisc/vmath.h" + +#include <QGraphicsScene> + +//--------------------------------------------------------------------------------------------------------------------- +VPieceItem::VPieceItem(QGraphicsItem *pParent) + : QGraphicsObject(pParent), + m_rectBoundingBox(), + m_eMode(VPieceItem::mNormal), + m_bReleased(false), + m_ptRotCenter(), + m_inactiveZ(1) +{ + m_rectBoundingBox.setTopLeft(QPointF(0, 0)); + setAcceptHoverEvents(true); +} + +//--------------------------------------------------------------------------------------------------------------------- +VPieceItem::~VPieceItem() +{ +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief boundingRect returns the item bounding box + * @return item bounding box + */ +QRectF VPieceItem::boundingRect() const +{ + return m_rectBoundingBox; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Reset resets the item, putting the mode and z coordinate to normal and redraws it + */ +void VPieceItem::Reset() +{ + if (QGraphicsScene *toolScene = scene()) + { + toolScene->clearSelection(); + } + m_eMode = mNormal; + m_bReleased = false; + Update(); + setZValue(m_inactiveZ); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief IsIdle returns the idle flag. + * @return true, if item mode is normal and false otherwise. + */ +bool VPieceItem::IsIdle() const +{ + return m_eMode == mNormal; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief GetAngle calculates the angle between the line, which goes from rotation center to pt and x axis + * @param pt point of interest + * @return the angle between line from rotation center and point of interest and x axis + */ +double VPieceItem::GetAngle(const QPointF &pt) const +{ + const double dX = pt.x() - m_ptRotCenter.x(); + const double dY = pt.y() - m_ptRotCenter.y(); + + if (fabs(dX) < 1 && fabs(dY) < 1) + { + return 0; + } + else + { + return qAtan2(dY, dX); + } +} + diff --git a/src/libs/vwidgets/vpieceitem.h b/src/libs/vwidgets/vpieceitem.h new file mode 100644 index 000000000..7b3306044 --- /dev/null +++ b/src/libs/vwidgets/vpieceitem.h @@ -0,0 +1,73 @@ +/************************************************************************ + ** + ** @file + ** @author Roman Telezhynskyi <dismine(at)gmail.com> + ** @date 18 1, 2017 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2017 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#ifndef VPIECEITEM_H +#define VPIECEITEM_H + +#include <QtCore/qglobal.h> +#include <QGraphicsObject> + +class VPieceItem : public QGraphicsObject +{ + Q_OBJECT +public: + explicit VPieceItem(QGraphicsItem* pParent = nullptr); + virtual ~VPieceItem(); + + virtual QRectF boundingRect() const Q_DECL_OVERRIDE; + + virtual void Update() =0; + + void Reset(); + bool IsIdle() const; + + double GetAngle(const QPointF &pt) const; + +signals: + void SignalMoved(const QPointF &ptPos); + +protected: + enum Mode + { + mNormal, + mMove, + mResize, + mRotate + }; + QRectF m_rectBoundingBox; + Mode m_eMode; + bool m_bReleased; + QPointF m_ptRotCenter; + + qreal m_inactiveZ; + +private: + Q_DISABLE_COPY(VPieceItem) +}; + +#endif // VPIECEITEM_H diff --git a/src/libs/vwidgets/vsimplepoint.cpp b/src/libs/vwidgets/vsimplepoint.cpp index 676dbcf48..8d1980e3a 100644 --- a/src/libs/vwidgets/vsimplepoint.cpp +++ b/src/libs/vwidgets/vsimplepoint.cpp @@ -53,8 +53,14 @@ class QKeyEvent; //--------------------------------------------------------------------------------------------------------------------- VSimplePoint::VSimplePoint(quint32 id, const QColor ¤tColor, Unit patternUnit, qreal *factor, QObject *parent) - :VAbstractSimple(id, currentColor, patternUnit, factor, parent), QGraphicsEllipseItem(), - radius(ToPixel(DefPointRadius/*mm*/, Unit::Mm)), namePoint(nullptr), lineName(nullptr) + : VAbstractSimple(id, currentColor, patternUnit, factor, parent), + QGraphicsEllipseItem(), + radius(ToPixel(DefPointRadius/*mm*/, Unit::Mm)), + namePoint(nullptr), + lineName(nullptr), + m_onlyPoint(false), + m_isHighlight(false), + m_visualizationMode(false) { namePoint = new VGraphicsSimpleTextItem(this); connect(namePoint, &VGraphicsSimpleTextItem::ShowContextMenu, this, &VSimplePoint::ContextMenu); @@ -64,7 +70,7 @@ VSimplePoint::VSimplePoint(quint32 id, const QColor ¤tColor, Unit patternU connect(namePoint, &VGraphicsSimpleTextItem::NameChangePosition, this, &VSimplePoint::ChangedPosition); lineName = new QGraphicsLineItem(this); this->setBrush(QBrush(Qt::NoBrush)); - SetPen(this, currentColor, WidthHairLine(patternUnit)); + SetPen(this, currentColor, m_isHighlight ? WidthMainLine(patternUnit) : WidthHairLine(patternUnit)); this->setAcceptHoverEvents(true); this->setFlag(QGraphicsItem::ItemIsFocusable, true);// For keyboard input focus } @@ -73,6 +79,39 @@ VSimplePoint::VSimplePoint(quint32 id, const QColor ¤tColor, Unit patternU VSimplePoint::~VSimplePoint() {} +//--------------------------------------------------------------------------------------------------------------------- +void VSimplePoint::SetOnlyPoint(bool value) +{ + m_onlyPoint = value; + namePoint->setVisible(not m_onlyPoint); + lineName->setVisible(not m_onlyPoint); +} + +//--------------------------------------------------------------------------------------------------------------------- +bool VSimplePoint::IsOnlyPoint() const +{ + return m_onlyPoint; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VSimplePoint::SetVisualizationMode(bool value) +{ + m_visualizationMode = value; + this->setFlag(QGraphicsItem::ItemIsFocusable, not m_visualizationMode); +} + +//--------------------------------------------------------------------------------------------------------------------- +bool VSimplePoint::IsVisualizationMode() const +{ + return m_visualizationMode; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VSimplePoint::SetPointHighlight(bool value) +{ + m_isHighlight = value; +} + //--------------------------------------------------------------------------------------------------------------------- void VSimplePoint::RefreshLine() { @@ -106,7 +145,7 @@ void VSimplePoint::RefreshLine() void VSimplePoint::RefreshGeometry(const VPointF &point) { this->setFlag(QGraphicsItem::ItemSendsGeometryChanges, false); - SetPen(this, currentColor, WidthHairLine(patternUnit)); + SetPen(this, currentColor, m_isHighlight ? WidthMainLine(patternUnit) : WidthHairLine(patternUnit)); QRectF rec = QRectF(0, 0, radius*2, radius*2); rec.translate(-rec.center().x(), -rec.center().y()); this->setRect(rec); @@ -127,7 +166,7 @@ void VSimplePoint::RefreshGeometry(const VPointF &point) void VSimplePoint::SetEnabled(bool enabled) { VAbstractSimple::SetEnabled(enabled); - SetPen(this, currentColor, WidthHairLine(patternUnit)); + SetPen(this, currentColor, m_isHighlight ? WidthMainLine(patternUnit) : WidthHairLine(patternUnit)); SetPen(lineName, Qt::black, WidthHairLine(patternUnit)); namePoint->setEnabled(enabled); } @@ -184,24 +223,31 @@ void VSimplePoint::ChangedPosition(const QPointF &pos) //--------------------------------------------------------------------------------------------------------------------- void VSimplePoint::mousePressEvent(QGraphicsSceneMouseEvent *event) { - // Special for not selectable item first need to call standard mousePressEvent then accept event - QGraphicsEllipseItem::mousePressEvent(event); - - // Somehow clicking on notselectable object do not clean previous selections. - if (not (flags() & ItemIsSelectable) && scene()) + if (m_visualizationMode) { - scene()->clearSelection(); - } - - if (selectionType == SelectionType::ByMouseRelease) - { - event->accept();// Special for not selectable item first need to call standard mousePressEvent then accept event + event->ignore(); } else { - if (event->button() == Qt::LeftButton) + // Special for not selectable item first need to call standard mousePressEvent then accept event + QGraphicsEllipseItem::mousePressEvent(event); + + // Somehow clicking on notselectable object do not clean previous selections. + if (not (flags() & ItemIsSelectable) && scene()) { - emit Choosed(id); + scene()->clearSelection(); + } + + if (selectionType == SelectionType::ByMouseRelease) + {// Special for not selectable item first need to call standard mousePressEvent then accept event + event->accept(); + } + else + { + if (event->button() == Qt::LeftButton) + { + emit Choosed(id); + } } } } @@ -209,14 +255,17 @@ void VSimplePoint::mousePressEvent(QGraphicsSceneMouseEvent *event) //--------------------------------------------------------------------------------------------------------------------- void VSimplePoint::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { - if (selectionType == SelectionType::ByMouseRelease) + if (not m_visualizationMode) { - if (event->button() == Qt::LeftButton) + if (selectionType == SelectionType::ByMouseRelease) { - emit Choosed(id); + if (event->button() == Qt::LeftButton) + { + emit Choosed(id); + } } + QGraphicsEllipseItem::mouseReleaseEvent(event); } - QGraphicsEllipseItem::mouseReleaseEvent(event); } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/vwidgets/vsimplepoint.h b/src/libs/vwidgets/vsimplepoint.h index 009f914e0..7378f5362 100644 --- a/src/libs/vwidgets/vsimplepoint.h +++ b/src/libs/vwidgets/vsimplepoint.h @@ -62,6 +62,14 @@ public: virtual int type() const Q_DECL_OVERRIDE {return Type;} enum { Type = UserType + static_cast<int>(Vis::SimplePoint)}; + void SetOnlyPoint(bool value); + bool IsOnlyPoint() const; + + void SetVisualizationMode(bool value); + bool IsVisualizationMode() const; + + void SetPointHighlight(bool value); + void RefreshLine(); void RefreshGeometry(const VPointF &point); virtual void SetEnabled(bool enabled) Q_DECL_OVERRIDE; @@ -104,6 +112,10 @@ private: /** @brief lineName line what we see if label moved too away from point. */ QGraphicsLineItem *lineName; + + bool m_onlyPoint; + bool m_isHighlight; + bool m_visualizationMode; }; #endif // VSIMPLEPOINT_H diff --git a/src/libs/vtools/tools/vtextgraphicsitem.cpp b/src/libs/vwidgets/vtextgraphicsitem.cpp similarity index 90% rename from src/libs/vtools/tools/vtextgraphicsitem.cpp rename to src/libs/vwidgets/vtextgraphicsitem.cpp index d9b815266..c423a04b8 100644 --- a/src/libs/vtools/tools/vtextgraphicsitem.cpp +++ b/src/libs/vwidgets/vtextgraphicsitem.cpp @@ -55,32 +55,85 @@ const qreal rotateCircle = (2./*mm*/ / 25.4) * PrintDPI; #define ROTATE_ARC 50 const qreal minW = (4./*mm*/ / 25.4) * PrintDPI + resizeSquare; const qreal minH = (4./*mm*/ / 25.4) * PrintDPI + resizeSquare; -#define INACTIVE_Z 2 #define ACTIVE_Z 10 +namespace +{ +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief GetBoundingRect calculates the bounding box around rectBB rectangle, rotated around its center by dRot degrees + * @param rectBB rectangle of interest + * @param dRot rectangle rotation + * @return bounding box around rectBB rotated by dRot + */ +QRectF GetBoundingRect(QRectF rectBB, qreal dRot) +{ + QPointF apt[4] = { rectBB.topLeft(), rectBB.topRight(), rectBB.bottomLeft(), rectBB.bottomRight() }; + QPointF ptCenter = rectBB.center(); + + qreal dX1 = 0; + qreal dX2 = 0; + qreal dY1 = 0; + qreal dY2 = 0; + + double dAng = qDegreesToRadians(dRot); + for (int i = 0; i < 4; ++i) + { + QPointF pt = apt[i] - ptCenter; + qreal dX = pt.x()*cos(dAng) + pt.y()*sin(dAng); + qreal dY = -pt.x()*sin(dAng) + pt.y()*cos(dAng); + + if (i == 0) + { + dX1 = dX2 = dX; + dY1 = dY2 = dY; + } + else + { + if (dX < dX1) + { + dX1 = dX; + } + else if (dX > dX2) + { + dX2 = dX; + } + if (dY < dY1) + { + dY1 = dY; + } + else if (dY > dY2) + { + dY2 = dY; + } + } + } + QRectF rect; + rect.setTopLeft(ptCenter + QPointF(dX1, dY1)); + rect.setWidth(dX2 - dX1); + rect.setHeight(dY2 - dY1); + return rect; +} +}//static functions + //--------------------------------------------------------------------------------------------------------------------- /** * @brief VTextGraphicsItem::VTextGraphicsItem constructor * @param pParent pointer to the parent item */ VTextGraphicsItem::VTextGraphicsItem(QGraphicsItem* pParent) - : QGraphicsObject(pParent), - m_eMode(VTextGraphicsItem::mNormal), - m_bReleased(false), + : VPieceItem(pParent), m_ptStartPos(), m_ptStart(), - m_ptRotCenter(), m_szStart(), m_dRotation(0), m_dAngle(0), m_rectResize(), - m_rectBoundingBox(), m_tm() { - m_rectBoundingBox.setTopLeft(QPointF(0, 0)); + m_inactiveZ = 2; SetSize(minW, minH); - setZValue(INACTIVE_Z); - setAcceptHoverEvents(true); + setZValue(m_inactiveZ); } //--------------------------------------------------------------------------------------------------------------------- @@ -195,28 +248,6 @@ void VTextGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem } } -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief VTextGraphicsItem::Reset resets the item, putting the mode and z coordinate to normal and redraws it - */ -void VTextGraphicsItem::Reset() -{ - m_eMode = mNormal; - m_bReleased = false; - Update(); - setZValue(INACTIVE_Z); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief VTextGraphicsItem::IsIdle checks if the item is in normal mode. - * @return true, if item is in normal mode and false otherwise. - */ -bool VTextGraphicsItem::IsIdle() const -{ - return m_eMode == mNormal; -} - //--------------------------------------------------------------------------------------------------------------------- /** * @brief VTextGraphicsItem::AddLine adds a line of text to the label list. @@ -369,16 +400,6 @@ int VTextGraphicsItem::GetFontSize() const return m_tm.GetFont().pixelSize(); } -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief VTextGraphicsItem::boundingRect returns the label bounding box - * @return label bounding box - */ -QRectF VTextGraphicsItem::boundingRect() const -{ - return m_rectBoundingBox; -} - //--------------------------------------------------------------------------------------------------------------------- /** * @brief VTextGraphicsItem::mousePressEvent handles left button mouse press events @@ -612,82 +633,3 @@ void VTextGraphicsItem::CorrectLabel() m_tm.FitFontSize(m_rectBoundingBox.width(), m_rectBoundingBox.height()); UpdateBox(); } - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief VTextGraphicsItem::GetAngle calculates the angle between the line, which goes from - * rotation center to pt and x axis - * @param pt point of interest - * @return the angle between line from rotation center and point of interest and x axis - */ -double VTextGraphicsItem::GetAngle(QPointF pt) const -{ - double dX = pt.x() - m_ptRotCenter.x(); - double dY = pt.y() - m_ptRotCenter.y(); - - if (fabs(dX) < 1 && fabs(dY) < 1) - { - return 0; - } - else - { - return qAtan2(dY, dX); - } -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief VTextGraphicsItem::GetBoundingRect calculates the bounding box - * around rectBB rectangle, rotated around its center by dRot degrees - * @param rectBB rectangle of interest - * @param dRot rectangle rotation - * @return bounding box around rectBB rotated by dRot - */ -QRectF VTextGraphicsItem::GetBoundingRect(QRectF rectBB, qreal dRot) const -{ - QPointF apt[4] = { rectBB.topLeft(), rectBB.topRight(), rectBB.bottomLeft(), rectBB.bottomRight() }; - QPointF ptCenter = rectBB.center(); - - qreal dX1 = 0; - qreal dX2 = 0; - qreal dY1 = 0; - qreal dY2 = 0; - - double dAng = qDegreesToRadians(dRot); - for (int i = 0; i < 4; ++i) - { - QPointF pt = apt[i] - ptCenter; - qreal dX = pt.x()*cos(dAng) + pt.y()*sin(dAng); - qreal dY = -pt.x()*sin(dAng) + pt.y()*cos(dAng); - - if (i == 0) - { - dX1 = dX2 = dX; - dY1 = dY2 = dY; - } - else - { - if (dX < dX1) - { - dX1 = dX; - } - else if (dX > dX2) - { - dX2 = dX; - } - if (dY < dY1) - { - dY1 = dY; - } - else if (dY > dY2) - { - dY2 = dY; - } - } - } - QRectF rect; - rect.setTopLeft(ptCenter + QPointF(dX1, dY1)); - rect.setWidth(dX2 - dX1); - rect.setHeight(dY2 - dY1); - return rect; -} diff --git a/src/libs/vwidgets/vtextgraphicsitem.h b/src/libs/vwidgets/vtextgraphicsitem.h new file mode 100644 index 000000000..1748ddc9c --- /dev/null +++ b/src/libs/vwidgets/vtextgraphicsitem.h @@ -0,0 +1,109 @@ +/************************************************************************ + ** + ** @file vtextgraphicsitem.h + ** @author Bojan Kverh + ** @date June 16, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2013-2015 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#ifndef VTEXTGRAPHICSITEM_H +#define VTEXTGRAPHICSITEM_H + +#include <QFont> +#include <QGraphicsObject> +#include <QList> +#include <QMetaObject> +#include <QObject> +#include <QPointF> +#include <QRectF> +#include <QSizeF> +#include <QString> +#include <QtGlobal> + +#include "vpieceitem.h" +#include "../vlayout/vtextmanager.h" + +class QFont; +class QGraphicsItem; +class QGraphicsSceneHoverEvent; +class QGraphicsSceneMouseEvent; +class QPainter; +class QPointF; +class QRectF; +class QStyleOptionGraphicsItem; +class QWidget; +class VAbstractPattern; +class VPatternPieceData; + +/** + * @brief The VTextGraphicsItem class. This class implements text graphics item, + * which can be dragged around, resized and rotated within the parent item. The text font + * size will be automatically updated, so that the entire text will fit into the item. + */ +class VTextGraphicsItem : public VPieceItem +{ + Q_OBJECT +public: + explicit VTextGraphicsItem(QGraphicsItem* pParent = nullptr); + virtual ~VTextGraphicsItem(); + + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) Q_DECL_OVERRIDE; + virtual void Update() Q_DECL_OVERRIDE; + + void SetFont(const QFont& fnt); + int GetFontSize() const; + void AddLine(const TextLine& tl); + void Clear(); + void SetSize(qreal fW, qreal fH); + bool IsContained(QRectF rectBB, qreal dRot, qreal& dX, qreal& dY) const; + void UpdateData(const QString& qsName, const VPatternPieceData& data); + void UpdateData(const VAbstractPattern* pDoc, qreal dSize, qreal dHeight); + int GetTextLines() const; + +protected: + virtual void mousePressEvent(QGraphicsSceneMouseEvent* pME) Q_DECL_OVERRIDE; + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent* pME) Q_DECL_OVERRIDE; + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent* pME) Q_DECL_OVERRIDE; + virtual void hoverMoveEvent(QGraphicsSceneHoverEvent* pHE) Q_DECL_OVERRIDE; + virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent* pHE) Q_DECL_OVERRIDE; + + void UpdateBox(); + void CorrectLabel(); + +signals: + void SignalResized(qreal iTW, int iFontSize); + void SignalRotated(qreal dAng); + void SignalShrink(); + +private: + Q_DISABLE_COPY(VTextGraphicsItem) + QPointF m_ptStartPos; + QPointF m_ptStart; + QSizeF m_szStart; + double m_dRotation; + double m_dAngle; + QRectF m_rectResize; + VTextManager m_tm; +}; + +#endif // VTEXTGRAPHICSITEM_H diff --git a/src/libs/vwidgets/vwidgets.pri b/src/libs/vwidgets/vwidgets.pri index 042607eb2..1f3219b8f 100644 --- a/src/libs/vwidgets/vwidgets.pri +++ b/src/libs/vwidgets/vwidgets.pri @@ -11,7 +11,10 @@ SOURCES += \ $$PWD/vabstractsimple.cpp \ $$PWD/vnobrushscalepathitem.cpp \ $$PWD/vsimplecurve.cpp \ - $$PWD/vabstractmainwindow.cpp + $$PWD/vabstractmainwindow.cpp \ + $$PWD/vtextgraphicsitem.cpp \ + $$PWD/vgrainlineitem.cpp \ + $$PWD/vpieceitem.cpp win32-msvc*:SOURCES += $$PWD/stable.cpp @@ -26,4 +29,7 @@ HEADERS += \ $$PWD/vabstractsimple.h \ $$PWD/vnobrushscalepathitem.h \ $$PWD/vsimplecurve.h \ - $$PWD/vabstractmainwindow.h + $$PWD/vabstractmainwindow.h \ + $$PWD/vtextgraphicsitem.h \ + $$PWD/vgrainlineitem.h \ + $$PWD/vpieceitem.h diff --git a/src/test/TranslationsTest/tst_buitinregexp.cpp b/src/test/TranslationsTest/tst_buitinregexp.cpp index 60a2b30e3..1ae953068 100644 --- a/src/test/TranslationsTest/tst_buitinregexp.cpp +++ b/src/test/TranslationsTest/tst_buitinregexp.cpp @@ -138,6 +138,7 @@ void TST_BuitInRegExp::TestCheckUnderlineExists_data() data.insert(angle2SplPath, false); data.insert(seg_, true); data.insert(currentLength, false); + data.insert(currentSeamAllowance, false); data.insert(c1LengthSpl_, true); data.insert(c2LengthSpl_, true); data.insert(c1LengthSplPath, false); diff --git a/src/test/ValentinaTest/ValentinaTest.pro b/src/test/ValentinaTest/ValentinaTest.pro index d4aab2df2..0427cb402 100644 --- a/src/test/ValentinaTest/ValentinaTest.pro +++ b/src/test/ValentinaTest/ValentinaTest.pro @@ -36,7 +36,6 @@ DEFINES += SRCDIR=\\\"$$PWD/\\\" SOURCES += \ qttestmainlambda.cpp \ tst_vposter.cpp \ - tst_vabstractdetail.cpp \ tst_vspline.cpp \ tst_nameregexp.cpp \ tst_vlayoutdetail.cpp \ @@ -46,7 +45,7 @@ SOURCES += \ tst_vlockguard.cpp \ tst_misc.cpp \ tst_vcommandline.cpp \ - tst_vdetail.cpp \ + tst_vpiece.cpp \ tst_vabstractcurve.cpp \ tst_findpoint.cpp \ tst_vellipticalarc.cpp \ @@ -55,13 +54,13 @@ SOURCES += \ tst_vsplinepath.cpp \ tst_vpointf.cpp \ tst_readval.cpp \ - tst_vtranslatevars.cpp + tst_vtranslatevars.cpp \ + tst_vabstractpiece.cpp win32-msvc*:SOURCES += stable.cpp HEADERS += \ tst_vposter.h \ - tst_vabstractdetail.h \ tst_vspline.h \ tst_nameregexp.h \ tst_vlayoutdetail.h \ @@ -72,7 +71,7 @@ HEADERS += \ tst_vlockguard.h \ tst_misc.h \ tst_vcommandline.h \ - tst_vdetail.h \ + tst_vpiece.h \ tst_vabstractcurve.h \ tst_findpoint.h \ tst_vellipticalarc.h \ @@ -81,7 +80,8 @@ HEADERS += \ tst_vsplinepath.h \ tst_vpointf.h \ tst_readval.h \ - tst_vtranslatevars.h + tst_vtranslatevars.h \ + tst_vabstractpiece.h # Set using ccache. Function enable_ccache() defined in common.pri. $$enable_ccache() diff --git a/src/test/ValentinaTest/qttestmainlambda.cpp b/src/test/ValentinaTest/qttestmainlambda.cpp index 60997e2ee..8a3537b56 100644 --- a/src/test/ValentinaTest/qttestmainlambda.cpp +++ b/src/test/ValentinaTest/qttestmainlambda.cpp @@ -29,7 +29,7 @@ #include <QtTest> #include "tst_vposter.h" -#include "tst_vabstractdetail.h" +#include "tst_vabstractpiece.h" #include "tst_vspline.h" #include "tst_nameregexp.h" #include "tst_vlayoutdetail.h" @@ -40,7 +40,7 @@ #include "tst_vlockguard.h" #include "tst_misc.h" #include "tst_vcommandline.h" -#include "tst_vdetail.h" +#include "tst_vpiece.h" #include "tst_findpoint.h" #include "tst_vabstractcurve.h" #include "tst_vcubicbezierpath.h" @@ -67,9 +67,9 @@ int main(int argc, char** argv) }; ASSERT_TEST(new TST_FindPoint()); - ASSERT_TEST(new TST_VDetail()); + ASSERT_TEST(new TST_VPiece()); ASSERT_TEST(new TST_VPoster()); - ASSERT_TEST(new TST_VAbstractDetail()); + ASSERT_TEST(new TST_VAbstractPiece()); ASSERT_TEST(new TST_VSpline()); ASSERT_TEST(new TST_VSplinePath()); ASSERT_TEST(new TST_NameRegExp()); diff --git a/src/test/ValentinaTest/tst_vabstractcurve.cpp b/src/test/ValentinaTest/tst_vabstractcurve.cpp index 3b5c04da5..0ce69d462 100644 --- a/src/test/ValentinaTest/tst_vabstractcurve.cpp +++ b/src/test/ValentinaTest/tst_vabstractcurve.cpp @@ -113,3 +113,76 @@ void TST_VAbstractCurve::GetSegmentPoints_issue458() // Begin comparison Comparison(points, origPoints); } + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VAbstractCurve::IsPointOnCurve_data() const +{ + QTest::addColumn<QVector<QPointF>>("points"); + QTest::addColumn<QPointF>("point"); + QTest::addColumn<bool>("expectedResult"); + + + QVector<QPointF> points; + points << QPointF(714.5704733515146, 229.44783247230293); + points << QPointF(713.2432059361518, 236.799577781511); + points << QPointF(709.8892587314249, 252.1363394689535); + points << QPointF(703.6056072956214, 276.4001729111941); + points << QPointF(687.7559494358588, 329.1513838344773); + points << QPointF(670.3756426535148, 387.2408887452223); + points << QPointF(662.3317449567428, 417.643760273044); + points << QPointF(657.4471488294345, 438.31881594794856); + points << QPointF(653.1084257285696, 459.2974181766972); + points << QPointF(649.4426552757304, 480.5376973511262); + points << QPointF(646.5769170924987, 501.9977838630714); + points << QPointF(644.6382908004568, 523.6358081043691); + points << QPointF(644.1029291338583, 534.5132598425197); + points << QPointF(644.1029291338583, 534.5132598425197); + points << QPointF(643.4592698551749, 551.9888717674471); + points << QPointF(642.9134698671897, 584.1776423714557); + points << QPointF(643.1914832622404, 613.2382010061506); + points << QPointF(644.2199668178571, 639.3780275889782); + points << QPointF(645.9255773115714, 662.8046020373845); + points << QPointF(648.2349715209137, 683.7254042688159); + points << QPointF(651.0748062234152, 702.3479142007185); + points << QPointF(654.3717381966065, 718.8796117505387); + points << QPointF(658.0524242180187, 733.5279768357226); + points << QPointF(662.0435210651824, 746.5004893737165); + points << QPointF(666.2716855156286, 758.0046292819667); + points << QPointF(670.6635743468883, 768.2478764779191); + points << QPointF(677.400406718071, 781.7952098705392); + points << QPointF(686.2864119958404, 797.2061069980141); + points << QPointF(690.4766621750516, 804.2970071162871); + points << QPointF(690.4766621750516, 804.2970071162871); + points << QPointF(692.7921674626707, 808.1521079045636); + points << QPointF(697.7183992280718, 815.2245015705212); + points << QPointF(702.9886930214004, 821.5595818277402); + points << QPointF(708.5917117312482, 827.1885221028615); + points << QPointF(714.5161182462067, 832.1424958225257); + points << QPointF(720.750575454867, 836.4526764133732); + points << QPointF(727.2837462458206, 840.1502373020446); + points << QPointF(734.1042935076591, 843.2663519151808); + points << QPointF(741.200880128974, 845.8321936794223); + points << QPointF(748.5621689983566, 847.8789360214096); + points << QPointF(756.1768230043983, 849.4377523677833); + points << QPointF(764.0335050356908, 850.5398161451842); + points << QPointF(772.1208779808252, 851.2163007802526); + points << QPointF(780.4276047283932, 851.4983796996295); + points << QPointF(793.250306920113, 851.2897382511853); + points << QPointF(802.0871811023624, 850.6707401574804); + + QPointF point(652.5169278885382, 462.6106569368444); + + // See file collection/bug/pointOnCurve.val + QTest::newRow("Point on curve") << points << point << true; +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VAbstractCurve::IsPointOnCurve() const +{ + QFETCH(QVector<QPointF>, points); + QFETCH(QPointF, point); + QFETCH(bool, expectedResult); + + bool result = VAbstractCurve::IsPointOnCurve(points, point); + QCOMPARE(result, expectedResult); +} diff --git a/src/test/ValentinaTest/tst_vabstractcurve.h b/src/test/ValentinaTest/tst_vabstractcurve.h index 7ffd2d773..565b995f2 100644 --- a/src/test/ValentinaTest/tst_vabstractcurve.h +++ b/src/test/ValentinaTest/tst_vabstractcurve.h @@ -39,7 +39,8 @@ public: private slots: void GetSegmentPoints_issue458(); - + void IsPointOnCurve_data() const; + void IsPointOnCurve() const; }; #endif // TST_VABSTRACTCURVE_H diff --git a/src/test/ValentinaTest/tst_vabstractdetail.cpp b/src/test/ValentinaTest/tst_vabstractdetail.cpp deleted file mode 100644 index 9a900dc89..000000000 --- a/src/test/ValentinaTest/tst_vabstractdetail.cpp +++ /dev/null @@ -1,1386 +0,0 @@ -/************************************************************************ - ** - ** @file tst_vabstractdetail.cpp - ** @author Roman Telezhynskyi <dismine(at)gmail.com> - ** @date 16 4, 2015 - ** - ** @brief - ** @copyright - ** This source code is part of the Valentine project, a pattern making - ** program, whose allow create and modeling patterns of clothing. - ** Copyright (C) 2015 Valentina project - ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. - ** - ** Valentina is free software: you can redistribute it and/or modify - ** it under the terms of the GNU General Public License as published by - ** the Free Software Foundation, either version 3 of the License, or - ** (at your option) any later version. - ** - ** Valentina is distributed in the hope that it will be useful, - ** but WITHOUT ANY WARRANTY; without even the implied warranty of - ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - ** GNU General Public License for more details. - ** - ** You should have received a copy of the GNU General Public License - ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. - ** - *************************************************************************/ - -#include "tst_vabstractdetail.h" -#include "../vlayout/vabstractdetail.h" - -#include <QPointF> -#include <QVector> - -#include <QtTest> - -//--------------------------------------------------------------------------------------------------------------------- -TST_VAbstractDetail::TST_VAbstractDetail(QObject *parent) - :AbstractTest(parent) -{ -} - -//--------------------------------------------------------------------------------------------------------------------- -void TST_VAbstractDetail::EquidistantRemoveLoop_data() -{ - QTest::addColumn<QVector<QPointF>>("points"); - QTest::addColumn<int>("eqv"); - QTest::addColumn<qreal>("width"); - QTest::addColumn<QVector<QPointF>>("ekvOrig"); - - // These are two real cases where equdistant has loop. - // See issue #298. Segmented Curve isn't selected in Seam Allowance tool. - // https://bitbucket.org/dismine/valentina/issue/298/segmented-curve-isnt-selected-in-seam - // Code should clean loops in path. - QTest::newRow("Issue 298. Case1") << InputPointsIssue298Case1() - << static_cast<int>(EquidistantType::CloseEquidistant) - << 75.5906 // seam allowance width - << OutputPointsIssue298Case1(); - - QTest::newRow("Issue 298. Case2") << InputPointsIssue298Case2() - << static_cast<int>(EquidistantType::CloseEquidistant) - << 37.7953 // seam allowance width - << OutputPointsIssue298Case2(); - - // See issue #548. Bug Detail tool. Case when seam allowance is wrong. - // https://bitbucket.org/dismine/valentina/issues/548/bug-detail-tool-case-when-seam-allowance - // Files: Steampunk_trousers.val and marie.vit - // Actually buggy detail see in file src/app/share/collection/bugs/Steampunk_trousers_issue_#548.val - // Code should clean loops in path. - QTest::newRow("Issue 548. Case1") << InputPointsIssue548Case1() - << static_cast<int>(EquidistantType::CloseEquidistant) - << 11.338582677165354 // seam allowance width (0.3 cm) - << OutputPointsIssue548Case1(); - - QTest::newRow("Issue 548. Case2") << InputPointsIssue548Case2() - << static_cast<int>(EquidistantType::CloseEquidistant) - << 37.795275590551185 // seam allowance width (1.0 cm) - << OutputPointsIssue548Case2(); - - QTest::newRow("Issue 548. Case3") << InputPointsIssue548Case3() - << static_cast<int>(EquidistantType::CloseEquidistant) - << 75.59055118110237 // seam allowance width (2.0 cm) - << OutputPointsIssue548Case3(); -} - -//--------------------------------------------------------------------------------------------------------------------- -// cppcheck-suppress unusedFunction -void TST_VAbstractDetail::EquidistantRemoveLoop() const -{ - QFETCH(QVector<QPointF>, points); - QFETCH(int, eqv); - QFETCH(qreal, width); - QFETCH(QVector<QPointF>, ekvOrig); - - const QVector<QPointF> ekv = VAbstractDetail::Equidistant(points, static_cast<EquidistantType>(eqv), width); - - // Begin comparison - Comparison(ekv, ekvOrig); -} - -//--------------------------------------------------------------------------------------------------------------------- -void TST_VAbstractDetail::SumTrapezoids() const -{ - // Case3 checks that the method 'SumTrapezoids' returns negative value for three clockwise allocated points - // Case4 checks that the method 'SumTrapezoids' returns positive value for three counterclock-wise allocated points - // Case5 checks that the method 'SumTrapezoids' returns 0 for one point - Case3(); - Case4(); - Case5(); -} - -//--------------------------------------------------------------------------------------------------------------------- -void TST_VAbstractDetail::PathRemoveLoop_data() const -{ - QTest::addColumn<QVector<QPointF>>("path"); - QTest::addColumn<QVector<QPointF>>("expect"); - - QVector<QPointF> path; - path << QPointF(10, 10); - path << QPointF(20, 10); - path << QPointF(20, 20); - path << QPointF(10, 20); - path << QPointF(10, 10); - QTest::newRow("Correct closed a path (four unique points)") << path << path; - -#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0) - path.remove(path.size() - 1); -#else - path.removeLast(); -#endif - QTest::newRow("Correct unclosed a path (four unique points)") << path << path; - - path.clear(); - path << QPointF(0, 10); - path << QPointF(10, 10); - path << QPointF(20, 10); - path << QPointF(20, 20); - path << QPointF(10, 20); - path << QPointF(0, 20); - path << QPointF(0, 10); - QTest::newRow("Correct closed a path (six unique points)") << path << path; - -#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0) - path.remove(path.size() - 1); -#else - path.removeLast(); -#endif - QTest::newRow("Correct unclosed a path (six unique points)") << path << path; - - path.clear(); - path << QPointF(20, 10); - path << QPointF(20, 20); - path << QPointF(10, 10); - path << QPointF(10, 20); - path << QPointF(20, 10); - - QVector<QPointF> res; - res << QPointF(20, 10); - res << QPointF(20, 20); - res << QPointF(15, 15); - res << QPointF(20, 10); - QTest::newRow("One loop, closed a path (four unique points)") << path << res; - -#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0) - path.remove(path.size() - 1); - res.remove(res.size() - 1); -#else - path.removeLast(); - res.removeLast(); -#endif - QTest::newRow("One loop, unclosed a path (four unique points)") << path << res; - - path.clear(); - path << QPointF(20, 10); - path << QPointF(20, 20); - path << QPointF(10, 10); - path << QPointF(0, 20); - path << QPointF(0, 10); - path << QPointF(10, 20); - path << QPointF(20, 10); - - res.clear(); - res << QPointF(20, 10); - res << QPointF(20, 20); - res << QPointF(15, 15); - res << QPointF(20, 10); - QTest::newRow("Two loops, closed a path (six unique points)") << path << res; - -#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0) - path.remove(path.size() - 1); - res.remove(res.size() - 1); -#else - path.removeLast(); - res.removeLast(); -#endif - QTest::newRow("Two loops, unclosed a path (six unique points)") << path << res; - - path.clear(); - path << QPointF(20, 10); - path << QPointF(20, 20); - path << QPointF(10, 10); - path << QPointF(0, 10); - path << QPointF(0, 20); - path << QPointF(10, 20); - path << QPointF(20, 10); - - res.clear(); - res << QPointF(20, 10); - res << QPointF(20, 20); - res << QPointF(15, 15); - res << QPointF(20, 10); - QTest::newRow("One loop, the first loop, closed a path (six unique points)") << path << res; - -#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0) - path.remove(path.size() - 1); - res.remove(res.size() - 1); -#else - path.removeLast(); - res.removeLast(); -#endif - QTest::newRow("One loop, the first loop, unclosed a path (six unique points)") << path << res; - - path.clear(); - path << QPointF(20, 10); - path << QPointF(20, 20); - path << QPointF(10, 20); - path << QPointF(0, 10); - path << QPointF(0, 20); - path << QPointF(10, 10); - path << QPointF(20, 10); - - res.clear(); - res << QPointF(20, 10); - res << QPointF(20, 20); - res << QPointF(10, 20); - res << QPointF(5, 15); - res << QPointF(10, 10); - res << QPointF(20, 10); - QTest::newRow("One loop, the second loop, closed a path (six unique points)") << path << res; - -#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0) - path.remove(path.size() - 1); - res.remove(res.size() - 1); -#else - path.removeLast(); - res.removeLast(); -#endif - QTest::newRow("One loop, the second loop, unclosed a path (six unique points)") << path << res; - - path.clear(); - path << QPointF(20, 10); - path << QPointF(20, 20); - path << QPointF(10, 20); - path << QPointF(20, 15); - path << QPointF(10, 10); - path << QPointF(20, 10); - QTest::newRow("Correct closed a path, point on line (four unique points)") << path << path; - -#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0) - path.remove(path.size() - 1); -#else - path.removeLast(); -#endif - QTest::newRow("Corect unclosed a path, point on line (four unique points)") << path << path; - - path.clear(); - path << QPointF(20, 10); - path << QPointF(10, 15); - path << QPointF(20, 20); - path << QPointF(10, 20); - path << QPointF(0, 20); - path << QPointF(10, 15); - path << QPointF(0, 10); - path << QPointF(10, 10); - path << QPointF(20, 10); - - QTest::newRow("Correct closed a path, point on line (six unique points)") << path << path; - -#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0) - path.remove(path.size() - 1); -#else - path.removeLast(); -#endif - QTest::newRow("Corect unclosed a path, point on line (six unique points)") << path << path; - - path.clear(); - path << QPointF(100.96979100571033, 1797.6153764073072); - path << QPointF(168.3888427659865, 1807.2395034187866); - path << QPointF(206.78076137364403, 1812.2910842036706); - path << QPointF(239.1630793382262, 1815.951361623424); - path << QPointF(267.5320085054171, 1818.4827543754482); - path << QPointF(293.9502505847841, 1820.144031725603); - path << QPointF(320.48133946750147, 1821.175819320443); - path << QPointF(364.5960626489172, 1822.0507669842166); - path << QPointF(400.66867742260206, 1822.488188976378); - path << QPointF(623.3126833308274, 1822.488188976378); - path << QPointF(653.5489038032683, 2162.6456692913384); - path << QPointF(570.545584385708, 2162.6456692913384); - path << QPointF(600.7818048581489, 1822.488188976378); - path << QPointF(1001.3385826771654, 1822.488188976378); - path << QPointF(1001.3385826771654, 2680.44094488189); - path << QPointF(-22.11646613738226, 2680.44094488189); - path << QPointF(100.96979100571033, 1797.6153764073072); - - res.clear(); - res << QPointF(100.96979100571033, 1797.6153764073072); - res << QPointF(168.3888427659865, 1807.2395034187866); - res << QPointF(206.78076137364403, 1812.2910842036706); - res << QPointF(239.1630793382262, 1815.951361623424); - res << QPointF(267.5320085054171, 1818.4827543754482); - res << QPointF(293.9502505847841, 1820.144031725603); - res << QPointF(320.48133946750147, 1821.175819320443); - res << QPointF(364.5960626489172, 1822.0507669842166); - res << QPointF(400.66867742260206, 1822.488188976378); - res << QPointF(1001.3385826771654, 1822.488188976378); - res << QPointF(1001.3385826771654, 2680.44094488189); - res << QPointF(-22.11646613738226, 2680.44094488189); - res << QPointF(100.96979100571033, 1797.6153764073072); - - // See the file "collection/bugs/Issue_#493.val" - QTest::newRow("Test case issue #493") << path << res; - - path.clear(); - path << QPointF(-685.2149804319953, -3568.7982439212556); - path << QPointF(-700.7415523087261, -3623.900571239949); - path << QPointF(-675.4694480627154, -3639.3631430823175); - path << QPointF(-684.7497934439581, -3631.3546395862268); - path << QPointF(-683.1356602239256, -3633.2868478418427); - path << QPointF(-686.8764821039574, -3627.927414863926); - path << QPointF(-684.7670104817863, -3631.587853202178); - path << QPointF(-682.2386030572435, -3636.8469922361573); - path << QPointF(-676.4708011186385, -3650.307478525872); - path << QPointF(-666.3050989871189, -3676.5286567894937); - path << QPointF(-654.0449409043066, -3710.198553447806); - path << QPointF(-640.1333287371614, -3750.0101920374505); - path << QPointF(-617.0729873733014, -3818.3303697354913); - path << QPointF(-583.8128392515604, -3920.9726624886944); - path << QPointF(-550.5307668482033, -4027.6970214479597); - path << QPointF(-527.4164674104215, -4104.7034088569535); - path << QPointF(-513.4302533332675, -4152.73879565781); - path << QPointF(-501.0373006826446, -4196.767296675345); - path << QPointF(-490.59311078227046, -4235.660899517831); - path << QPointF(-477.25724163384456, -4288.293444470835); - path << QPointF(-405.3839593893572, -4272.013803282615); - path << QPointF(-545.9786893428341, -3568.830152982464); - path << QPointF(-685.2149804319953, -3568.7982439212556); - - res.clear(); - res << QPointF(-685.2149804319953, -3568.7982439212556); - res << QPointF(-700.7415523087261, -3623.900571239949); - res << QPointF(-683.3457668881176, -3634.5440688767967); - res << QPointF(-682.2386030572435, -3636.8469922361573); - res << QPointF(-676.4708011186385, -3650.307478525872); - res << QPointF(-666.3050989871189, -3676.5286567894937); - res << QPointF(-654.0449409043066, -3710.198553447806); - res << QPointF(-640.1333287371614, -3750.0101920374505); - res << QPointF(-617.0729873733014, -3818.3303697354913); - res << QPointF(-583.8128392515604, -3920.9726624886944); - res << QPointF(-550.5307668482033, -4027.6970214479597); - res << QPointF(-527.4164674104215, -4104.7034088569535); - res << QPointF(-513.4302533332675, -4152.73879565781); - res << QPointF(-501.0373006826446, -4196.767296675345); - res << QPointF(-490.59311078227046, -4235.660899517831); - res << QPointF(-477.25724163384456, -4288.293444470835); - res << QPointF(-405.3839593893572, -4272.013803282615); - res << QPointF(-545.9786893428341, -3568.830152982464); - res << QPointF(-685.2149804319953, -3568.7982439212556); - - // See the file "collection/bugs/Issue_#515.val" - // Check a seam allowance path. - // The curve that causes the issue is the first in the list. - QTest::newRow("Test case issue #515. Big loop in seam allowance path.") << path << res; - - path.clear(); - path << QPointF(-449.6699112298347, -4243.2921010175705); - path << QPointF(-576.966638263205, -3606.6183279948636); - path << QPointF(-656.9465284876832, -3606.6183279948636); - path << QPointF(-656.5996104603414, -3606.6000783462687); - path << QPointF(-655.7439133016985, -3607.1236310612317); - path << QPointF(-654.129780081666, -3609.0558393168476); - path << QPointF(-651.3154902471701, -3613.939306009108); - path << QPointF(-647.8207651830382, -3621.2084054506768); - path << QPointF(-641.4701586077349, -3636.0289997859454); - path << QPointF(-630.9244502073004, -3663.23035747934); - path << QPointF(-618.4465305467888, -3697.4982896415795); - path << QPointF(-604.3873016966293, -3737.732371148936); - path << QPointF(-581.1891087215608, -3806.460957656939); - path << QPointF(-547.7936207285052, -3909.520915257629); - path << QPointF(-514.3891332445846, -4016.6378180116963); - path << QPointF(-491.17181635142833, -4093.9874129706236); - path << QPointF(-477.094588519539, -4142.335384784734); - path << QPointF(-464.5941701318652, -4186.745679830414); - path << QPointF(-454.0214632588362, -4226.117872983938); - - res.clear(); - res << QPointF(-449.6699112298347, -4243.2921010175705); - res << QPointF(-576.966638263205, -3606.6183279948636); - res << QPointF(-656.5697831440032, -3606.6183279948636); - res << QPointF(-655.7439133016985, -3607.1236310612317); - res << QPointF(-654.129780081666, -3609.0558393168476); - res << QPointF(-651.3154902471701, -3613.939306009108); - res << QPointF(-647.8207651830382, -3621.2084054506768); - res << QPointF(-641.4701586077349, -3636.0289997859454); - res << QPointF(-630.9244502073004, -3663.23035747934); - res << QPointF(-618.4465305467888, -3697.4982896415795); - res << QPointF(-604.3873016966293, -3737.732371148936); - res << QPointF(-581.1891087215608, -3806.460957656939); - res << QPointF(-547.7936207285052, -3909.520915257629); - res << QPointF(-514.3891332445846, -4016.6378180116963); - res << QPointF(-491.17181635142833, -4093.9874129706236); - res << QPointF(-477.094588519539, -4142.335384784734); - res << QPointF(-464.5941701318652, -4186.745679830414); - res << QPointF(-454.0214632588362, -4226.117872983938); - - // See the file "collection/bugs/Issue_#515.val" - // Check a seam allowance path. - // The curve that causes the issue is the last in the list. - QTest::newRow("Test case issue #515. Small loop in seam allowance path.") << path << res; - - path.clear(); - path << QPointF(1229.6503937007876, 937.6667716535435); - path << QPointF(203.08931117793543, 937.6667716535435); - path << QPointF(459.7677349767701, -2166.704563141019); - path << QPointF(1229.6503937007876, -1990.077167189857); - path << QPointF(1229.6503937007876, -555.2466141732282); - path << QPointF(920.1053824527112, -555.2466141732282); - path << QPointF(887.034516310979, -63.90803149606281); - path << QPointF(816.3607592795726, -63.908031496062826); - path << QPointF(780.7580397937137, -592.8627210002539); - path << QPointF(816.0241340748559, -1202.917917917055); - path << QPointF(887.3711415156957, -1202.917917917055); - path << QPointF(920.4420076574283, -630.8371653543306); - path << QPointF(1229.6503937007876, -630.8371653543306); - path << QPointF(1229.6503937007876, 937.6667716535435); - - res.clear(); - res << QPointF(1229.6503937007876, 937.6667716535435); - res << QPointF(203.08931117793543, 937.6667716535435); - res << QPointF(459.7677349767702, -2166.704563141019); - res << QPointF(1229.6503937007876, -1990.077167189857); - res << QPointF(1229.6503937007876, 937.6667716535435); - - // See the file "collection/bugs/Issue_#603.val" - // Point H1 is first in the list - QTest::newRow("Test issue 603.") << path << res; -} - -//--------------------------------------------------------------------------------------------------------------------- -void TST_VAbstractDetail::PathRemoveLoop() const -{ - QFETCH(QVector<QPointF>, path); - QFETCH(QVector<QPointF>, expect); - - QVector<QPointF> res = VAbstractDetail::CheckLoops(path); - Comparison(res, expect); -} - -//--------------------------------------------------------------------------------------------------------------------- -void TST_VAbstractDetail::PathLoopsCase_data() const -{ - QTest::addColumn<QVector<QPointF>>("path"); - QTest::addColumn<QVector<QPointF>>("expect"); - - QVector<QPointF> path; - path << QPointF(61.86670866141733, 446.92270866141735); - path << QPointF(650.6504606788366, 473.2192016666484); - path << QPointF(649.4426552757304, 480.5376973511262); - path << QPointF(646.5769170924987, 501.9977838630714); - path << QPointF(644.6382908004568, 523.6358081043691); - path << QPointF(643.4592698551749, 551.9888717674471); - path << QPointF(642.9134698671897, 584.1776423714557); - path << QPointF(643.1914832622404, 613.2382010061506); - path << QPointF(644.2199668178571, 639.3780275889782); - path << QPointF(645.9255773115714, 662.8046020373845); - path << QPointF(648.2349715209137, 683.7254042688159); - path << QPointF(651.0748062234152, 702.3479142007185); - path << QPointF(654.3717381966065, 718.8796117505387); - path << QPointF(658.0524242180187, 733.5279768357226); - path << QPointF(662.0435210651824, 746.5004893737165); - path << QPointF(666.2716855156286, 758.0046292819667); - path << QPointF(670.6635743468883, 768.2478764779191); - path << QPointF(677.400406718071, 781.7952098705392); - path << QPointF(691.6740007010135, 806.2608114022295); - path << QPointF(694.5877745571677, 810.2150054671212); - path << QPointF(699.9560352035193, 816.1706553153153); - path << QPointF(708.9007628091615, 824.0594196166176); - path << QPointF(719.3794725391945, 831.7499791040799); - path << QPointF(730.9568541500198, 839.0942359684872); - path << QPointF(743.1975973980386, 845.9440924006244); - path << QPointF(755.6663920396528, 852.1514505912763); - path << QPointF(767.9279278312633, 857.568212731228); - path << QPointF(779.5468945292718, 862.046281011264); - path << QPointF(790.0879818900794, 865.4375576221694); - path << QPointF(799.115879670088, 867.5939447547289); - path << QPointF(804.5608128209333, 868.2650594004886); - path << QPointF(807.5317661719646, 868.2782441618697); - path << QPointF(809.8795601157717, 867.8994015359809); - path << QPointF(811.5497808719051, 867.1100192966705); - path << QPointF(812.4880146599148, 865.8915852177861); - path << QPointF(812.6398476993509, 864.2255870731761); - path << QPointF(811.9508662097637, 862.0935126366886); - path << QPointF(810.3666564107034, 859.4768496821717); - path << QPointF(806.3216663321919, 854.66911491981); - path << QPointF(802.0871811023624, 850.6707401574804); - path << QPointF(799.4598981526765, 850.6707401574804); - path << QPointF(802.0871811023624, 1653.9337322834645); - path << QPointF(61.86670866141733, 1653.9337322834645); - - QVector<QPointF> res; - res << QPointF(61.86670866141733, 446.92270866141735); - res << QPointF(650.6504606788366, 473.2192016666484); - res << QPointF(649.4426552757304, 480.5376973511262); - res << QPointF(646.5769170924987, 501.9977838630714); - res << QPointF(644.6382908004568, 523.6358081043691); - res << QPointF(643.4592698551749, 551.9888717674471); - res << QPointF(642.9134698671897, 584.1776423714557); - res << QPointF(643.1914832622404, 613.2382010061506); - res << QPointF(644.2199668178571, 639.3780275889782); - res << QPointF(645.9255773115714, 662.8046020373845); - res << QPointF(648.2349715209137, 683.7254042688159); - res << QPointF(651.0748062234152, 702.3479142007185); - res << QPointF(654.3717381966065, 718.8796117505387); - res << QPointF(658.0524242180187, 733.5279768357226); - res << QPointF(662.0435210651824, 746.5004893737165); - res << QPointF(666.2716855156286, 758.0046292819667); - res << QPointF(670.6635743468883, 768.2478764779191); - res << QPointF(677.400406718071, 781.7952098705392); - res << QPointF(691.6740007010135, 806.2608114022295); - res << QPointF(694.5877745571677, 810.2150054671212); - res << QPointF(699.9560352035193, 816.1706553153153); - res << QPointF(708.9007628091615, 824.0594196166176); - res << QPointF(719.3794725391945, 831.7499791040799); - res << QPointF(730.9568541500198, 839.0942359684872); - res << QPointF(743.1975973980386, 845.9440924006244); - res << QPointF(755.6663920396528, 852.1514505912763); - res << QPointF(767.9279278312633, 857.568212731228); - res << QPointF(779.5468945292718, 862.046281011264); - res << QPointF(790.0879818900794, 865.4375576221694); - res << QPointF(799.115879670088, 867.5939447547289); - res << QPointF(799.5154110117976, 867.6431889469776); - res << QPointF(802.0871811023624, 1653.9337322834645); - res << QPointF(61.86670866141733, 1653.9337322834645); - - // See file "collection/bugs/Issue_#609_case1.val" - // Clear a main path. Bound intersection. External loop. Outside a loop. Start point Ф1. - QTest::newRow("Issue 609. Case1a") << path << res; - - path.clear(); - path << QPointF(-365.68188649000314, -2143.126579528016); - path << QPointF(-195.75487873249062, -2116.7935769656237); - path << QPointF(-195.75487873249062, -1836.0319480765759); - path << QPointF(-233.39027086052477, -1838.4849618976993); - path << QPointF(-231.15080237392075, -1855.5915146519483); - path << QPointF(-225.84473077299972, -1889.4811404382626); - path << QPointF(-219.39861487985402, -1922.986407729537); - path << QPointF(-211.6695159016421, -1955.9990283342697); - path << QPointF(-204.87723909172885, -1980.439660924953); - path << QPointF(-199.87970909142098, -1996.6270828437923); - path << QPointF(-194.48099536000245, -2012.6451713592935); - path << QPointF(-188.65032933731845, -2028.5246588116781); - path << QPointF(-182.36812965707693, -2044.2602109802488); - path << QPointF(-175.61499879935675, -2059.8462252736344); - path << QPointF(-168.3717693169516, -2075.2768492268588); - path << QPointF(-160.6424572210866, -2090.5008865466684); - path << QPointF(-150.22847685877994, -2109.7385074212525); - path << QPointF(194.23861004296444, -2056.3576305273214); - path << QPointF(302.4787663409577, -1301.003761061316); - path << QPointF(279.86810151275455, -1288.330749878147); - path << QPointF(-641.7062267185897, -2051.118466118487); - path << QPointF(-365.68188649000314, -2143.126579528016); - - res.clear(); - res << QPointF(-365.68188649000314, -2143.126579528016); - res << QPointF(-195.75487873249062, -2116.7935769656237); - res << QPointF(-195.75487873249062, -2008.8655346469059); - res << QPointF(-194.48099536000245, -2012.6451713592935); - res << QPointF(-188.65032933731845, -2028.5246588116781); - res << QPointF(-182.36812965707693, -2044.2602109802488); - res << QPointF(-175.61499879935675, -2059.8462252736344); - res << QPointF(-168.3717693169516, -2075.2768492268588); - res << QPointF(-160.6424572210866, -2090.5008865466684); - res << QPointF(-150.22847685877994, -2109.7385074212525); - res << QPointF(194.23861004296444, -2056.3576305273214); - res << QPointF(302.4787663409577, -1301.003761061316); - res << QPointF(279.86810151275455, -1288.330749878147); - res << QPointF(-641.7062267185897, -2051.118466118487); - res << QPointF(-365.68188649000314, -2143.126579528016); - - // See file "collection/bugs/Issue_#609_case2.val" - // Clear an equdistant. Bound intersection. Internal loop. Outside a loop. Start point А2. - QTest::newRow("Issue 609. Case2b") << path << res; - - path.clear(); - path << QPointF(0, 10); - path << QPointF(5, 10); - path << QPointF(2.5, 15); - path << QPointF(7.5, 15); - path << QPointF(5, 10); - path << QPointF(10, 10); - path << QPointF(10, 20); - path << QPointF(0, 20); - path << QPointF(0, 10); - - QTest::newRow("Internal loop. Valid case.") << path << path; - - path.clear(); - path << QPointF(0, 10); - path << QPointF(5, 10); - path << QPointF(7.5, 15); - path << QPointF(2.5, 15); - path << QPointF(5, 10); - path << QPointF(10, 10); - path << QPointF(10, 20); - path << QPointF(0, 20); - path << QPointF(0, 10); - - res.clear(); - res << QPointF(0, 10); - res << QPointF(10, 10); - res << QPointF(10, 20); - res << QPointF(0, 20); - res << QPointF(0, 10); - - QTest::newRow("Internal loop. Invalid case.") << path << res; - - path.clear(); - path << QPointF(0, 10); - path << QPointF(5, 10); - path << QPointF(0, 0); - path << QPointF(10, 0); - path << QPointF(5, 10); - path << QPointF(10, 10); - path << QPointF(10, 20); - path << QPointF(0, 20); - path << QPointF(0, 10); - - QTest::newRow("External loop. Valid case.") << path << path; - - path.clear(); - path << QPointF(0, 10); - path << QPointF(5, 10); - path << QPointF(10, 0); - path << QPointF(0, 0); - path << QPointF(5, 10); - path << QPointF(10, 10); - path << QPointF(10, 20); - path << QPointF(0, 20); - path << QPointF(0, 10); - - res.clear(); - res << QPointF(0, 10); - res << QPointF(10, 10); - res << QPointF(10, 20); - res << QPointF(0, 20); - res << QPointF(0, 10); - - QTest::newRow("External loop. Invalid case.") << path << res; -} - -//--------------------------------------------------------------------------------------------------------------------- -void TST_VAbstractDetail::PathLoopsCase() const -{ - QFETCH(QVector<QPointF>, path); - QFETCH(QVector<QPointF>, expect); - - const QVector<QPointF> res = VAbstractDetail::CheckLoops(path); - Comparison(res, expect); -} - -//--------------------------------------------------------------------------------------------------------------------- -void TST_VAbstractDetail::BrokenDetailEquidistant_data() const -{ - QTest::addColumn<QVector<QPointF>>("points"); - QTest::addColumn<int>("eqv"); - QTest::addColumn<qreal>("width"); - QTest::addColumn<QVector<QPointF>>("ekvOrig"); - - // For more details see the file "collection/bugs/GAVAUDAN Laure - corsage - figure 4.val". - // We will test only one detail. The second require too accurate data that we cannot get from debuger. - // The test check an open equdistant of correct detail. - QVector<QPointF> points;// Input points. - points.append(QPointF(787.5835464566929, 1701.3138897637796)); - points.append(QPointF(938.7646488188976, 1701.3138897637796)); - points.append(QPointF(928.6149958683911, 1732.4440719866434)); - points.append(QPointF(910.0209091217698, 1792.3369853889722)); - points.append(QPointF(893.3643262819251, 1849.7845131987456)); - points.append(QPointF(878.5244039283091, 1905.2261617043234)); - points.append(QPointF(865.3802986403739, 1959.101437194065)); - points.append(QPointF(863.9366982685195, 1965.6834024491068)); - points.append(QPointF(852.8936778444679, 1919.6965437838999)); - points.append(QPointF(837.0628180560684, 1860.2846653184251)); - points.append(QPointF(819.0677656132684, 1798.6758641921479)); - points.append(QPointF(798.7585839758027, 1734.54810216256)); - points.append(QPointF(787.5835464566929, 1701.3138897637796)); - - EquidistantType eqv = EquidistantType::OpenEquidistant; // Open path - qreal width = 37.795275590551185; // seam allowance width - - QVector<QPointF> ekvOrig; - ekvOrig.append(QPointF(774.8748468280837, 1663.5186141732283)); - ekvOrig.append(QPointF(990.8407795072413, 1663.5186141732283)); - ekvOrig.append(QPointF(964.6314912875667, 1743.9055911653147)); - ekvOrig.append(QPointF(946.2221157804494, 1803.203536155223)); - ekvOrig.append(QPointF(929.7733291125676, 1859.9343877726233)); - ekvOrig.append(QPointF(915.1430746962241, 1914.5927211230298)); - ekvOrig.append(QPointF(902.2033544443959, 1967.630259856634)); - ekvOrig.append(QPointF(894.4064781634931, 2003.1794116713015)); - ekvOrig.append(QPointF(834.213891302752, 2003.7742535883901)); - ekvOrig.append(QPointF(816.2523103379473, 1928.9761772004185)); - ekvOrig.append(QPointF(800.6574884611877, 1870.4501290629887)); - ekvOrig.append(QPointF(782.9077417718742, 1809.6811695225983)); - ekvOrig.append(QPointF(786.7126382487066, 1698.723835966227)); - - QTest::newRow("GAVAUDAN Laure.") << points << static_cast<int>(eqv) << width << ekvOrig; - - points.clear(); - points.append(QPointF(97.33089106412862, -223.03306117556497)); - points.append(QPointF(990.7494050554426, 2.819093995045)); - points.append(QPointF(908.3966357321774, 379.5839357215547)); - points.append(QPointF(-135.41154226686143, 697.6417881399819)); - - eqv = EquidistantType::OpenEquidistant; - width = 11.338582677165354; - - ekvOrig.clear(); - ekvOrig.append(QPointF(100.10981413873267, -234.02583351343978)); - ekvOrig.append(QPointF(1004.1704360325447, -5.483401649771952)); - ekvOrig.append(QPointF(918.0553412376563, 388.4941212347381)); - ekvOrig.append(QPointF(-138.65807550610091, 710.4843173601864)); - - // See the file "collection/bugs/Issue_#604.val" (since 0.5.0) - QTest::newRow("Issue #604.") << points << static_cast<int>(eqv) << width << ekvOrig; -} - -//--------------------------------------------------------------------------------------------------------------------- -void TST_VAbstractDetail::BrokenDetailEquidistant() const -{ - QFETCH(QVector<QPointF>, points); - QFETCH(int, eqv); - QFETCH(qreal, width); - QFETCH(QVector<QPointF>, ekvOrig); - - const QVector<QPointF> ekv = VAbstractDetail::Equidistant(points, static_cast<EquidistantType>(eqv), - width);// Take result - - // Begin comparison - Comparison(ekv, ekvOrig); -} - -//--------------------------------------------------------------------------------------------------------------------- -void TST_VAbstractDetail::CorrectEquidistantPoints_data() const -{ - // See file zigzag.val - QTest::addColumn<QVector<QPointF>>("points"); - QTest::addColumn<QVector<QPointF>>("expect"); - QTest::addColumn<bool>("removeFirstAndLast"); - - QVector<QPointF> points; - points.append(QPointF(-741.7894588053705, 1065.7336503858917)); - points.append(QPointF(-759.696551643576, -115.81420543069257)); - points.append(QPointF(-278.17249953019325, -217.1037453126913)); - points.append(QPointF(-244.64654130659474, 1077.9548221866635)); - points.append(QPointF(-741.7894588053705, 1065.7336503858917)); - - QVector<QPointF> expect; - expect.append(QPointF(-741.7894588053705, 1065.7336503858917)); - expect.append(QPointF(-759.696551643576, -115.81420543069257)); - expect.append(QPointF(-278.17249953019325, -217.1037453126913)); - expect.append(QPointF(-244.64654130659474, 1077.9548221866635)); - expect.append(QPointF(-741.7894588053705, 1065.7336503858917)); - - QTest::newRow("Closed seam allowance. Last point equal first.") << points << expect << false; - - points.clear(); - points.append(QPointF(-704.5489521643801, 1028.8424328418016)); - points.append(QPointF(-721.4335720065426, -85.24049234531904)); - points.append(QPointF(-707.7852899705758, 755.7064514429209)); - points.append(QPointF(-721.4335720065426, -85.24049234531904)); - points.append(QPointF(-314.78124296268265, -170.7806167067443)); - points.append(QPointF(-283.4579031023758, 1039.1940357173805)); - - expect.clear(); - expect.append(QPointF(-704.5489521643801, 1028.8424328418016)); - expect.append(QPointF(-721.4335720065426, -85.24049234531904)); - expect.append(QPointF(-314.78124296268265, -170.7806167067443)); - expect.append(QPointF(-283.4579031023758, 1039.1940357173805)); - - QTest::newRow("Clearing bad main path.") << points << expect << true; -} - -//--------------------------------------------------------------------------------------------------------------------- -void TST_VAbstractDetail::CorrectEquidistantPoints() const -{ - QFETCH(QVector<QPointF>, points); - QFETCH(QVector<QPointF>, expect); - QFETCH(bool, removeFirstAndLast); - - const QVector<QPointF> res = VAbstractDetail::CorrectEquidistantPoints(points, removeFirstAndLast); - - // Begin comparison - Comparison(res, expect); -} - -//--------------------------------------------------------------------------------------------------------------------- -void TST_VAbstractDetail::TestCorrectEquidistantPoints_data() -{ - QTest::addColumn<QVector<QPointF>>("before"); - QTest::addColumn<QVector<QPointF>>("expect"); - - QVector<QPointF> before; - before << QPointF(30.0, 39.999874015748034); - before << QPointF(785.9055118110236, 39.999874015748034); - before << QPointF(785.9055118110236, 3819.527433070866); - before << QPointF(483.54330708661416, 3819.527433070866); - before << QPointF(483.54330708661416, 1929.763653543307); - before << QPointF(407.9527559055629, 984.8817637795973); - before << QPointF(407.9527559055118, 1929.763653543307); - before << QPointF(407.9527559055118, 3819.527433070866); - before << QPointF(30.0, 3819.527433070866); - - QVector<QPointF> expect; - expect << QPointF(30.0, 39.999874015748034); - expect << QPointF(785.9055118110236, 39.999874015748034); - expect << QPointF(785.9055118110236, 3819.527433070866); - expect << QPointF(483.54330708661416, 3819.527433070866); - expect << QPointF(483.54330708661416, 1929.763653543307); - expect << QPointF(407.9527559055629, 984.8817637795973); - expect << QPointF(407.9527559055118, 3819.527433070866); - expect << QPointF(30.0, 3819.527433070866); - - QTest::newRow("Test case issue #548") << before << expect; -} - -//--------------------------------------------------------------------------------------------------------------------- -void TST_VAbstractDetail::TestCorrectEquidistantPoints() const -{ - QFETCH(QVector<QPointF>, before); - QFETCH(QVector<QPointF>, expect); - - QVector<QPointF> after = VAbstractDetail::CorrectEquidistantPoints(before); - Comparison(after, expect); -} - -#ifndef Q_OS_WIN -//--------------------------------------------------------------------------------------------------------------------- -void TST_VAbstractDetail::PossibleInfiniteClearLoops_data() const -{ - QTest::addColumn<QVector<QPointF>>("path"); - QTest::addColumn<QVector<QPointF>>("expect"); - - QVector<QPointF> path; - path << QPointF(-670.6449010946802, 4046.36220472441); - path << QPointF(-1025.9051277126944, 4046.36220472441); - path << QPointF(-1026.4460203880594, 4010.5247429150854); - path << QPointF(-1027.2972172274538, 3924.202328582098); - path << QPointF(-1028.1383921346433, 3768.5948526129496); - path << QPointF(-1028.5065585022217, 3521.575730066707); - path << QPointF(-1028.2712136539103, 3252.2436039362233); - path << QPointF(-1027.2910122410117, 2850.1024469719814); - path << QPointF(-1025.9446023682538, 2439.350819630564); - path << QPointF(-1025.8983315247287, 2338.629525677473); - path << QPointF(-1025.3536572186458, 2309.970015878699); - path << QPointF(-1024.2100836932389, 2281.714612342931); - path << QPointF(-1022.5102766116828, 2253.846781520112); - path << QPointF(-1020.2969016371525, 2226.349989860186); - path << QPointF(-1017.6126244328227, 2199.207703813094); - path << QPointF(-1014.5001106618688, 2172.403389828782); - path << QPointF(-1011.0020259874652, 2145.9205143571917); - path << QPointF(-1005.1601480132764, 2106.7277181407126); - path << QPointF(-996.3625412018714, 2055.4921956731814); - path << QPointF(-986.7906327138169, 2005.2448233555149); - path << QPointF(-976.785747854512, 1955.8533327872588); - path << QPointF(-961.6606968634906, 1883.0158867454916); - path << QPointF(-947.5864881030896, 1811.4914675744105); - path << QPointF(-939.2629508127773, 1764.2008199992524); - path << QPointF(-933.8852659113251, 1728.8707137815559); - path << QPointF(-930.742733377741, 1705.3464944792456); - path << QPointF(-928.0252775410311, 1681.829576238578); - path << QPointF(-925.7755640643697, 1658.3034255094963); - path << QPointF(-924.036258610932, 1634.7515087419433); - path << QPointF(-922.850026843893, 1611.1572923858625); - path << QPointF(-922.2595344264276, 1587.504242891197); - path << QPointF(-922.3074470217107, 1563.7758267078902); - path << QPointF(-922.613405031688, 1551.8740157480315); - path << QPointF(-960.4086806222392, 841.3228346456693); - path << QPointF(-954.9336313684444, 841.5464781141166); - path << QPointF(-944.0363771538431, 841.3102753632543); - path << QPointF(-933.2160856340209, 840.291423017261); - path << QPointF(-922.4878118569704, 838.5316299985567); - path << QPointF(-911.8666108706839, 836.0726052295611); - path << QPointF(-901.3675377231535, 832.9560576326933); - path << QPointF(-891.005647462372, 829.2236961303737); - path << QPointF(-880.7959951363317, 824.9172296450213); - path << QPointF(-870.7536357930251, 820.0783670990559); - path << QPointF(-860.893624480444, 814.7488174148973); - path << QPointF(-851.2310162465817, 808.9702895149649); - path << QPointF(-841.7808661394299, 802.7844923216785); - path << QPointF(-832.5582292069812, 796.2331347574575); - path << QPointF(-823.578160497228, 789.3579257447218); - path << QPointF(-810.5607800373014, 778.5565764202543); - path << QPointF(-794.2367125298769, 763.3635567727296); - path << QPointF(-779.1539087770976, 747.6258919346988); - path << QPointF(-765.4328091629026, 731.6772532855191); - path << QPointF(-753.193854071231, 715.8513122045474); - path << QPointF(-742.557483886022, 700.4817400711408); - path << QPointF(-733.644138991215, 685.9022082646563); - path << QPointF(-726.5742597707488, 672.446388164451); - path << QPointF(-721.4682866085625, 660.447951149882); - path << QPointF(-718.6229063234249, 651.1532303788147); - path << QPointF(-716.6036430255488, 642.9038041285014); - path << QPointF(-714.137568179324, 630.1235656609365); - path << QPointF(-711.8605525364693, 612.2344502588126); - path << QPointF(-710.4560555432737, 593.4222205889721); - path << QPointF(-709.4234847119759, 563.5940176156308); - path << QPointF(-708.952111561728, 520.4666582691573); - path << QPointF(-708.4401766852314, 497.3858267716535); - path << QPointF(-400.92922424489655, 469.03937007874015); - path << QPointF(-708.4401766852314, 440.6929133858268); - path << QPointF(-708.7078446526739, 341.66122584661264); - path << QPointF(-709.3427685457568, 299.60322373665383); - path << QPointF(-710.6909230403871, 257.048095841136); - path << QPointF(-713.0251717477311, 214.57984397612822); - path << QPointF(-715.632864794307, 183.1716335401434); - path << QPointF(-717.7953694429818, 162.55016633308693); - path << QPointF(-720.3578834261159, 142.27891915519677); - path << QPointF(-723.3545146951046, 122.43089223348173); - path << QPointF(-725.0465030138121, 112.71059563115871); - path << QPointF(-219.59055118110237, -35.52755905511811); - path << QPointF(-218.99352387527398, -33.21125072212394); - path << QPointF(-217.35724543521775, -28.699086141666157); - path << QPointF(-215.20035586903225, -24.33136255454731); - path << QPointF(-212.53403014110648, -20.10796717265881); - path << QPointF(-209.36944321582945, -16.02878720789205); - path << QPointF(-205.71777005759026, -12.093709872138447); - path << QPointF(-201.59018563077785, -8.302622377289406); - path << QPointF(-196.99786489978123, -4.65541193523633); - path << QPointF(-189.3170483291933, 0.5638303631539586); - path << QPointF(-177.47808861476295, 6.996342387787443); - path << QPointF(-163.981333042598, 12.855376387191757); - path << QPointF(-148.91618132781048, 18.141834666235646); - path << QPointF(-132.37203318551252, 22.856619529787864); - path << QPointF(-114.43828833081622, 27.00063328271716); - path << QPointF(-95.20434647883366, 30.574778229892296); - path << QPointF(-74.75960734467688, 33.57995667618201); - path << QPointF(-53.193470643458, 36.01707092645505); - path << QPointF(-30.595336090289106, 37.887023285580185); - path << QPointF(-7.0546034002822875, 39.19071605842615); - path << QPointF(17.339327711450373, 39.929051549861704); - path << QPointF(29.858267716535437, 40.06299212598426); - path << QPointF(-45.73228346456693, 1589.6692913385828); - path << QPointF(-45.73228346456693, 4046.36220472441); - path << QPointF(-297.70078740157487, 4046.36220472441); - path << QPointF(-297.70078740157487, 2118.8031496062995); - path << QPointF(-222.1102362204725, 1589.6692913385828); - path << QPointF(-297.70078740157487, 1060.535433070866); - path << QPointF(-373.2913385826772, 1589.6692913385828); - path << QPointF(-297.70078740157487, 2118.8031496062995); - path << QPointF(-297.70078740157487, 4046.36220472441); - path << QPointF(-670.6449010946802, 4046.36220472441); - path << QPointF(-670.6449010946802, 2024.3149606299214); - path << QPointF(-622.7555214134819, 1570.7716535433071); - path << QPointF(-670.6449010946802, 1117.2283464566929); - path << QPointF(-718.5342807758785, 1570.7716535433071); - path << QPointF(-670.6449010946802, 2024.3149606299214); - - QVector<QPointF> expect; - expect << QPointF(-670.6449010946802, 4046.36220472441); - expect << QPointF(-670.6449010946802, 4046.36220472441); - expect << QPointF(-670.6449010946802, 2024.3149606299214); - expect << QPointF(-670.6449010946802, 2024.3149606299214); - expect << QPointF(-670.6449010946802, 2024.3149606299214); - - // See the file "collection/bugs/possible_inf_loop.val" - QTest::newRow("Possible infinite loop") << path << expect; -} - -//--------------------------------------------------------------------------------------------------------------------- -void TST_VAbstractDetail::PossibleInfiniteClearLoops() const -{ - QFETCH(QVector<QPointF>, path); - QFETCH(QVector<QPointF>, expect); - - QVector<QPointF> res = VAbstractDetail::CheckLoops(path); - Comparison(res, expect); -} -#endif //#ifndef Q_OS_WIN - -//--------------------------------------------------------------------------------------------------------------------- -void TST_VAbstractDetail::Case3() const -{ - const QVector<QPointF> points = InputPointsCase3(); // Input points. - - const qreal result = VAbstractDetail::SumTrapezoids(points); - QVERIFY(result < 0); -} - -//--------------------------------------------------------------------------------------------------------------------- -void TST_VAbstractDetail::Case4() const -{ - const QVector<QPointF> points = InputPointsCase4(); // Input points. - - const qreal result = VAbstractDetail::SumTrapezoids(points); - QVERIFY(result > 0); -} - -//--------------------------------------------------------------------------------------------------------------------- -void TST_VAbstractDetail::Case5() const -{ - const QVector<QPointF> points = InputPointsCase5(); // Input points. - - const qreal result = VAbstractDetail::SumTrapezoids(points); - QVERIFY(qFuzzyIsNull(result)); -} - -//--------------------------------------------------------------------------------------------------------------------- -QVector<QPointF> TST_VAbstractDetail::InputPointsIssue298Case1() const -{ - QVector<QPointF> points; - - points += QPointF(35, 39.9999); - points += QPointF(412.953, 39.9999); - points += QPointF(417.135, 417.929); - points += QPointF(417.135, 417.929); - points += QPointF(408.797, 405.589); - points += QPointF(390.909, 377.669); - points += QPointF(362.315, 330.86); - points += QPointF(323.075, 264.247); - points += QPointF(286.15, 201.448); - points += QPointF(262.477, 162.745); - points += QPointF(249.22, 142.455); - points += QPointF(241.092, 131.261); - points += QPointF(236.545, 125.75); - points += QPointF(232.808, 122.058); - points += QPointF(230.6, 120.629); - points += QPointF(229.393, 120.277); - points += QPointF(228.421, 120.456); - points += QPointF(227.69, 121.185); - points += QPointF(227.033, 123.272); - points += QPointF(227.112, 128.232); - points += QPointF(228.29, 135.699); - points += QPointF(230.625, 145.81); - points += QPointF(234.173, 158.703); - points += QPointF(241.73, 183.168); - points += QPointF(248.796, 204.144); - points += QPointF(248.796, 204.144); - points += QPointF(251.528, 212.406); - points += QPointF(255.482, 227.075); - points += QPointF(257.717, 239.591); - points += QPointF(258.279, 247.554); - points += QPointF(258.203, 252.278); - points += QPointF(257.756, 256.51); - points += QPointF(256.949, 260.264); - points += QPointF(255.795, 263.547); - points += QPointF(254.308, 266.372); - points += QPointF(252.501, 268.749); - points += QPointF(250.385, 270.688); - points += QPointF(247.974, 272.201); - points += QPointF(245.281, 273.296); - points += QPointF(242.319, 273.986); - points += QPointF(239.1, 274.28); - points += QPointF(233.846, 274.05); - points += QPointF(226.022, 272.393); - points += QPointF(217.402, 269.345); - points += QPointF(208.09, 264.991); - points += QPointF(198.186, 259.414); - points += QPointF(187.795, 252.7); - points += QPointF(177.019, 244.933); - points += QPointF(165.96, 236.197); - points += QPointF(154.721, 226.576); - points += QPointF(143.405, 216.157); - points += QPointF(132.113, 205.022); - points += QPointF(120.95, 193.257); - points += QPointF(110.017, 180.946); - points += QPointF(99.4167, 168.174); - points += QPointF(89.2522, 155.024); - points += QPointF(79.626, 141.582); - points += QPointF(70.6405, 127.933); - points += QPointF(62.3985, 114.16); - points += QPointF(55.0025, 100.348); - points += QPointF(48.5551, 86.5823); - points += QPointF(43.159, 72.9466); - points += QPointF(38.9167, 59.5258); - points += QPointF(35.9309, 46.4042); - points += QPointF(35, 39.9999); - - return points; -} - -//--------------------------------------------------------------------------------------------------------------------- -QVector<QPointF> TST_VAbstractDetail::OutputPointsIssue298Case1() const -{ - QVector<QPointF> points; - points += QPointF(-52.3724798442221, -35.5907); - points += QPointF(487.7117748779425, -35.5907); - points += QPointF(493.3432017362585, 473.32371517914754); - points += QPointF(385.98559977345093, 506.8445742667132); - points += QPointF(345.64704646524604, 447.1446764706891); - points += QPointF(326.82411403464874, 417.76541252489994); - points += QPointF(297.4844355409708, 369.73572061014266); - points += QPointF(280.35686644039447, 340.63425704493835); - points += QPointF(268.2336759982877, 345.56366422433183); - points += QPointF(254.38869069377708, 348.78886336684104); - points += QPointF(240.8928242225697, 350.0214774527481); - points += QPointF(224.29748398011193, 349.2949970081793); - points += QPointF(205.50330859478322, 345.31468660256957); - points += QPointF(188.72568121178054, 339.38217984347546); - points += QPointF(173.487571907339, 332.2573164509149); - points += QPointF(159.09346043909582, 324.15190856941325); - points += QPointF(145.1562378134811, 315.1465661857729); - points += QPointF(131.46917217609203, 305.28136213922494); - points += QPointF(117.9345600633141, 294.589765121662); - points += QPointF(104.5254725457231, 283.11108988305153); - points += QPointF(91.25156649455745, 270.88938370179534); - points += QPointF(78.14294517511125, 257.9630200468154); - points += QPointF(65.25722328495372, 244.3823949426573); - points += QPointF(52.65759889494496, 230.19470850111355); - points += QPointF(40.412239584772514, 215.4406233233806); - points += QPointF(28.600027181043494, 200.15894757848054); - points += QPointF(17.304913602921047, 184.38648111018338); - points += QPointF(6.6105681133211736, 168.14173996194046); - points += QPointF(-3.3897319816688407, 151.43048866270516); - points += QPointF(-12.592267484961765, 134.24479093805914); - points += QPointF(-20.880547263016442, 116.54866956498358); - points += QPointF(-28.111192294561146, 98.27715746242171); - points += QPointF(-34.098213657706594, 79.33681465062016); - points += QPointF(-38.441724866417594, 60.24852451858777); - points += QPointF(-52.3724798442221, -35.5907); - - return points; -} - -//--------------------------------------------------------------------------------------------------------------------- -QVector<QPointF> TST_VAbstractDetail::InputPointsIssue298Case2() const -{ - QVector<QPointF> points; - - points += QPointF(35, 39.9999); - points += QPointF(35, 39.9999); - points += QPointF(35.9309, 46.4042); - points += QPointF(38.9167, 59.5258); - points += QPointF(43.159, 72.9466); - points += QPointF(48.5551, 86.5823); - points += QPointF(55.0025, 100.348); - points += QPointF(62.3985, 114.16); - points += QPointF(70.6405, 127.933); - points += QPointF(79.626, 141.582); - points += QPointF(89.2522, 155.024); - points += QPointF(99.4167, 168.174); - points += QPointF(110.017, 180.946); - points += QPointF(120.95, 193.257); - points += QPointF(132.113, 205.022); - points += QPointF(143.405, 216.157); - points += QPointF(154.721, 226.576); - points += QPointF(165.96, 236.197); - points += QPointF(177.019, 244.933); - points += QPointF(187.795, 252.7); - points += QPointF(198.186, 259.414); - points += QPointF(208.09, 264.991); - points += QPointF(217.402, 269.345); - points += QPointF(226.022, 272.393); - points += QPointF(233.846, 274.05); - points += QPointF(239.1, 274.28); - points += QPointF(242.319, 273.986); - points += QPointF(245.281, 273.296); - points += QPointF(247.974, 272.201); - points += QPointF(250.385, 270.688); - points += QPointF(252.501, 268.749); - points += QPointF(254.308, 266.372); - points += QPointF(255.795, 263.547); - points += QPointF(256.949, 260.264); - points += QPointF(257.756, 256.51); - points += QPointF(258.203, 252.278); - points += QPointF(258.279, 247.554); - points += QPointF(257.717, 239.591); - points += QPointF(255.482, 227.075); - points += QPointF(251.528, 212.406); - points += QPointF(248.796, 204.144); - points += QPointF(248.796, 204.144); - points += QPointF(241.73, 183.168); - points += QPointF(234.173, 158.703); - points += QPointF(230.625, 145.81); - points += QPointF(228.29, 135.699); - points += QPointF(227.112, 128.232); - points += QPointF(227.033, 123.272); - points += QPointF(227.69, 121.185); - points += QPointF(228.421, 120.456); - points += QPointF(229.393, 120.277); - points += QPointF(230.6, 120.629); - points += QPointF(232.808, 122.058); - points += QPointF(236.545, 125.75); - points += QPointF(241.092, 131.261); - points += QPointF(249.22, 142.455); - points += QPointF(262.477, 162.745); - points += QPointF(286.15, 201.448); - points += QPointF(323.075, 264.247); - points += QPointF(362.315, 330.86); - points += QPointF(390.909, 377.669); - points += QPointF(408.797, 405.589); - points += QPointF(417.135, 417.929); - points += QPointF(417.135, 417.929); - points += QPointF(35, 417.953); - - return points; -} - -//--------------------------------------------------------------------------------------------------------------------- -QVector<QPointF> TST_VAbstractDetail::OutputPointsIssue298Case2() const -{ - QVector<QPointF> points; - - points += QPointF(-2.7952999999999975, 4.8384699505981095); - points += QPointF(67.34448942068963, -0.23248582689164274); - points += QPointF(73.11721243320879, 39.48203774070609); - points += QPointF(75.42415682885321, 49.62029267468959); - points += QPointF(78.79409614728041, 60.281321268788744); - points += QPointF(83.27292363150828, 71.59911521750833); - points += QPointF(88.79988374248082, 83.39960453097031); - points += QPointF(95.2926159908344, 95.5247556686474); - points += QPointF(102.65546594334339, 107.82863001903641); - points += QPointF(110.78654319853989, 120.17975944490887); - points += QPointF(119.5782864094781, 132.4565262107595); - points += QPointF(128.91893020761376, 144.54068833830968); - points += QPointF(138.69670055252752, 156.3216457494432); - points += QPointF(148.79638835752286, 167.69430252867102); - points += QPointF(159.09802741244354, 178.55148997659143); - points += QPointF(169.48171675272164, 188.79080814910267); - points += QPointF(179.81876372713828, 198.30845505847407); - points += QPointF(189.9727199683426, 207.00061743916868); - points += QPointF(199.7939139119543, 214.75881893038778); - points += QPointF(209.1143810932559, 221.476716907111); - points += QPointF(216.03386663545683, 225.9476461661168); - points += QPointF(215.3306509043856, 223.3387762725701); - points += QPointF(205.75073516810195, 194.75155680967347); - points += QPointF(197.88802785264718, 169.29686123304236); - points += QPointF(193.97579117825833, 155.08026950731082); - points += QPointF(191.1640933645057, 142.90507610480435); - points += QPointF(189.3638602852325, 131.49392126360493); - points += QPointF(189.14507682295456, 117.75764312564759); - points += QPointF(194.42693552963567, 100.97950138920423); - points += QPointF(210.03879336533757, 85.41035725481989); - points += QPointF(231.36634627769158, 81.48275234606332); - points += QPointF(246.4916615881645, 85.89378050620131); - points += QPointF(256.60614755001956, 92.43979519799973); - points += QPointF(264.4750900046005, 100.21398185636762); - points += QPointF(270.9888544453203, 108.1087159300009); - points += QPointF(280.35077918473866, 121.00209505562212); - points += QPointF(294.42535276480356, 142.5434013797918); - points += QPointF(318.5597512322288, 182.00074197391842); - points += QPointF(394.73028222951507, 311.42213969492946); - points += QPointF(422.9514429826756, 357.62079373755); - points += QPointF(440.37197676737753, 384.8111617646563); - points += QPointF(488.2841719585649, 455.71983154868764); - points += QPointF(-2.795300000000013, 455.7506738094777); - points += QPointF(-2.7952999999999975, 4.8384699505981095); - - return points; -} - -//--------------------------------------------------------------------------------------------------------------------- -QVector<QPointF> TST_VAbstractDetail::InputPointsIssue548Case1() const -{ - QVector<QPointF> points; - - points += QPointF(236.97989607468364, 65.89325192030674); - points += QPointF(198.93409106041895, 172.04876297154925); - points += QPointF(260.32251114299453, 75.38027418944861); - points += QPointF(324.54110236213444, 101.48031496062993); - points += QPointF(29.858267716535437, 300.85039370078744); - points += QPointF(99.86433649395013, 10.166060970128015); - - return points; -} - -//--------------------------------------------------------------------------------------------------------------------- -QVector<QPointF> TST_VAbstractDetail::OutputPointsIssue548Case1() const -{ - QVector<QPointF> points; - - points += QPointF(251.32210577118798, 59.48301432799721); - points += QPointF(243.9841262159756, 79.95746530820585); - points += QPointF(255.82424817748586, 61.31279754390509); - points += QPointF(348.48337789725855, 98.9717841021069); - points += QPointF(29.780382054543473, 314.59289909613994); - points += QPointF(17.01672179602679, 305.7450049304056); - points += QPointF(91.92616539550944, -5.299480329501037); - points += QPointF(251.32210577118798, 59.48301432799721); - - return points; -} - -//--------------------------------------------------------------------------------------------------------------------- -QVector<QPointF> TST_VAbstractDetail::InputPointsIssue548Case2() const -{ - QVector<QPointF> points; - points << QPointF(99.86433649395013, 10.166060970128015); - points << QPointF(236.97989607468364, 65.89325192030674); - points << QPointF(198.93409106041895, 172.04876297154925); - points << QPointF(260.32251114299453, 75.38027418944861); - points << QPointF(324.54110236213444, 101.48031496062993); - points << QPointF(29.858267716535437, 300.85039370078744); - - return points; -} - -//--------------------------------------------------------------------------------------------------------------------- -QVector<QPointF> TST_VAbstractDetail::OutputPointsIssue548Case2() const -{ - QVector<QPointF> points; - points << QPointF(73.40376616581447, -41.38574336196901); - points << QPointF(245.32830125796568, 28.488685370970344); - points << QPointF(245.32830125796573, 28.488685370970277); - points << QPointF(404.3486874792147, 93.11854543221973); - points << QPointF(29.598648843228922, 346.6587450186291); - points << QPointF(-12.946885351826726, 317.1657644661815); - points << QPointF(73.40376616581447, -41.38574336196901); - - return points; -} - -//--------------------------------------------------------------------------------------------------------------------- -QVector<QPointF> TST_VAbstractDetail::InputPointsIssue548Case3() const -{ - QVector<QPointF> points; - - points += QPointF(99.86433649395013, 10.166060970128015); - points += QPointF(236.97989607468364, 65.89325192030674); - points += QPointF(198.93409106041895, 172.04876297154925); - points += QPointF(260.32251114299453, 75.38027418944861); - points += QPointF(324.54110236213444, 101.48031496062993); - points += QPointF(29.858267716535437, 300.85039370078744); - - return points; -} - -//--------------------------------------------------------------------------------------------------------------------- -QVector<QPointF> TST_VAbstractDetail::OutputPointsIssue548Case3() const -{ - QVector<QPointF> points; - - points += QPointF(46.94319583767885, -92.9375476940661); -#if QT_VERSION < QT_VERSION_CHECK(5, 3, 0) - points += QPointF(234.2633962639462, -16.805935717278903); -#else - points += QPointF(238.798634936, -14.9627013515); -#endif - points += QPointF(484.15627259629446, 84.75677590380938); - points += QPointF(29.339029969922702, 392.46709633647066); - points += QPointF(-55.75203842018885, 333.48113523157537); - points += QPointF(46.94319583767885, -92.9375476940661); - - return points; -} - -//--------------------------------------------------------------------------------------------------------------------- -QVector<QPointF> TST_VAbstractDetail::InputPointsCase3() const -{ - QVector<QPointF> points; - - points += QPointF(35, 35); - points += QPointF(50, 50); - points += QPointF(15, 50); - - return points; -} - -//--------------------------------------------------------------------------------------------------------------------- -QVector<QPointF> TST_VAbstractDetail::InputPointsCase4() const -{ - QVector<QPointF> points; - - points += QPointF(15, 15); - points += QPointF(15, 50); - points += QPointF(50, 50); - - return points; -} - -//--------------------------------------------------------------------------------------------------------------------- -QVector<QPointF> TST_VAbstractDetail::InputPointsCase5() const -{ - QVector<QPointF> points; - - points += QPointF(35, 35); - - return points; -} diff --git a/src/test/ValentinaTest/tst_vabstractpiece.cpp b/src/test/ValentinaTest/tst_vabstractpiece.cpp new file mode 100644 index 000000000..6705e500e --- /dev/null +++ b/src/test/ValentinaTest/tst_vabstractpiece.cpp @@ -0,0 +1,3161 @@ +/************************************************************************ + ** + ** @file + ** @author Roman Telezhynskyi <dismine(at)gmail.com> + ** @date 17 11, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2016 Valentina project + ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see <http://www.gnu.org/licenses/>. + ** + *************************************************************************/ + +#include "tst_vabstractpiece.h" +#include "../vlayout/vabstractpiece.h" + +#include <QPointF> +#include <QVector> + +#include <QtTest> + +//--------------------------------------------------------------------------------------------------------------------- +TST_VAbstractPiece::TST_VAbstractPiece(QObject *parent) + : AbstractTest(parent) +{} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VAbstractPiece::EquidistantRemoveLoop_data() +{ + QTest::addColumn<QVector<VSAPoint>>("points"); + QTest::addColumn<qreal>("width"); + QTest::addColumn<QVector<QPointF>>("ekvOrig"); + + // See file src/app/share/collection/test/seamtest1.val + QTest::newRow("Seam test 1") << InputPointsCase1() + << 37.795275590551185 // seam allowance width + << OutputPointsCase1(); + + // See file src/app/share/collection/test/seamtest2.val + QTest::newRow("Seam test 2") << InputPointsCase2() + << 37.795275590551185 // seam allowance width + << OutputPointsCase2(); + + // See file src/app/share/collection/test/seamtest3.val + QTest::newRow("Seam test 3") << InputPointsCase3() + << 37.795275590551185 // seam allowance width + << OutputPointsCase3(); + + // These are two real cases where equdistant has loop. + // See issue #298. Segmented Curve isn't selected in Seam Allowance tool. + // https://bitbucket.org/dismine/valentina/issue/298/segmented-curve-isnt-selected-in-seam + // Code should clean loops in path. + QTest::newRow("Issue 298. Case1") << InputPointsIssue298Case1() + << 75.5906 // seam allowance width + << OutputPointsIssue298Case1(); + + QTest::newRow("Issue 298. Case2") << InputPointsIssue298Case2() + << 37.7953 // seam allowance width + << OutputPointsIssue298Case2(); + + // See issue #548. Bug Detail tool. Case when seam allowance is wrong. + // https://bitbucket.org/dismine/valentina/issues/548/bug-detail-tool-case-when-seam-allowance + // Files: Steampunk_trousers.val and marie.vit + // Actually buggy detail see in file src/app/share/collection/bugs/Steampunk_trousers_issue_#548.val + // Code should clean loops in path. + QTest::newRow("Issue 548. Case1") << InputPointsIssue548Case1() + << 11.338582677165354 // seam allowance width (0.3 cm) + << OutputPointsIssue548Case1(); + + QTest::newRow("Issue 548. Case2") << InputPointsIssue548Case2() + << 37.795275590551185 // seam allowance width (1.0 cm) + << OutputPointsIssue548Case2(); + + QTest::newRow("Issue 548. Case3") << InputPointsIssue548Case3() + << 75.59055118110237 // seam allowance width (2.0 cm) + << OutputPointsIssue548Case3(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VAbstractPiece::EquidistantRemoveLoop() const +{ + QFETCH(QVector<VSAPoint>, points); + QFETCH(qreal, width); + QFETCH(QVector<QPointF>, ekvOrig); + + const QVector<QPointF> ekv = VAbstractPiece::Equidistant(points, width); + + // Begin comparison + Comparison(ekv, ekvOrig); +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<VSAPoint> TST_VAbstractPiece::InputPointsCase1() const +{ + + QVector<VSAPoint> points; + + VSAPoint p = VSAPoint(30.0, 894.8030236220472); + p.SetSAAfter(0); + p.SetSABefore(75.59055118110237); + points.append(p); + + p = VSAPoint(30.0, 39.999874015748034); + //////p.SetSAAfter(-1); + p.SetSABefore(0); + points.append(p); + + p = VSAPoint(30.0, 39.999874015748034); + //////p.SetSAAfter(-1); + p.SetSABefore(0); + points.append(p); + + p = VSAPoint(47.64159471849116, 39.94788491648882); + //////p.SetSAAfter(-1); + //////p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(76.58589406160007, 39.22029871626823); + //////p.SetSAAfter(-1); + //////p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(96.8510955083063, 38.214779786537555); + //////p.SetSAAfter(-1); + //////p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(117.72526111352542, 36.63514697516433); + //////p.SetSAAfter(-1); + //////p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(139.00155591749595, 34.36192982961571); + //////p.SetSAAfter(-1); + //////p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(160.47314496045635, 31.27565789735886); + //////p.SetSAAfter(-1); + //////p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(181.9331932826451, 27.25686072586095); + //////p.SetSAAfter(-1); + //////p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(203.17486592430072, 22.18606786258914); + //////p.SetSAAfter(-1); + //////p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(223.99132792566166, 15.943808855010598); + //////p.SetSAAfter(-1); + //////p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(239.1756066691363, 10.378329140641144); + //////p.SetSAAfter(-1); + //////p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(249.07102191481937, 6.266596479372291); + //////p.SetSAAfter(-1); + //////p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(258.7437898355629, 1.7947951524770347); + //////p.SetSAAfter(-1); + //////p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(268.16805606139667, -3.0520086466112275); + //////p.SetSAAfter(-1); + //////p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(277.3179662223507, -8.2887487244591); + //////p.SetSAAfter(-1); + //////p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(286.16766594845456, -13.93035888763319); + //////p.SetSAAfter(-1); + //////p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(294.69130086973814, -19.991772942700095); + //////p.SetSAAfter(-1); + //////p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(302.86301661623133, -26.48792469622643); + //////p.SetSAAfter(-1); + //////p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(310.6569588179638, -33.433747954778795); + //////p.SetSAAfter(-1); + //////p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(318.04727310496537, -40.84417652492378); + //////p.SetSAAfter(-1); + //////p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(325.00810510726603, -48.73414421322801); + //////p.SetSAAfter(-1); + //////p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(331.51360045489537, -57.118584826258086); + //////p.SetSAAfter(-1); + //////p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(334.56692913385825, -61.522435695538036); + p.SetSAAfter(0); + //////p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(334.56692913385825, -61.522435695538036); + p.SetSAAfter(0); + //////p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(519.4465667350105, -36.01405338211436); + //////p.SetSAAfter(-1); + p.SetSABefore(0); + points.append(p); + + p = VSAPoint(460.3937007874016, 342.36207874015753); + //////p.SetSAAfter(-1); + //////p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(620.5290071875437, -5.50631876178551); + p.SetSAAfter(0); + //////p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(944.2945933263424, 136.63905516701567); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(0); + points.append(p); + + p = VSAPoint(944.2945933263424, 136.63905516701567); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(0); + points.append(p); + + p = VSAPoint(937.525981220313, 150.5000566598672); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(924.7444201119979, 177.43472401968558); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(912.8425448338431, 203.43742191080565); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(901.7902332810357, 228.52240953585334); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(891.5573633487625, 252.7039460974546); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(882.1138129322104, 275.99629079823535); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(869.2733175133695, 309.4054580978942); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(854.7606685168345, 350.82610676604395); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(842.8630996965477, 388.94665363817853); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(833.3396342140044, 423.88117233530545); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(825.9492952306994, 455.7437364784321); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(820.4511059081283, 484.6484196885659); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(816.6040894077858, 510.7092955867147); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(814.1672688911672, 534.0404377938855); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(812.8996675197675, 554.7559199310863); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(812.5603084550817, 572.9698156193242); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(812.9082148586052, 588.7961984796068); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(814.1809574610598, 608.5715133604979); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(815.1968503937007, 618.5825511811024); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(815.1968503937007, 618.5825511811024); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(815.7375399808675, 623.4475087782134); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(817.2456173381056, 633.4974833757362); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(819.2665464515061, 643.8914388413946); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(821.8012316951542, 654.584830268716); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(824.8505774431355, 665.5331127512278); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(828.4154880695357, 676.6917413824576); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(832.4968679484402, 688.0161712559327); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(837.0956214539344, 699.4618574651809); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(842.212652960104, 710.9842551037295); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(847.8488668410344, 722.5388192651058); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(854.0051674708111, 734.0810050428374); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(860.6824592235198, 745.5662675304518); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(867.8816464732456, 756.9500618214765); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(875.6036335940746, 768.187843009439); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(883.8493249600917, 779.2350661878667); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(892.6196249453828, 790.0471864502871); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(901.9154379240335, 800.5796588902277); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(911.7376682701291, 810.7879386012161); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(922.0872203577552, 820.6274806767794); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(932.9649985609971, 830.0537402104453); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(944.3719072539405, 839.0221722957415); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(956.3088508106711, 847.4882320261951); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(968.776733605274, 855.4073744953336); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(981.7764600118351, 862.7350547966848); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(995.3089344044396, 869.4267280237759); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(1009.3750611571733, 875.4378492701345); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(1023.9757446441214, 880.7238736292878); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(1039.1118892393697, 885.2402561947638); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(1054.784399317004, 888.9424520600894); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(1070.994179251109, 891.7859163187926); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(1087.7421334157707, 893.7261040644007); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(1105.0291661850742, 894.7184703904409); + p.SetSAAfter(188.97637795275591); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(1113.8976377952758, 894.8030236220472); + p.SetSAAfter(0); + p.SetSABefore(188.97637795275591); + points.append(p); + + p = VSAPoint(1113.8976377952758, 894.8030236220472); + p.SetSAAfter(0); + p.SetSABefore(188.97637795275591); + points.append(p); + + return points; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<QPointF> TST_VAbstractPiece::OutputPointsCase1() const +{ + QVector<QPointF> points; + + points += QPointF(30.00000000000004, 970.3929479721926); + points += QPointF(30.0, 2.204434307474013); + points += QPointF(47.110950439162494, 2.154008996440882); + points += QPointF(75.17428353484098, 1.4485680510386028); + points += QPointF(94.48820285018608, 0.4902498458165696); + points += QPointF(114.29080866669788, -1.0082936883322242); + points += QPointF(134.30369213200785, -3.146524533710341); + points += QPointF(154.30324182399514, -6.0212092507409025); + points += QPointF(174.06202812984606, -9.721413151776975); + points += QPointF(193.35089649585723, -14.32603434620921); + points += QPointF(212.04908234619523, -19.93308318294329); + points += QPointF(225.4146962614004, -24.83196935145066); + points += QPointF(233.88383173589082, -28.35105572413872); + points += QPointF(242.16354279128632, -32.17883523742874); + points += QPointF(250.12919225691988, -36.27548734456109); + points += QPointF(257.76141086050376, -40.64361165848513); + points += QPointF(265.0438386703493, -45.28609897626606); + points += QPointF(271.9635110924753, -50.20688688697322); + points += QPointF(278.5110730948284, -55.4119084151831); + points += QPointF(284.68071875165725, -60.91018735939974); + points += QPointF(290.46975730117975, -66.71498198586181); + points += QPointF(295.87773947883056, -72.84482460043537); + points += QPointF(301.0311752209645, -79.48669791277798); + points += QPointF(292.5914051639158, -67.31392104851938); + points += QPointF(556.8930273120665, -30.847456102511416); + points += QPointF(539.6101141051189, 79.89131577778163); + points += QPointF(585.9167315845334, -20.702420721823447); + points += QPointF(1117.4712505569892, 212.6701769158142); + points += QPointF(1107.8013393916237, 232.47256047676322); + points += QPointF(1096.0328222042483, 257.2724337531229); + points += QPointF(1085.2347243947604, 280.86364678273935); + points += QPointF(1075.284743777034, 303.4467181585846); + points += QPointF(1066.1500107021461, 325.033221582634); + points += QPointF(1057.8916931702825, 345.40221101096097); + points += QPointF(1046.6844069650929, 374.5619971088514); + points += QPointF(1034.1843603449327, 410.2384638595294); + points += QPointF(1024.281900134066, 441.9665592645446); + points += QPointF(1016.6128103198599, 470.0987514791772); + points += QPointF(1010.8915481272591, 494.7652903217387); + points += QPointF(1006.8300406648394, 516.1171535751373); + points += QPointF(1004.140951447517, 534.3338730421456); + points += QPointF(1002.5429209641061, 549.6340874837038); + points += QPointF(1001.7684597861733, 562.2905401031172); + points += QPointF(1001.5753826870504, 572.6532694631434); + points += QPointF(1001.7511114738644, 580.6472328726268); + points += QPointF(1002.5244573746393, 592.6631414076071); + points += QPointF(1011.1831553003773, 625.860901250618); + points += QPointF(1013.5469326629959, 631.1835932583286); + points += QPointF(1016.1978697144372, 636.6181674061058); + points += QPointF(1019.1173567112357, 642.0917891993197); + points += QPointF(1022.283791807397, 647.5382096308747); + points += QPointF(1025.6730034935645, 652.8974380139866); + points += QPointF(1029.258679857382, 658.1156604426072); + points += QPointF(1033.0128662502555, 663.1453581470851); + points += QPointF(1036.906587776057, 667.9455799725583); + points += QPointF(1040.910648783598, 672.4823173517011); + points += QPointF(1044.9966554234593, 676.7289189086724); + points += QPointF(1049.138296281844, 680.666466074281); + points += QPointF(1053.3128972071952, 684.2840128781046); + points += QPointF(1057.5032369521043, 687.5785757108713); + points += QPointF(1061.6995688685456, 690.5547476668297); + points += QPointF(1065.9017414956827, 693.2238137995831); + points += QPointF(1070.1212524492987, 695.6022659553563); + points += QPointF(1074.3830151134682, 697.7096649640421); + points += QPointF(1078.7265805419665, 699.565875909043); + points += QPointF(1083.206554246492, 701.1878034134409); + points += QPointF(1087.8919933013688, 702.5858632116882); + points += QPointF(1092.8646688655851, 703.7605199081748); + points += QPointF(1098.2162239125396, 704.699271425244); + points += QPointF(1104.0444208482252, 705.3744462055462); + points += QPointF(1304.758494368609, 711.4626979457951); + points += QPointF(1293.9429531218987, 1089.1048479381132); + points += QPointF(30.00000000000004, 970.3929479721926); + + return points; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<VSAPoint> TST_VAbstractPiece::InputPointsCase2() const +{ + + QVector<VSAPoint> points; + + VSAPoint p = VSAPoint(30.0, 39.999874015748034); + ////p.SetSAAfter(-1); + ////p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(407.9527559055118, 39.999874015748034); + ////p.SetSAAfter(-1); + ////p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(407.9527559055118, 228.97625196850396); + ////p.SetSAAfter(-1); + ////p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(407.9527559055118, 228.97625196850396); + ////p.SetSAAfter(-1); + ////p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(403.3769166670402, 231.4465511704684); + p.SetSAAfter(37.803178025111038); + p.SetSABefore(37.803178025111038); + points.append(p); + + p = VSAPoint(394.1607984354165, 235.58132461572228); + p.SetSAAfter(37.818528535007879); + p.SetSABefore(37.818528535007879); + points.append(p); + + p = VSAPoint(384.8923171505302, 238.7905285112787); + p.SetSAAfter(37.833434086432739); + p.SetSABefore(37.833434086432739); + points.append(p); + + p = VSAPoint(375.59921131499664, 241.12018552459608); + p.SetSAAfter(37.847993627262561); + p.SetSABefore(37.847993627262561); + points.append(p); + + p = VSAPoint(366.3092194314313, 242.61631832313287); + p.SetSAAfter(37.862293350550544); + p.SetSABefore(37.862293350550544); + points.append(p); + + p = VSAPoint(357.0500800024495, 243.3249495743475); + p.SetSAAfter(37.876405426208798); + p.SetSABefore(37.876405426208798); + points.append(p); + + p = VSAPoint(347.8495315306667, 243.2921019456984); + p.SetSAAfter(37.890387402651413); + p.SetSABefore(37.890387402651413); + points.append(p); + + p = VSAPoint(338.73531251869827, 242.56379810464406); + p.SetSAAfter(37.904282247411182); + p.SetSABefore(37.904282247411182); + points.append(p); + + p = VSAPoint(329.7351614691596, 241.18606071864286); + p.SetSAAfter(37.91811891950119); + p.SetSABefore(37.91811891950119); + points.append(p); + + p = VSAPoint(320.876816884666, 239.20491245515328); + p.SetSAAfter(37.931913327979281); + p.SetSABefore(37.931913327979281); + points.append(p); + + p = VSAPoint(312.18801726783295, 236.6663759816338); + p.SetSAAfter(37.945669528152067); + p.SetSABefore(37.945669528152067); + points.append(p); + + p = VSAPoint(303.6965011212758, 233.61647396554275); + p.SetSAAfter(37.959381027682795); + p.SetSABefore(37.959381027682795); + points.append(p); + + p = VSAPoint(295.43000694760997, 230.10122907433865); + p.SetSAAfter(37.973032106608528); + p.SetSABefore(37.973032106608528); + points.append(p); + + p = VSAPoint(287.41627324945074, 226.16666397547993); + p.SetSAAfter(37.986599088053786); + p.SetSABefore(37.986599088053786); + points.append(p); + + p = VSAPoint(279.6830385294136, 221.85880133642502); + p.SetSAAfter(38.000051524725791); + p.SetSABefore(38.000051524725791); + points.append(p); + + p = VSAPoint(272.2580412901139, 217.2236638246324); + p.SetSAAfter(38.013353288194111); + p.SetSABefore(38.013353288194111); + points.append(p); + + p = VSAPoint(265.16902003416703, 212.3072741075605); + p.SetSAAfter(38.026463563868212); + p.SetSABefore(38.026463563868212); + points.append(p); + + p = VSAPoint(258.44371326418843, 207.15565485266765); + p.SetSAAfter(38.03933776597485); + p.SetSABefore(38.03933776597485); + points.append(p); + + p = VSAPoint(252.1098594827934, 201.81482872741242); + p.SetSAAfter(38.051928395587325); + p.SetSABefore(38.051928395587325); + points.append(p); + + p = VSAPoint(246.19519719259745, 196.33081839925325); + p.SetSAAfter(38.064185872874937); + p.SetSABefore(38.064185872874937); + points.append(p); + + p = VSAPoint(240.72746489621585, 190.74964653564848); + p.SetSAAfter(38.076059384395691); + p.SetSABefore(38.076059384395691); + points.append(p); + + p = VSAPoint(235.73440109626404, 185.11733580405664); + p.SetSAAfter(38.087497800100167); + p.SetSABefore(38.087497800100167); + points.append(p); + + p = VSAPoint(231.24374429535737, 179.47990887193612); + p.SetSAAfter(38.098450736467157); + p.SetSABefore(38.098450736467157); + points.append(p); + + p = VSAPoint(227.2832329961113, 173.88338840674544); + p.SetSAAfter(38.108869877607624); + p.SetSABefore(38.108869877607624); + points.append(p); + + p = VSAPoint(223.88060570114112, 168.37379707594295); + p.SetSAAfter(38.118710724548052); + p.SetSABefore(38.118710724548052); + points.append(p); + + p = VSAPoint(221.06360091306237, 162.99715754698713); + p.SetSAAfter(38.127935039089436); + p.SetSABefore(38.127935039089436); + points.append(p); + + p = VSAPoint(218.8599571344903, 157.79949248733644); + p.SetSAAfter(38.136514404353001); + p.SetSABefore(38.136514404353001); + points.append(p); + + p = VSAPoint(217.2974128680403, 152.82682456444928); + p.SetSAAfter(38.144435562325597); + p.SetSABefore(38.144435562325597); + points.append(p); + + p = VSAPoint(216.40370661632784, 148.12517644578412); + p.SetSAAfter(38.15170849722444); + p.SetSABefore(38.15170849722444); + points.append(p); + + p = VSAPoint(216.20657688196826, 143.7405707987994); + p.SetSAAfter(38.158378424653918); + p.SetSABefore(38.158378424653918); + points.append(p); + + p = VSAPoint(216.7337621675769, 139.71903029095353); + p.SetSAAfter(38.164542166418755); + p.SetSABefore(38.164542166418755); + points.append(p); + + p = VSAPoint(218.01300097576927, 136.10657758970495); + p.SetSAAfter(38.17036598425517); + p.SetSABefore(38.17036598425517); + points.append(p); + + p = VSAPoint(218.97637795275608, 134.48806299212646); + p.SetSAAfter(38.173228346456696); + p.SetSABefore(38.173228346456696); + points.append(p); + + p = VSAPoint(218.97637795275608, 134.48806299212646); + p.SetSAAfter(38.173228346456696); + p.SetSABefore(38.173228346456696); + points.append(p); + + p = VSAPoint(218.97637795275608, 134.48806299212646); + p.SetSAAfter(38.173228346456696); + p.SetSABefore(38.173228346456696); + points.append(p); + + p = VSAPoint(217.1202289172026, 137.73030103616844); + p.SetSAAfter(38.167995197589178); + p.SetSABefore(38.167995197589178); + points.append(p); + + p = VSAPoint(212.6973363405255, 143.4397404435662); + p.SetSAAfter(38.157878743288215); + p.SetSABefore(38.157878743288215); + points.append(p); + + p = VSAPoint(207.48487786706698, 148.24866810991395); + p.SetSAAfter(38.147944713012919); + p.SetSABefore(38.147944713012919); + points.append(p); + + p = VSAPoint(201.55301739671896, 152.18989767496004); + p.SetSAAfter(38.137968823998783); + p.SetSABefore(38.137968823998783); + points.append(p); + + p = VSAPoint(194.9719188293733, 155.29624277845284); + p.SetSAAfter(38.127775030254007); + p.SetSABefore(38.127775030254007); + points.append(p); + + p = VSAPoint(187.81174606492203, 157.6005170601407); + p.SetSAAfter(38.117238836985599); + p.SetSABefore(38.117238836985599); + points.append(p); + + p = VSAPoint(180.14266300325704, 159.13553415977202); + p.SetSAAfter(38.106283289982827); + p.SetSABefore(38.106283289982827); + points.append(p); + + p = VSAPoint(172.0348335442702, 159.93410771709506); + p.SetSAAfter(38.094871286509886); + p.SetSABefore(38.094871286509886); + points.append(p); + + p = VSAPoint(163.55842158785353, 160.02905137185826); + p.SetSAAfter(38.082997200945435); + p.SetSABefore(38.082997200945435); + points.append(p); + + p = VSAPoint(154.78359103389897, 159.4531787638099); + p.SetSAAfter(38.070679409075119); + p.SetSABefore(38.070679409075119); + points.append(p); + + p = VSAPoint(145.78050578229832, 158.23930353269841); + p.SetSAAfter(38.057954219352141); + p.SetSABefore(38.057954219352141); + points.append(p); + + p = VSAPoint(136.61932973294367, 156.42023931827214); + p.SetSAAfter(38.044871166362007); + p.SetSABefore(38.044871166362007); + points.append(p); + + p = VSAPoint(127.37022678572683, 154.0287997602794); + p.SetSAAfter(38.031489421641503); + p.SetSABefore(38.031489421641503); + points.append(p); + + p = VSAPoint(118.10336084053982, 151.09779849846862); + p.SetSAAfter(38.017875048227786); + p.SetSABefore(38.017875048227786); + points.append(p); + + p = VSAPoint(108.88889579727454, 147.66004917258803); + p.SetSAAfter(38.00409885919936); + p.SetSABefore(38.00409885919936); + points.append(p); + + p = VSAPoint(99.79699555582292, 143.7483654223861); + p.SetSAAfter(37.990234686678903); + p.SetSABefore(37.990234686678903); + points.append(p); + + p = VSAPoint(90.8978240160769, 139.3955608876111); + p.SetSAAfter(37.976357907221328); + p.SetSABefore(37.976357907221328); + points.append(p); + + p = VSAPoint(82.26154507792839, 134.63444920801146); + p.SetSAAfter(37.962544096747962); + p.SetSABefore(37.962544096747962); + points.append(p); + + p = VSAPoint(73.95832264126932, 129.49784402333552); + p.SetSAAfter(37.94886770258455); + p.SetSABefore(37.94886770258455); + points.append(p); + + p = VSAPoint(66.05832060599164, 124.01855897333157); + p.SetSAAfter(37.935400622146403); + p.SetSABefore(37.935400622146403); + points.append(p); + + p = VSAPoint(58.63170287198729, 118.22940769774803); + p.SetSAAfter(37.922210567500777); + p.SetSABefore(37.922210567500777); + points.append(p); + + p = VSAPoint(51.74863333914817, 112.16320383633325); + p.SetSAAfter(37.90935907207141); + p.SetSABefore(37.90935907207141); + points.append(p); + + p = VSAPoint(45.47927590736623, 105.85276102883554); + p.SetSAAfter(37.896898960241472); + p.SetSABefore(37.896898960241472); + points.append(p); + + p = VSAPoint(39.8937944765334, 99.33089291500332); + p.SetSAAfter(37.884871055952601); + p.SetSABefore(37.884871055952601); + points.append(p); + + p = VSAPoint(35.062352946541615, 92.63041313458488); + p.SetSAAfter(37.873299866072891); + p.SetSABefore(37.873299866072891); + points.append(p); + + p = VSAPoint(31.055115217282804, 85.78413532732864); + p.SetSAAfter(37.86218797621639); + p.SetSABefore(37.86218797621639); + points.append(p); + + p = VSAPoint(27.94224518864889, 78.82487313298289); + p.SetSAAfter(37.851509027526909); + p.SetSABefore(37.851509027526909); + points.append(p); + + p = VSAPoint(25.793906760531815, 71.78544019129603); + p.SetSAAfter(37.841199561247805); + p.SetSABefore(37.841199561247805); + points.append(p); + + p = VSAPoint(24.68026383282351, 64.69865014201642); + p.SetSAAfter(37.831150915024352); + p.SetSABefore(37.831150915024352); + points.append(p); + + p = VSAPoint(24.671480305415898, 57.597316624892386); + p.SetSAAfter(37.821203708860601); + p.SetSABefore(37.821203708860601); + points.append(p); + + p = VSAPoint(25.837720078200917, 50.514253279672296); + p.SetSAAfter(37.811148513024627); + p.SetSABefore(37.811148513024627); + points.append(p); + + p = VSAPoint(28.2491470510705, 43.48227374610451); + p.SetSAAfter(37.800735391906976); + p.SetSABefore(37.800735391906976); + points.append(p); + + p = VSAPoint(30.0, 39.999874015748034); + ////p.SetSAAfter(-1); + ////p.SetSABefore(-1); + points.append(p); + + return points; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<QPointF> TST_VAbstractPiece::OutputPointsCase2() const +{ + QVector<QPointF> points; + + points += QPointF(6.735602739585184, 2.204598425196849); + points += QPointF(445.748031496063, 2.204598425196849); + points += QPointF(445.748031496063, 251.48446223243934); + points += QPointF(420.1672505436216, 265.34467354701); + points += QPointF(408.16868834563587, 270.74969811280204); + points += QPointF(395.75743565485675, 275.06821746196044); + points += QPointF(383.28015968092507, 278.216263983686); + points += QPointF(370.8288026520235, 280.2409452967658); + points += QPointF(358.4874104434599, 281.2043381226534); + points += QPointF(346.3281093878975, 281.1794055890767); + points += QPointF(334.4094715702431, 280.2452307190486); + points += QPointF(322.77695514341303, 278.48262025768446); + points += QPointF(311.46472096401544, 275.97070996938834); + points += QPointF(300.4980766475991, 272.78475431818316); + points += QPointF(289.8959627998986, 268.994968265893); + points += QPointF(279.67312801429796, 264.6661417252929); + points += QPointF(269.84184205634284, 259.8577269753623); + points += QPointF(260.4131332789275, 254.62414553625888); + points += QPointF(251.39760921382512, 249.0151257350064); + points += QPointF(242.80594716150756, 243.07593816151942); + points += QPointF(234.64914462550888, 236.84743207794344); + points += QPointF(226.93861367892654, 230.36578881474733); + points += QPointF(219.6862008839008, 223.6618981488572); + points += QPointF(212.90422632696564, 216.76022967199233); + points += QPointF(206.60567695694368, 209.67701009653408); + points += QPointF(200.8047886617048, 202.41742546763192); + points += QPointF(195.51846445950318, 194.97144814919497); + points += QPointF(195.49646472111115, 194.93594659378365); + points += QPointF(185.71068181674897, 196.88038239808796); + points += QPointF(174.06579870156523, 198.0108674081686); + points += QPointF(162.4698365016369, 198.12450807507133); + points += QPointF(150.93599464376967, 197.35134057907845); + points += QPointF(139.4731688630524, 195.78946993073865); + points += QPointF(128.09385198069478, 193.51339391764853); + points += QPointF(116.81695231109029, 190.58079085562875); + points += QPointF(105.66811291289228, 187.03735678012447); + points += QPointF(94.6789709925457, 182.91996300992662); + points += QPointF(83.88608373098256, 178.2585220934185); + points += QPointF(73.32986575781915, 173.07687844159756); + points += QPointF(63.05370660182625, 167.39293026852914); + points += QPointF(53.10337911388009, 161.21809122399117); + points += QPointF(43.52687054865665, 154.55612780781823); + points += QPointF(34.37485617471233, 147.40137397927876); + points += QPointF(25.702201154685437, 139.73635741878132); + points += QPointF(17.571137619050678, 131.52904674063026); + points += QPointF(10.057109595108484, 122.7304016692299); + points += QPointF(3.2585649313074336, 113.27395345986065); + points += QPointF(-2.688329688884947, 103.08109119247632); + points += QPointF(-7.591302782642628, 92.07847647311537); + points += QPointF(-11.187498579572614, 80.23547322967522); + points += QPointF(-13.151329717912063, 67.62324223181253); + points += QPointF(-13.149175120030888, 54.474729701833986); + points += QPointF(-10.94337542157982, 41.194055939258014); + points += QPointF(-6.654890183208465, 28.745230608885407); + points += QPointF(6.735602739585184, 2.204598425196849); + + return points; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<VSAPoint> TST_VAbstractPiece::InputPointsCase3() const +{ + QVector<VSAPoint> points; + + VSAPoint p = VSAPoint(30.0, 39.999874015748034); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(407.9527559055118, 39.999874015748034); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(407.9527559055118, 228.97625196850396); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(407.9527559055118, 228.97625196850396); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(406.33770829042953, 232.38064611626584); + p.SetSAAfter(37.381380099110068); + p.SetSABefore(37.381380099110068); + points.append(p); + + p = VSAPoint(402.870644734503, 238.5569810399819); + p.SetSAAfter(36.603370955765051); + p.SetSABefore(36.603370955765051); + points.append(p); + + p = VSAPoint(399.14591058639644, 243.99520937172397); + p.SetSAAfter(35.879339211886929); + p.SetSABefore(35.879339211886929); + points.append(p); + + p = VSAPoint(395.19316295581496, 248.71848383837556); + p.SetSAAfter(35.202813177025682); + p.SetSABefore(35.202813177025682); + points.append(p); + + p = VSAPoint(391.04205895246355, 252.7499571668203); + p.SetSAAfter(34.56719781657663); + p.SetSABefore(34.56719781657663); + points.append(p); + + p = VSAPoint(386.72225568604733, 256.1127820839417); + p.SetSAAfter(33.965870279175178); + p.SetSABefore(33.965870279175178); + points.append(p); + + p = VSAPoint(382.2634102662714, 258.8301113166233); + p.SetSAAfter(33.392312673818843); + p.SetSABefore(33.392312673818843); + points.append(p); + + p = VSAPoint(377.6951798028408, 260.9250975917487); + p.SetSAAfter(32.840273714828662); + p.SetSABefore(32.840273714828662); + points.append(p); + + p = VSAPoint(373.0472214054606, 262.4208936362013); + p.SetSAAfter(32.303940879158468); + p.SetSABefore(32.303940879158468); + points.append(p); + + p = VSAPoint(368.34919218383584, 263.34065217686486); + p.SetSAAfter(31.778098176885351); + p.SetSABefore(31.778098176885351); + points.append(p); + + p = VSAPoint(363.6307492476716, 263.7075259406228); + p.SetSAAfter(31.25824538248542); + p.SetSABefore(31.25824538248542); + points.append(p); + + p = VSAPoint(358.921549706673, 263.5446676543588); + p.SetSAAfter(30.740662987580134); + p.SetSABefore(30.740662987580134); + points.append(p); + + p = VSAPoint(354.251250670545, 262.87523004495625); + p.SetSAAfter(30.222419479548449); + p.SetSABefore(30.222419479548449); + points.append(p); + + p = VSAPoint(349.6495092489928, 261.72236583929885); + p.SetSAAfter(29.701328542831337); + p.SetSABefore(29.701328542831337); + points.append(p); + + p = VSAPoint(345.1459825517213, 260.1092277642701); + p.SetSAAfter(29.175869934623716); + p.SetSABefore(29.175869934623716); + points.append(p); + + p = VSAPoint(340.7703276884358, 258.0589685467535); + p.SetSAAfter(28.645088729374258); + p.SetSABefore(28.645088729374258); + points.append(p); + + p = VSAPoint(336.5522017688411, 255.59474091363262); + p.SetSAAfter(28.108485094878901); + p.SetSABefore(28.108485094878901); + points.append(p); + + p = VSAPoint(332.52126190264244, 252.73969759179104); + p.SetSAAfter(27.565902911541084); + p.SetSABefore(27.565902911541084); + points.append(p); + + p = VSAPoint(328.7071651995449, 249.51699130811238); + p.SetSAAfter(27.017421899167815); + p.SetSABefore(27.017421899167815); + points.append(p); + + p = VSAPoint(325.1395687692534, 245.94977478948007); + p.SetSAAfter(26.463255170503039); + p.SetSABefore(26.463255170503039); + points.append(p); + + p = VSAPoint(321.84812972147313, 242.06120076277773); + p.SetSAAfter(25.903652411137717); + p.SetSABefore(25.903652411137717); + points.append(p); + + p = VSAPoint(318.86250516590917, 237.87442195488893); + p.SetSAAfter(25.338808050829666); + p.SetSABefore(25.338808050829666); + points.append(p); + + p = VSAPoint(316.2123522122665, 233.4125910926972); + p.SetSAAfter(24.768773642603289); + p.SetSABefore(24.768773642603289); + points.append(p); + + p = VSAPoint(313.9273279702502, 228.69886090308609); + p.SetSAAfter(24.19337403613525); + p.SetSABefore(24.19337403613525); + points.append(p); + + p = VSAPoint(312.03708954956545, 223.75638411293914); + p.SetSAAfter(23.612127698143627); + p.SetSABefore(23.612127698143627); + points.append(p); + + p = VSAPoint(310.57129405991714, 218.60831344913998); + p.SetSAAfter(23.024172586797707); + p.SetSABefore(23.024172586797707); + points.append(p); + + p = VSAPoint(309.55959861101053, 213.27780163857204); + p.SetSAAfter(22.42820018785644); + p.SetSABefore(22.42820018785644); + points.append(p); + + p = VSAPoint(309.03166031255046, 207.788001408119); + p.SetSAAfter(21.822401444747854); + p.SetSABefore(21.822401444747854); + points.append(p); + + p = VSAPoint(309.01713627424215, 202.1620654846643); + p.SetSAAfter(21.204429040574471); + p.SetSABefore(21.204429040574471); + points.append(p); + + p = VSAPoint(309.5456836057906, 196.42314659509157); + p.SetSAAfter(20.57138043760828); + p.SetSABefore(20.57138043760828); + points.append(p); + + p = VSAPoint(310.64695941690104, 190.59439746628436); + p.SetSAAfter(19.919804940549692); + p.SetSABefore(19.919804940549692); + points.append(p); + + p = VSAPoint(312.35062081727835, 184.6989708251262); + p.SetSAAfter(19.24573577317911); + p.SetSABefore(19.24573577317911); + points.append(p); + + p = VSAPoint(313.4645669291343, 181.73215748031558); + p.SetSAAfter(18.897637795275593); + p.SetSABefore(18.897637795275593); + points.append(p); + + p = VSAPoint(313.4645669291343, 181.73215748031558); + p.SetSAAfter(18.897637795275593); + p.SetSABefore(18.897637795275593); + points.append(p); + + p = VSAPoint(313.4645669291343, 181.73215748031558); + p.SetSAAfter(18.897637795275593); + p.SetSABefore(18.897637795275593); + points.append(p); + + p = VSAPoint(313.4645669291343, 181.73215748031558); + p.SetSAAfter(18.897637795275593); + p.SetSABefore(18.897637795275593); + points.append(p); + + p = VSAPoint(313.4645669291343, 181.73215748031558); + p.SetSAAfter(18.897637795275593); + p.SetSABefore(18.897637795275593); + points.append(p); + + p = VSAPoint(313.4645669291343, 181.73215748031558); + p.SetSAAfter(18.897637795275593); + p.SetSABefore(18.897637795275593); + points.append(p); + + p = VSAPoint(313.4645669291343, 181.73215748031558); + p.SetSAAfter(18.897637795275593); + p.SetSABefore(18.897637795275593); + points.append(p); + + p = VSAPoint(315.0998723566189, 177.44976641127198); + p.SetSAAfter(19.446824166328746); + p.SetSABefore(19.446824166328746); + points.append(p); + + p = VSAPoint(317.6731184586346, 169.45847196043132); + p.SetSAAfter(20.452631980165769); + p.SetSABefore(20.452631980165769); + points.append(p); + + p = VSAPoint(319.4487651643931, 162.13409856250706); + p.SetSAAfter(21.355546141728666); + p.SetSABefore(21.355546141728666); + points.append(p); + + p = VSAPoint(320.470410593102, 155.4530193599665); + p.SetSAAfter(22.165276674578177); + p.SetSABefore(22.165276674578177); + points.append(p); + + p = VSAPoint(320.78165286396893, 149.39160749527696); + p.SetSAAfter(22.892420458564697); + p.SetSABefore(22.892420458564697); + points.append(p); + + p = VSAPoint(320.4260900962016, 143.92623611090573); + p.SetSAAfter(23.548583135932272); + p.SetSABefore(23.548583135932272); + points.append(p); + + p = VSAPoint(319.44732040900783, 139.03327834932014); + p.SetSAAfter(24.146396878545747); + p.SetSABefore(24.146396878545747); + points.append(p); + + p = VSAPoint(317.88894192159495, 134.68910735298743); + p.SetSAAfter(24.699324443869902); + p.SetSABefore(24.699324443869902); + points.append(p); + + p = VSAPoint(315.79455275317093, 130.870096264375); + p.SetSAAfter(25.221147659605332); + p.SetSABefore(25.221147659605332); + points.append(p); + + p = VSAPoint(313.2077510229431, 127.55261822595011); + p.SetSAAfter(25.725143604791594); + p.SetSABefore(25.725143604791594); + points.append(p); + + p = VSAPoint(310.1721348501194, 124.71304638018006); + p.SetSAAfter(26.223136485113741); + p.SetSABefore(26.223136485113741); + points.append(p); + + p = VSAPoint(306.73130235390744, 122.32775386953216); + p.SetSAAfter(26.724730852906816); + p.SetSABefore(26.724730852906816); + points.append(p); + + p = VSAPoint(302.9288516535148, 120.3731138364737); + p.SetSAAfter(27.236947738833074); + p.SetSABefore(27.236947738833074); + points.append(p); + + p = VSAPoint(298.80838086814924, 118.82549942347202); + p.SetSAAfter(27.764271724915222); + p.SetSABefore(27.764271724915222); + points.append(p); + + p = VSAPoint(294.41348811701835, 117.66128377299438); + p.SetSAAfter(28.308962477298437); + p.SetSABefore(28.308962477298437); + points.append(p); + + p = VSAPoint(289.7877715193297, 116.85684002750813); + p.SetSAAfter(28.871463995346204); + p.SetSABefore(28.871463995346204); + points.append(p); + + p = VSAPoint(282.5270013648352, 116.23547488513984); + p.SetSAAfter(29.744519639698659); + p.SetSABefore(29.744519639698659); + points.append(p); + + p = VSAPoint(272.4138025206039, 116.50169653372318); + p.SetSAAfter(30.956550523683344); + p.SetSABefore(30.956550523683344); + points.append(p); + + p = VSAPoint(262.16207443587984, 117.7817223666835); + p.SetSAAfter(32.194294958045219); + p.SetSABefore(32.194294958045219); + points.append(p); + + p = VSAPoint(252.12060206432426, 119.88653752375922); + p.SetSAAfter(33.423457501774081); + p.SetSABefore(33.423457501774081); + points.append(p); + + p = VSAPoint(242.63817035959835, 122.62712714468876); + p.SetSAAfter(34.605995611034089); + p.SetSABefore(34.605995611034089); + points.append(p); + + p = VSAPoint(234.06356427536352, 125.81447636921058); + p.SetSAAfter(35.70195258686585); + p.SetSABefore(35.70195258686585); + points.append(p); + + p = VSAPoint(226.74556876528095, 129.25957033706317); + p.SetSAAfter(36.670979260736637); + p.SetSABefore(36.670979260736637); + points.append(p); + + p = VSAPoint(221.03296878301197, 132.77339418798488); + p.SetSAAfter(37.474483357433364); + p.SetSABefore(37.474483357433364); + points.append(p); + + p = VSAPoint(218.97637795275608, 134.48806299212646); + p.SetSAAfter(37.795275590551185); + p.SetSABefore(37.795275590551185); + points.append(p); + + p = VSAPoint(218.97637795275608, 134.48806299212646); + p.SetSAAfter(37.795275590551185); + p.SetSABefore(37.795275590551185); + points.append(p); + + p = VSAPoint(218.97637795275608, 134.48806299212646); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(218.97637795275608, 134.48806299212646); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(218.97637795275608, 134.48806299212646); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(218.97637795275608, 134.48806299212646); + p.SetSAAfter(37.795275590551185); + p.SetSABefore(37.795275590551185); + points.append(p); + + p = VSAPoint(218.97637795275608, 134.48806299212646); + p.SetSAAfter(37.795275590551185); + p.SetSABefore(37.795275590551185); + points.append(p); + + p = VSAPoint(214.11186185064025, 138.80795875858354); + p.SetSAAfter(36.653502722568419); + p.SetSABefore(36.653502722568419); + points.append(p); + + p = VSAPoint(205.18536816471078, 146.02812964687715); + p.SetSAAfter(34.638570080274732); + p.SetSABefore(34.638570080274732); + points.append(p); + + p = VSAPoint(197.17461091794695, 151.63888788459965); + p.SetSAAfter(32.922124316374287); + p.SetSABefore(32.922124316374287); + points.append(p); + + p = VSAPoint(190.02702368501878, 155.74482471949955); + p.SetSAAfter(31.475467886854414); + p.SetSABefore(31.475467886854414); + points.append(p); + + p = VSAPoint(183.69004004059613, 158.45053139932526); + p.SetSAAfter(30.266183845834068); + p.SetSABefore(30.266183845834068); + points.append(p); + + p = VSAPoint(178.11109355934906, 159.86059917182507); + p.SetSAAfter(29.256280085066027); + p.SetSABefore(29.256280085066027); + points.append(p); + + p = VSAPoint(173.23761781594754, 160.07961928474754); + p.SetSAAfter(28.400113855274189); + p.SetSABefore(28.400113855274189); + points.append(p); + + p = VSAPoint(169.01704638506152, 159.21218298584108); + p.SetSAAfter(27.643914239586497); + p.SetSABefore(27.643914239586497); + points.append(p); + + p = VSAPoint(165.396812841361, 157.36288152285397); + p.SetSAAfter(26.930461655777069); + p.SetSABefore(26.930461655777069); + points.append(p); + + p = VSAPoint(162.32435075951594, 154.63630614353477); + p.SetSAAfter(26.20953145720112); + p.SetSABefore(26.20953145720112); + points.append(p); + + p = VSAPoint(159.7470937141963, 151.13704809563185); + p.SetSAAfter(25.44681460859611); + p.SetSABefore(25.44681460859611); + points.append(p); + + p = VSAPoint(157.61247528007215, 146.96969862689363); + p.SetSAAfter(24.625073374270738); + p.SetSABefore(24.625073374270738); + points.append(p); + + p = VSAPoint(155.86792903181333, 142.23884898506853); + p.SetSAAfter(23.740148635253075); + p.SetSABefore(23.740148635253075); + points.append(p); + + p = VSAPoint(154.46088854408993, 137.049090417905); + p.SetSAAfter(22.796456338245449); + p.SetSABefore(22.796456338245449); + points.append(p); + + p = VSAPoint(152.84240084594785, 128.65747053734566); + p.SetSAAfter(21.296571460906105); + p.SetSABefore(21.296571460906105); + points.append(p); + + p = VSAPoint(150.86615884353574, 110.74781740906135); + p.SetSAAfter(18.134320368513631); + p.SetSABefore(18.134320368513631); + points.append(p); + + p = VSAPoint(149.37382105332603, 94.00159365355543); + p.SetSAAfter(15.183683963183684); + p.SetSABefore(15.183683963183684); + points.append(p); + + p = VSAPoint(147.90386548781373, 84.77492816049366); + p.SetSAAfter(13.543967770207646); + p.SetSABefore(13.543967770207646); + points.append(p); + + p = VSAPoint(146.22482573007983, 79.58685396281504); + p.SetSAAfter(12.586956110891197); + p.SetSABefore(12.586956110891197); + points.append(p); + + p = VSAPoint(144.767673193039, 77.0483056159666); + p.SetSAAfter(12.073257080584666); + p.SetSABefore(12.073257080584666); + points.append(p); + + p = VSAPoint(142.9646628872432, 75.4105345645091); + p.SetSAAfter(11.645769545279848); + p.SetSABefore(11.645769545279848); + points.append(p); + + p = VSAPoint(140.76322838736246, 74.77813205619103); + p.SetSAAfter(11.243788560650403); + p.SetSABefore(11.243788560650403); + points.append(p); + + p = VSAPoint(138.11080326806675, 75.25568933876076); + p.SetSAAfter(10.77079881073082); + p.SetSABefore(10.77079881073082); + points.append(p); + + p = VSAPoint(134.95482110402602, 76.94779765996674); + p.SetSAAfter(10.142330100270035); + p.SetSABefore(10.142330100270035); + points.append(p); + + p = VSAPoint(131.24271546991025, 79.95904826755734); + p.SetSAAfter(9.3034514353721871); + p.SetSABefore(9.3034514353721871); + points.append(p); + + p = VSAPoint(126.92191994038947, 84.39403240928104); + p.SetSAAfter(8.216780859744869); + p.SetSABefore(8.216780859744869); + points.append(p); + + p = VSAPoint(124.4881889763782, 87.24396850393732); + p.SetSAAfter(7.559055118110237); + p.SetSABefore(7.559055118110237); + points.append(p); + + p = VSAPoint(124.4881889763782, 87.24396850393732); + p.SetSAAfter(7.559055118110237); + p.SetSABefore(7.559055118110237); + points.append(p); + + p = VSAPoint(124.4881889763782, 87.24396850393732); + //p.SetSAAfter(-1); + p.SetSABefore(7.559055118110237); + points.append(p); + + p = VSAPoint(124.4881889763782, 87.24396850393732); + //p.SetSAAfter(-1); + p.SetSABefore(7.559055118110237); + points.append(p); + + p = VSAPoint(124.4881889763782, 87.24396850393732); + //p.SetSAAfter(-1); + p.SetSABefore(7.559055118110237); + points.append(p); + + p = VSAPoint(124.4881889763782, 87.24396850393732); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(124.4881889763782, 87.24396850393732); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(121.4053345233613, 90.85541892105327); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(115.36650087404239, 97.1700051724747); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(109.48439793077911, 102.44240810316538); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(103.76400391356904, 106.72573235606063); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(98.2102970424097, 110.0730825740958); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(92.8282555372987, 112.53756340020624); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(87.62285761823352, 114.17227947732721); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(82.59908150521179, 115.03033544839411); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(77.76190541823104, 115.16483595634224); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(73.11630757728881, 114.62888564410696); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(68.66726620238268, 113.47558915462355); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(64.41975951351019, 111.7580511308274); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(60.3787657306689, 109.52937621565376); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(56.54926307385639, 106.84266905203805); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(52.93622976307019, 103.75103428291555); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(49.54464401830785, 100.30757655122164); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(44.854132804201555, 94.62627097468447); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(39.45938535079082, 86.2656734510919); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(35.040036121431584, 77.45366765004954); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(31.635910876104337, 68.61509071504); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(29.28683537478949, 60.17477978954592); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(28.03263537746753, 52.55757201704999); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(27.913136644118886, 46.188304541034846); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(28.62975536807624, 42.54811226326452); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(29.458368599363588, 40.697718569632514); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + p = VSAPoint(30.0, 39.999874015748034); + //p.SetSAAfter(-1); + //p.SetSABefore(-1); + points.append(p); + + return points; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<QPointF> TST_VAbstractPiece::OutputPointsCase3() const +{ + QVector<QPointF> points; + + points += QPointF(11.491153250328935, 2.204598425196849); + points += QPointF(445.748031496063, 2.204598425196849); + points += QPointF(445.748031496063, 239.25772323190495); + points += QPointF(437.3011718875349, 252.9620940028659); + points += QPointF(431.5210396453687, 261.04286502132345); + points += QPointF(425.0742362286929, 268.54423500057675); + points += QPointF(418.11166285006243, 275.22268157509825); + points += QPointF(410.66293904201643, 281.0200956238725); + points += QPointF(402.78657384181963, 285.87157614021027); + points += QPointF(394.5732042205309, 289.71737969963584); + points += QPointF(386.1419584708077, 292.51680859777775); + points += QPointF(377.62937764888807, 294.2596521460023); + points += QPointF(369.17363576502424, 294.9709765895621); + points += QPointF(360.89908762820056, 294.7076951308071); + points += QPointF(352.90578450956633, 293.54885121734077); + points += QPointF(345.2659401705694, 291.58363457828597); + points += QPointF(338.02638381419206, 288.9008829382743); + points += QPointF(331.214452254774, 285.58206377611566); + points += QPointF(324.8447893417784, 281.69791760615396); + points += QPointF(318.92540323684557, 277.307901893045); + points += QPointF(313.4622927999198, 272.4613294067597); + points += QPointF(308.4626029358523, 267.199302528306); + points += QPointF(303.93656720661477, 261.5568795640949); + points += QPointF(299.8985555961715, 255.5651950634023); + points += QPointF(296.3674859139379, 249.25344082283073); + points += QPointF(293.36675891047514, 242.65070430384247); + points += QPointF(290.9237823363554, 235.7876787648548); + points += QPointF(289.0690799250026, 228.6982245333719); + points += QPointF(287.8349531366277, 221.42069049439027); + points += QPointF(287.2536910795491, 213.9988201772971); + points += QPointF(287.3554164994589, 206.48200110960104); + points += QPointF(288.165803158891, 198.9246157503596); + points += QPointF(289.7040578703973, 191.38436170566055); + points += QPointF(291.98164916416846, 183.91963819443603); + points += QPointF(293.700387439861, 179.7469098237058); + points += QPointF(296.5884693392089, 171.49219190163677); + points += QPointF(297.59693481965496, 166.31235205234043); + points += QPointF(298.2857333094973, 160.53208953533525); + points += QPointF(298.43819035278193, 155.84335424804448); + points += QPointF(298.1940021729857, 152.25436961670644); + points += QPointF(297.7243212024687, 149.73346552056378); + points += QPointF(289.51401190033005, 145.54903057599236); + points += QPointF(285.1770288005626, 145.6959639947203); + points += QPointF(278.3617236899766, 146.6950293230864); + points += QPointF(271.14652259400714, 148.48714038237037); + points += QPointF(263.9194864200908, 150.92917578435245); + points += QPointF(257.2170705229372, 153.76755541765795); + points += QPointF(251.60582957396716, 156.6541701343772); + points += QPointF(247.78435692308207, 159.04593361720316); + points += QPointF(241.3885876220272, 164.12014968959915); + points += QPointF(236.47226924439926, 167.68896212834986); + points += QPointF(220.7012128062336, 176.43583903855628); + points += QPointF(209.5894888372958, 181.6299305429989); + points += QPointF(198.8701621522812, 185.51474135189684); + points += QPointF(188.2122212804039, 188.0080506184889); + points += QPointF(177.3148127107667, 188.81408257358973); + points += QPointF(166.19194469464537, 187.37324105698534); + points += QPointF(155.57420181410697, 183.17620217869953); + points += QPointF(146.72912660379956, 176.5077748886884); + points += QPointF(140.4165418057526, 168.5601760939351); + points += QPointF(136.398647544906, 160.4725908270882); + points += QPointF(134.00844184248987, 152.736031987575); + points += QPointF(132.67609691771358, 145.39573210082384); + points += QPointF(132.02477039749073, 138.2597894386109); + points += QPointF(131.93387537548404, 132.84913141002448); + points += QPointF(124.89904457045232, 138.11668139199287); + points += QPointF(115.8895831399309, 143.54689645077573); + points += QPointF(106.4111230253516, 147.88716086368487); + points += QPointF(96.50699490577813, 150.99747783054613); + points += QPointF(86.32454442321412, 152.7366302609282); + points += QPointF(76.11298204383012, 153.0205687205323); + points += QPointF(66.1751535607697, 151.8740677833447); + points += QPointF(56.79043276012441, 149.44132674047353); + points += QPointF(48.150859730789605, 145.94779600016403); + points += QPointF(40.340747704632996, 141.64039002708367); + points += QPointF(33.35598458760446, 136.7400113658245); + points += QPointF(27.139387101639755, 131.42053399597268); + points += QPointF(21.454249077112927, 125.64844566928473); + points += QPointF(14.297732218982075, 116.98023078208763); + points += QPointF(6.592092174102573, 105.03828991585031); + points += QPointF(0.43109819620648937, 92.75351406859683); + points += QPointF(-4.287700865002457, 80.50147704363812); + points += QPointF(-7.673598677574605, 68.33582707450634); + points += QPointF(-9.704701735666333, 56.0002075290815); + points += QPointF(-9.95133102840429, 42.85489720779573); + points += QPointF(-7.622895431362345, 31.027194419301413); + points += QPointF(-3.18150493921823, 21.10903158131186); + points += QPointF(11.491153250328935, 2.204598425196849); + + return points; +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VAbstractPiece::SumTrapezoids() const +{ + // Case3 checks that the method 'SumTrapezoids' returns negative value for three clockwise allocated points + // Case4 checks that the method 'SumTrapezoids' returns positive value for three counterclock-wise allocated points + // Case5 checks that the method 'SumTrapezoids' returns 0 for one point + Case3(); + Case4(); + Case5(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VAbstractPiece::PathRemoveLoop_data() const +{ + QTest::addColumn<QVector<QPointF>>("path"); + QTest::addColumn<QVector<QPointF>>("expect"); + + QVector<QPointF> path; + path << QPointF(10, 10); + path << QPointF(20, 10); + path << QPointF(20, 20); + path << QPointF(10, 20); + path << QPointF(10, 10); + QTest::newRow("Correct closed a path (four unique points)") << path << path; + +#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0) + path.remove(path.size() - 1); +#else + path.removeLast(); +#endif + QTest::newRow("Correct unclosed a path (four unique points)") << path << path; + + path.clear(); + path << QPointF(0, 10); + path << QPointF(10, 10); + path << QPointF(20, 10); + path << QPointF(20, 20); + path << QPointF(10, 20); + path << QPointF(0, 20); + path << QPointF(0, 10); + QTest::newRow("Correct closed a path (six unique points)") << path << path; + +#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0) + path.remove(path.size() - 1); +#else + path.removeLast(); +#endif + QTest::newRow("Correct unclosed a path (six unique points)") << path << path; + + path.clear(); + path << QPointF(20, 10); + path << QPointF(20, 20); + path << QPointF(10, 10); + path << QPointF(10, 20); + path << QPointF(20, 10); + + QVector<QPointF> res; + res << QPointF(20, 10); + res << QPointF(20, 20); + res << QPointF(15, 15); + res << QPointF(20, 10); + QTest::newRow("One loop, closed a path (four unique points)") << path << res; + +#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0) + path.remove(path.size() - 1); + res.remove(res.size() - 1); +#else + path.removeLast(); + res.removeLast(); +#endif + QTest::newRow("One loop, unclosed a path (four unique points)") << path << res; + + path.clear(); + path << QPointF(20, 10); + path << QPointF(20, 20); + path << QPointF(10, 10); + path << QPointF(0, 20); + path << QPointF(0, 10); + path << QPointF(10, 20); + path << QPointF(20, 10); + + res.clear(); + res << QPointF(20, 10); + res << QPointF(20, 20); + res << QPointF(15, 15); + res << QPointF(20, 10); + QTest::newRow("Two loops, closed a path (six unique points)") << path << res; + +#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0) + path.remove(path.size() - 1); + res.remove(res.size() - 1); +#else + path.removeLast(); + res.removeLast(); +#endif + QTest::newRow("Two loops, unclosed a path (six unique points)") << path << res; + + path.clear(); + path << QPointF(20, 10); + path << QPointF(20, 20); + path << QPointF(10, 10); + path << QPointF(0, 10); + path << QPointF(0, 20); + path << QPointF(10, 20); + path << QPointF(20, 10); + + res.clear(); + res << QPointF(20, 10); + res << QPointF(20, 20); + res << QPointF(15, 15); + res << QPointF(20, 10); + QTest::newRow("One loop, the first loop, closed a path (six unique points)") << path << res; + +#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0) + path.remove(path.size() - 1); + res.remove(res.size() - 1); +#else + path.removeLast(); + res.removeLast(); +#endif + QTest::newRow("One loop, the first loop, unclosed a path (six unique points)") << path << res; + + path.clear(); + path << QPointF(20, 10); + path << QPointF(20, 20); + path << QPointF(10, 20); + path << QPointF(0, 10); + path << QPointF(0, 20); + path << QPointF(10, 10); + path << QPointF(20, 10); + + res.clear(); + res << QPointF(20, 10); + res << QPointF(20, 20); + res << QPointF(10, 20); + res << QPointF(5, 15); + res << QPointF(10, 10); + res << QPointF(20, 10); + QTest::newRow("One loop, the second loop, closed a path (six unique points)") << path << res; + +#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0) + path.remove(path.size() - 1); + res.remove(res.size() - 1); +#else + path.removeLast(); + res.removeLast(); +#endif + QTest::newRow("One loop, the second loop, unclosed a path (six unique points)") << path << res; + + path.clear(); + path << QPointF(20, 10); + path << QPointF(20, 20); + path << QPointF(10, 20); + path << QPointF(20, 15); + path << QPointF(10, 10); + path << QPointF(20, 10); + QTest::newRow("Correct closed a path, point on line (four unique points)") << path << path; + +#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0) + path.remove(path.size() - 1); +#else + path.removeLast(); +#endif + QTest::newRow("Corect unclosed a path, point on line (four unique points)") << path << path; + + path.clear(); + path << QPointF(20, 10); + path << QPointF(10, 15); + path << QPointF(20, 20); + path << QPointF(10, 20); + path << QPointF(0, 20); + path << QPointF(10, 15); + path << QPointF(0, 10); + path << QPointF(10, 10); + path << QPointF(20, 10); + + QTest::newRow("Correct closed a path, point on line (six unique points)") << path << path; + +#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0) + path.remove(path.size() - 1); +#else + path.removeLast(); +#endif + QTest::newRow("Corect unclosed a path, point on line (six unique points)") << path << path; + + path.clear(); + path << QPointF(100.96979100571033, 1797.6153764073072); + path << QPointF(168.3888427659865, 1807.2395034187866); + path << QPointF(206.78076137364403, 1812.2910842036706); + path << QPointF(239.1630793382262, 1815.951361623424); + path << QPointF(267.5320085054171, 1818.4827543754482); + path << QPointF(293.9502505847841, 1820.144031725603); + path << QPointF(320.48133946750147, 1821.175819320443); + path << QPointF(364.5960626489172, 1822.0507669842166); + path << QPointF(400.66867742260206, 1822.488188976378); + path << QPointF(623.3126833308274, 1822.488188976378); + path << QPointF(653.5489038032683, 2162.6456692913384); + path << QPointF(570.545584385708, 2162.6456692913384); + path << QPointF(600.7818048581489, 1822.488188976378); + path << QPointF(1001.3385826771654, 1822.488188976378); + path << QPointF(1001.3385826771654, 2680.44094488189); + path << QPointF(-22.11646613738226, 2680.44094488189); + path << QPointF(100.96979100571033, 1797.6153764073072); + + res.clear(); + res << QPointF(100.96979100571033, 1797.6153764073072); + res << QPointF(168.3888427659865, 1807.2395034187866); + res << QPointF(206.78076137364403, 1812.2910842036706); + res << QPointF(239.1630793382262, 1815.951361623424); + res << QPointF(267.5320085054171, 1818.4827543754482); + res << QPointF(293.9502505847841, 1820.144031725603); + res << QPointF(320.48133946750147, 1821.175819320443); + res << QPointF(364.5960626489172, 1822.0507669842166); + res << QPointF(400.66867742260206, 1822.488188976378); + res << QPointF(1001.3385826771654, 1822.488188976378); + res << QPointF(1001.3385826771654, 2680.44094488189); + res << QPointF(-22.11646613738226, 2680.44094488189); + res << QPointF(100.96979100571033, 1797.6153764073072); + + // See the file "collection/bugs/Issue_#493.val" + QTest::newRow("Test case issue #493") << path << res; + + path.clear(); + path << QPointF(-685.2149804319953, -3568.7982439212556); + path << QPointF(-700.7415523087261, -3623.900571239949); + path << QPointF(-675.4694480627154, -3639.3631430823175); + path << QPointF(-684.7497934439581, -3631.3546395862268); + path << QPointF(-683.1356602239256, -3633.2868478418427); + path << QPointF(-686.8764821039574, -3627.927414863926); + path << QPointF(-684.7670104817863, -3631.587853202178); + path << QPointF(-682.2386030572435, -3636.8469922361573); + path << QPointF(-676.4708011186385, -3650.307478525872); + path << QPointF(-666.3050989871189, -3676.5286567894937); + path << QPointF(-654.0449409043066, -3710.198553447806); + path << QPointF(-640.1333287371614, -3750.0101920374505); + path << QPointF(-617.0729873733014, -3818.3303697354913); + path << QPointF(-583.8128392515604, -3920.9726624886944); + path << QPointF(-550.5307668482033, -4027.6970214479597); + path << QPointF(-527.4164674104215, -4104.7034088569535); + path << QPointF(-513.4302533332675, -4152.73879565781); + path << QPointF(-501.0373006826446, -4196.767296675345); + path << QPointF(-490.59311078227046, -4235.660899517831); + path << QPointF(-477.25724163384456, -4288.293444470835); + path << QPointF(-405.3839593893572, -4272.013803282615); + path << QPointF(-545.9786893428341, -3568.830152982464); + path << QPointF(-685.2149804319953, -3568.7982439212556); + + res.clear(); + res << QPointF(-685.2149804319953, -3568.7982439212556); + res << QPointF(-700.7415523087261, -3623.900571239949); + res << QPointF(-683.3457668881176, -3634.5440688767967); + res << QPointF(-682.2386030572435, -3636.8469922361573); + res << QPointF(-676.4708011186385, -3650.307478525872); + res << QPointF(-666.3050989871189, -3676.5286567894937); + res << QPointF(-654.0449409043066, -3710.198553447806); + res << QPointF(-640.1333287371614, -3750.0101920374505); + res << QPointF(-617.0729873733014, -3818.3303697354913); + res << QPointF(-583.8128392515604, -3920.9726624886944); + res << QPointF(-550.5307668482033, -4027.6970214479597); + res << QPointF(-527.4164674104215, -4104.7034088569535); + res << QPointF(-513.4302533332675, -4152.73879565781); + res << QPointF(-501.0373006826446, -4196.767296675345); + res << QPointF(-490.59311078227046, -4235.660899517831); + res << QPointF(-477.25724163384456, -4288.293444470835); + res << QPointF(-405.3839593893572, -4272.013803282615); + res << QPointF(-545.9786893428341, -3568.830152982464); + res << QPointF(-685.2149804319953, -3568.7982439212556); + + // See the file "collection/bugs/Issue_#515.val" + // Check a seam allowance path. + // The curve that causes the issue is the first in the list. + QTest::newRow("Test case issue #515. Big loop in seam allowance path.") << path << res; + + path.clear(); + path << QPointF(-449.6699112298347, -4243.2921010175705); + path << QPointF(-576.966638263205, -3606.6183279948636); + path << QPointF(-656.9465284876832, -3606.6183279948636); + path << QPointF(-656.5996104603414, -3606.6000783462687); + path << QPointF(-655.7439133016985, -3607.1236310612317); + path << QPointF(-654.129780081666, -3609.0558393168476); + path << QPointF(-651.3154902471701, -3613.939306009108); + path << QPointF(-647.8207651830382, -3621.2084054506768); + path << QPointF(-641.4701586077349, -3636.0289997859454); + path << QPointF(-630.9244502073004, -3663.23035747934); + path << QPointF(-618.4465305467888, -3697.4982896415795); + path << QPointF(-604.3873016966293, -3737.732371148936); + path << QPointF(-581.1891087215608, -3806.460957656939); + path << QPointF(-547.7936207285052, -3909.520915257629); + path << QPointF(-514.3891332445846, -4016.6378180116963); + path << QPointF(-491.17181635142833, -4093.9874129706236); + path << QPointF(-477.094588519539, -4142.335384784734); + path << QPointF(-464.5941701318652, -4186.745679830414); + path << QPointF(-454.0214632588362, -4226.117872983938); + + res.clear(); + res << QPointF(-449.6699112298347, -4243.2921010175705); + res << QPointF(-576.966638263205, -3606.6183279948636); + res << QPointF(-656.5697831440032, -3606.6183279948636); + res << QPointF(-655.7439133016985, -3607.1236310612317); + res << QPointF(-654.129780081666, -3609.0558393168476); + res << QPointF(-651.3154902471701, -3613.939306009108); + res << QPointF(-647.8207651830382, -3621.2084054506768); + res << QPointF(-641.4701586077349, -3636.0289997859454); + res << QPointF(-630.9244502073004, -3663.23035747934); + res << QPointF(-618.4465305467888, -3697.4982896415795); + res << QPointF(-604.3873016966293, -3737.732371148936); + res << QPointF(-581.1891087215608, -3806.460957656939); + res << QPointF(-547.7936207285052, -3909.520915257629); + res << QPointF(-514.3891332445846, -4016.6378180116963); + res << QPointF(-491.17181635142833, -4093.9874129706236); + res << QPointF(-477.094588519539, -4142.335384784734); + res << QPointF(-464.5941701318652, -4186.745679830414); + res << QPointF(-454.0214632588362, -4226.117872983938); + + // See the file "collection/bugs/Issue_#515.val" + // Check a seam allowance path. + // The curve that causes the issue is the last in the list. + QTest::newRow("Test case issue #515. Small loop in seam allowance path.") << path << res; + + path.clear(); + path << QPointF(1229.6503937007876, 937.6667716535435); + path << QPointF(203.08931117793543, 937.6667716535435); + path << QPointF(459.7677349767701, -2166.704563141019); + path << QPointF(1229.6503937007876, -1990.077167189857); + path << QPointF(1229.6503937007876, -555.2466141732282); + path << QPointF(920.1053824527112, -555.2466141732282); + path << QPointF(887.034516310979, -63.90803149606281); + path << QPointF(816.3607592795726, -63.908031496062826); + path << QPointF(780.7580397937137, -592.8627210002539); + path << QPointF(816.0241340748559, -1202.917917917055); + path << QPointF(887.3711415156957, -1202.917917917055); + path << QPointF(920.4420076574283, -630.8371653543306); + path << QPointF(1229.6503937007876, -630.8371653543306); + path << QPointF(1229.6503937007876, 937.6667716535435); + + res.clear(); + res << QPointF(1229.6503937007876, 937.6667716535435); + res << QPointF(203.08931117793543, 937.6667716535435); + res << QPointF(459.7677349767702, -2166.704563141019); + res << QPointF(1229.6503937007876, -1990.077167189857); + res << QPointF(1229.6503937007876, 937.6667716535435); + + // See the file "collection/bugs/Issue_#603.val" + // Point H1 is first in the list + QTest::newRow("Test issue 603.") << path << res; +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VAbstractPiece::PathRemoveLoop() const +{ + QFETCH(QVector<QPointF>, path); + QFETCH(QVector<QPointF>, expect); + + QVector<QPointF> res = VAbstractPiece::CheckLoops(path); + Comparison(res, expect); +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VAbstractPiece::PathLoopsCase_data() const +{ + QTest::addColumn<QVector<QPointF>>("path"); + QTest::addColumn<QVector<QPointF>>("expect"); + + QVector<QPointF> path; + path << QPointF(61.86670866141733, 446.92270866141735); + path << QPointF(650.6504606788366, 473.2192016666484); + path << QPointF(649.4426552757304, 480.5376973511262); + path << QPointF(646.5769170924987, 501.9977838630714); + path << QPointF(644.6382908004568, 523.6358081043691); + path << QPointF(643.4592698551749, 551.9888717674471); + path << QPointF(642.9134698671897, 584.1776423714557); + path << QPointF(643.1914832622404, 613.2382010061506); + path << QPointF(644.2199668178571, 639.3780275889782); + path << QPointF(645.9255773115714, 662.8046020373845); + path << QPointF(648.2349715209137, 683.7254042688159); + path << QPointF(651.0748062234152, 702.3479142007185); + path << QPointF(654.3717381966065, 718.8796117505387); + path << QPointF(658.0524242180187, 733.5279768357226); + path << QPointF(662.0435210651824, 746.5004893737165); + path << QPointF(666.2716855156286, 758.0046292819667); + path << QPointF(670.6635743468883, 768.2478764779191); + path << QPointF(677.400406718071, 781.7952098705392); + path << QPointF(691.6740007010135, 806.2608114022295); + path << QPointF(694.5877745571677, 810.2150054671212); + path << QPointF(699.9560352035193, 816.1706553153153); + path << QPointF(708.9007628091615, 824.0594196166176); + path << QPointF(719.3794725391945, 831.7499791040799); + path << QPointF(730.9568541500198, 839.0942359684872); + path << QPointF(743.1975973980386, 845.9440924006244); + path << QPointF(755.6663920396528, 852.1514505912763); + path << QPointF(767.9279278312633, 857.568212731228); + path << QPointF(779.5468945292718, 862.046281011264); + path << QPointF(790.0879818900794, 865.4375576221694); + path << QPointF(799.115879670088, 867.5939447547289); + path << QPointF(804.5608128209333, 868.2650594004886); + path << QPointF(807.5317661719646, 868.2782441618697); + path << QPointF(809.8795601157717, 867.8994015359809); + path << QPointF(811.5497808719051, 867.1100192966705); + path << QPointF(812.4880146599148, 865.8915852177861); + path << QPointF(812.6398476993509, 864.2255870731761); + path << QPointF(811.9508662097637, 862.0935126366886); + path << QPointF(810.3666564107034, 859.4768496821717); + path << QPointF(806.3216663321919, 854.66911491981); + path << QPointF(802.0871811023624, 850.6707401574804); + path << QPointF(799.4598981526765, 850.6707401574804); + path << QPointF(802.0871811023624, 1653.9337322834645); + path << QPointF(61.86670866141733, 1653.9337322834645); + + QVector<QPointF> res; + res << QPointF(61.86670866141733, 446.92270866141735); + res << QPointF(650.6504606788366, 473.2192016666484); + res << QPointF(649.4426552757304, 480.5376973511262); + res << QPointF(646.5769170924987, 501.9977838630714); + res << QPointF(644.6382908004568, 523.6358081043691); + res << QPointF(643.4592698551749, 551.9888717674471); + res << QPointF(642.9134698671897, 584.1776423714557); + res << QPointF(643.1914832622404, 613.2382010061506); + res << QPointF(644.2199668178571, 639.3780275889782); + res << QPointF(645.9255773115714, 662.8046020373845); + res << QPointF(648.2349715209137, 683.7254042688159); + res << QPointF(651.0748062234152, 702.3479142007185); + res << QPointF(654.3717381966065, 718.8796117505387); + res << QPointF(658.0524242180187, 733.5279768357226); + res << QPointF(662.0435210651824, 746.5004893737165); + res << QPointF(666.2716855156286, 758.0046292819667); + res << QPointF(670.6635743468883, 768.2478764779191); + res << QPointF(677.400406718071, 781.7952098705392); + res << QPointF(691.6740007010135, 806.2608114022295); + res << QPointF(694.5877745571677, 810.2150054671212); + res << QPointF(699.9560352035193, 816.1706553153153); + res << QPointF(708.9007628091615, 824.0594196166176); + res << QPointF(719.3794725391945, 831.7499791040799); + res << QPointF(730.9568541500198, 839.0942359684872); + res << QPointF(743.1975973980386, 845.9440924006244); + res << QPointF(755.6663920396528, 852.1514505912763); + res << QPointF(767.9279278312633, 857.568212731228); + res << QPointF(779.5468945292718, 862.046281011264); + res << QPointF(790.0879818900794, 865.4375576221694); + res << QPointF(799.115879670088, 867.5939447547289); + res << QPointF(799.5154110117976, 867.6431889469776); + res << QPointF(802.0871811023624, 1653.9337322834645); + res << QPointF(61.86670866141733, 1653.9337322834645); + + // See file "collection/bugs/Issue_#609_case1.val" + // Clear a main path. Bound intersection. External loop. Outside a loop. Start point Ф1. + QTest::newRow("Issue 609. Case1a") << path << res; + + path.clear(); + path << QPointF(-365.68188649000314, -2143.126579528016); + path << QPointF(-195.75487873249062, -2116.7935769656237); + path << QPointF(-195.75487873249062, -1836.0319480765759); + path << QPointF(-233.39027086052477, -1838.4849618976993); + path << QPointF(-231.15080237392075, -1855.5915146519483); + path << QPointF(-225.84473077299972, -1889.4811404382626); + path << QPointF(-219.39861487985402, -1922.986407729537); + path << QPointF(-211.6695159016421, -1955.9990283342697); + path << QPointF(-204.87723909172885, -1980.439660924953); + path << QPointF(-199.87970909142098, -1996.6270828437923); + path << QPointF(-194.48099536000245, -2012.6451713592935); + path << QPointF(-188.65032933731845, -2028.5246588116781); + path << QPointF(-182.36812965707693, -2044.2602109802488); + path << QPointF(-175.61499879935675, -2059.8462252736344); + path << QPointF(-168.3717693169516, -2075.2768492268588); + path << QPointF(-160.6424572210866, -2090.5008865466684); + path << QPointF(-150.22847685877994, -2109.7385074212525); + path << QPointF(194.23861004296444, -2056.3576305273214); + path << QPointF(302.4787663409577, -1301.003761061316); + path << QPointF(279.86810151275455, -1288.330749878147); + path << QPointF(-641.7062267185897, -2051.118466118487); + path << QPointF(-365.68188649000314, -2143.126579528016); + + res.clear(); + res << QPointF(-365.68188649000314, -2143.126579528016); + res << QPointF(-195.75487873249062, -2116.7935769656237); + res << QPointF(-195.75487873249062, -2008.8655346469059); + res << QPointF(-194.48099536000245, -2012.6451713592935); + res << QPointF(-188.65032933731845, -2028.5246588116781); + res << QPointF(-182.36812965707693, -2044.2602109802488); + res << QPointF(-175.61499879935675, -2059.8462252736344); + res << QPointF(-168.3717693169516, -2075.2768492268588); + res << QPointF(-160.6424572210866, -2090.5008865466684); + res << QPointF(-150.22847685877994, -2109.7385074212525); + res << QPointF(194.23861004296444, -2056.3576305273214); + res << QPointF(302.4787663409577, -1301.003761061316); + res << QPointF(279.86810151275455, -1288.330749878147); + res << QPointF(-641.7062267185897, -2051.118466118487); + res << QPointF(-365.68188649000314, -2143.126579528016); + + // See file "collection/bugs/Issue_#609_case2.val" + // Clear an equdistant. Bound intersection. Internal loop. Outside a loop. Start point А2. + QTest::newRow("Issue 609. Case2b") << path << res; + + path.clear(); + path << QPointF(0, 10); + path << QPointF(5, 10); + path << QPointF(2.5, 15); + path << QPointF(7.5, 15); + path << QPointF(5, 10); + path << QPointF(10, 10); + path << QPointF(10, 20); + path << QPointF(0, 20); + path << QPointF(0, 10); + + QTest::newRow("Internal loop. Valid case.") << path << path; + + path.clear(); + path << QPointF(0, 10); + path << QPointF(5, 10); + path << QPointF(7.5, 15); + path << QPointF(2.5, 15); + path << QPointF(5, 10); + path << QPointF(10, 10); + path << QPointF(10, 20); + path << QPointF(0, 20); + path << QPointF(0, 10); + + res.clear(); + res << QPointF(0, 10); + res << QPointF(10, 10); + res << QPointF(10, 20); + res << QPointF(0, 20); + res << QPointF(0, 10); + + QTest::newRow("Internal loop. Invalid case.") << path << res; + + path.clear(); + path << QPointF(0, 10); + path << QPointF(5, 10); + path << QPointF(0, 0); + path << QPointF(10, 0); + path << QPointF(5, 10); + path << QPointF(10, 10); + path << QPointF(10, 20); + path << QPointF(0, 20); + path << QPointF(0, 10); + + QTest::newRow("External loop. Valid case.") << path << path; + + path.clear(); + path << QPointF(0, 10); + path << QPointF(5, 10); + path << QPointF(10, 0); + path << QPointF(0, 0); + path << QPointF(5, 10); + path << QPointF(10, 10); + path << QPointF(10, 20); + path << QPointF(0, 20); + path << QPointF(0, 10); + + res.clear(); + res << QPointF(0, 10); + res << QPointF(10, 10); + res << QPointF(10, 20); + res << QPointF(0, 20); + res << QPointF(0, 10); + + QTest::newRow("External loop. Invalid case.") << path << res; +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VAbstractPiece::PathLoopsCase() const +{ + QFETCH(QVector<QPointF>, path); + QFETCH(QVector<QPointF>, expect); + + const QVector<QPointF> res = VAbstractPiece::CheckLoops(path); + Comparison(res, expect); +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VAbstractPiece::BrokenDetailEquidistant_data() const +{ + QTest::addColumn<QVector<VSAPoint>>("points"); + QTest::addColumn<qreal>("width"); + QTest::addColumn<QVector<QPointF>>("ekvOrig"); + + // For more details see the file "collection/bugs/GAVAUDAN Laure - corsage - figure 4.val". + // We will test only one detail. The second require too accurate data that we cannot get from debuger. + // The test check an open equdistant of correct detail. + QVector<VSAPoint> points;// Input points. + + qreal width = 37.795275590551185; // seam allowance width + + VSAPoint point = VSAPoint(787.5835464566929, 1701.3138897637796); + point.SetSAAfter(width); + point.SetSABefore(0); + points.append(point); + + point = VSAPoint(863.1740976377953, 1701.3138897637796); + point.SetSAAfter(width); + point.SetSAAfter(width); + points.append(point); + + points.append(VSAPoint(938.7646488188976, 1701.3138897637796)); + points.append(VSAPoint(928.6149944255945, 1732.4440762118775)); + points.append(VSAPoint(910.0209054382323, 1792.3369946802652)); + points.append(VSAPoint(893.3643210561819, 1849.7845240486258)); + points.append(VSAPoint(878.5243977752426, 1905.2261712206746)); + points.append(VSAPoint(865.3802920912136, 1959.1014431001254)); + points.append(VSAPoint(853.8111604998944, 2011.8498465906928)); + points.append(VSAPoint(843.6961594970844, 2063.910888596092)); + points.append(VSAPoint(834.9144455785826, 2115.7240760200366)); + points.append(VSAPoint(827.3451752401882, 2167.7289157662426)); + points.append(VSAPoint(820.8675049777007, 2220.364914738423)); + points.append(VSAPoint(815.3605912869193, 2274.0715798402925)); + points.append(VSAPoint(810.703590663643, 2329.2884179755656)); + points.append(VSAPoint(806.7756596036716, 2386.454936047957)); + points.append(VSAPoint(803.455954602804, 2446.0106409611817)); + points.append(VSAPoint(800.6236321568394, 2508.395039618954)); + points.append(VSAPoint(798.1578487615775, 2574.047638924988)); + points.append(VSAPoint(797.0323653543306, 2608.4005039370077)); + points.append(VSAPoint(929.3158299212598, 2608.4005039370077)); + points.append(VSAPoint(927.9285659612306, 2548.9599884455793)); + points.append(VSAPoint(925.157717598664, 2463.8329634071292)); + points.append(VSAPoint(922.7222742526749, 2408.6782012856274)); + points.append(VSAPoint(919.6220036804666, 2354.5469017384876)); + points.append(VSAPoint(915.706969354324, 2301.1170261784787)); + points.append(VSAPoint(910.8272347465313, 2248.066536018368)); + points.append(VSAPoint(904.8328633293736, 2195.073392670922)); + points.append(VSAPoint(897.5739185751353, 2141.8155575489095)); + points.append(VSAPoint(888.9004639561011, 2087.9709920650976)); + points.append(VSAPoint(878.6625629445558, 2033.2176576322527)); + points.append(VSAPoint(866.7102790127839, 1977.233515663143)); + points.append(VSAPoint(852.8936756330698, 1919.696527570536)); + points.append(VSAPoint(837.0628162776984, 1860.284654767199)); + points.append(VSAPoint(819.0677644189545, 1798.675858665899)); + points.append(VSAPoint(798.7585835291225, 1734.548100679404)); + points.append(VSAPoint(787.5835464566929, 1701.3138897637796)); + + point = VSAPoint(797.0323653543306, 2608.4005039370077); + point.SetSAAfter(0); + point.SetSABefore(width); + points.append(point); + + QVector<QPointF> ekvOrig; + ekvOrig.append(QPointF(735.0001191244485, 1663.5186141732283)); + ekvOrig.append(QPointF(990.8407796109454, 1663.5186141732283)); + ekvOrig.append(QPointF(964.6314897747087, 1743.9055956070622)); + ekvOrig.append(QPointF(946.222111945205, 1803.203545947388)); + ekvOrig.append(QPointF(929.7733236875301, 1859.9343993344141)); + ekvOrig.append(QPointF(915.1430683369846, 1914.5927314447797)); + ekvOrig.append(QPointF(902.2033477151627, 1967.6302665424967)); + ekvOrig.append(QPointF(890.8261161082305, 2019.5037195040304)); + ekvOrig.append(QPointF(880.8841829577946, 2070.673996127427)); + ekvOrig.append(QPointF(872.2520522462703, 2121.604624314014)); + ekvOrig.append(QPointF(864.8064761358401, 2172.759620123457)); + ekvOrig.append(QPointF(864.2562272534083, 2177.2308109121955)); + ekvOrig.append(QPointF(860.1867773842832, 2147.3738416825267)); + ekvOrig.append(QPointF(851.6617474319463, 2094.450692409028)); + ekvOrig.append(QPointF(841.5996933370075, 2040.6378051462616)); + ekvOrig.append(QPointF(829.8479530577714, 1985.5930036729653)); + ekvOrig.append(QPointF(816.2523082919595, 1928.9761616385213)); + ekvOrig.append(QPointF(800.6574868367429, 1870.4501190599349)); + ekvOrig.append(QPointF(782.9077406929495, 1809.6811643713463)); + ekvOrig.append(QPointF(762.8278965797896, 1746.2775544138444)); + ekvOrig.append(QPointF(735.0001191244485, 1663.5186141732283)); + + QTest::newRow("GAVAUDAN Laure.") << points << width << ekvOrig; + + width = 11.338582677165354; + + points.clear(); + point = VSAPoint(97.33089106412862, -223.03306117556497); + point.SetSAAfter(width); + point.SetSABefore(0); + points.append(point); + + point = VSAPoint(990.7494050554426, 2.819093995045); + point.SetSAAfter(width); + point.SetSABefore(width); + points.append(point); + + point = VSAPoint(908.3966357321774, 379.5839357215547); + point.SetSAAfter(width); + point.SetSABefore(width); + points.append(point); + + point = VSAPoint(-135.41154226686143, 697.6417881399819); + point.SetSAAfter(0); + point.SetSABefore(width); + points.append(point); + + ekvOrig.clear(); + ekvOrig.append(QPointF(100.10981413873267, -234.02583351343978)); + ekvOrig.append(QPointF(1004.1704360325447, -5.483401649771952)); + ekvOrig.append(QPointF(918.0553412376563, 388.4941212347381)); + ekvOrig.append(QPointF(-138.65807550610091, 710.4843173601864)); + ekvOrig.append(QPointF(100.10981413873267, -234.02583351343978)); + + // See the file "collection/bugs/Issue_#604.val" (since 0.5.0) + QTest::newRow("Issue #604.") << points << width << ekvOrig; +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VAbstractPiece::BrokenDetailEquidistant() const +{ + QFETCH(QVector<VSAPoint>, points); + QFETCH(qreal, width); + QFETCH(QVector<QPointF>, ekvOrig); + + const QVector<QPointF> ekv = VAbstractPiece::Equidistant(points, width);// Take result + + // Begin comparison + Comparison(ekv, ekvOrig); +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VAbstractPiece::CorrectEquidistantPoints_data() const +{ + // See file zigzag.val + QTest::addColumn<QVector<QPointF>>("points"); + QTest::addColumn<QVector<QPointF>>("expect"); + QTest::addColumn<bool>("removeFirstAndLast"); + + QVector<QPointF> points; + points.append(QPointF(-741.7894588053705, 1065.7336503858917)); + points.append(QPointF(-759.696551643576, -115.81420543069257)); + points.append(QPointF(-278.17249953019325, -217.1037453126913)); + points.append(QPointF(-244.64654130659474, 1077.9548221866635)); + points.append(QPointF(-741.7894588053705, 1065.7336503858917)); + + QVector<QPointF> expect; + expect.append(QPointF(-741.7894588053705, 1065.7336503858917)); + expect.append(QPointF(-759.696551643576, -115.81420543069257)); + expect.append(QPointF(-278.17249953019325, -217.1037453126913)); + expect.append(QPointF(-244.64654130659474, 1077.9548221866635)); + expect.append(QPointF(-741.7894588053705, 1065.7336503858917)); + + QTest::newRow("Closed seam allowance. Last point equal first.") << points << expect << false; + + points.clear(); + points.append(QPointF(-704.5489521643801, 1028.8424328418016)); + points.append(QPointF(-721.4335720065426, -85.24049234531904)); + points.append(QPointF(-707.7852899705758, 755.7064514429209)); + points.append(QPointF(-721.4335720065426, -85.24049234531904)); + points.append(QPointF(-314.78124296268265, -170.7806167067443)); + points.append(QPointF(-283.4579031023758, 1039.1940357173805)); + + expect.clear(); + expect.append(QPointF(-704.5489521643801, 1028.8424328418016)); + expect.append(QPointF(-721.4335720065426, -85.24049234531904)); + expect.append(QPointF(-314.78124296268265, -170.7806167067443)); + expect.append(QPointF(-283.4579031023758, 1039.1940357173805)); + + QTest::newRow("Clearing bad main path.") << points << expect << true; +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VAbstractPiece::CorrectEquidistantPoints() const +{ + QFETCH(QVector<QPointF>, points); + QFETCH(QVector<QPointF>, expect); + QFETCH(bool, removeFirstAndLast); + + const QVector<QPointF> res = VAbstractPiece::CorrectEquidistantPoints(points, removeFirstAndLast); + + // Begin comparison + Comparison(res, expect); +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VAbstractPiece::TestCorrectEquidistantPoints_data() +{ + QTest::addColumn<QVector<QPointF>>("before"); + QTest::addColumn<QVector<QPointF>>("expect"); + + QVector<QPointF> before; + before << QPointF(30.0, 39.999874015748034); + before << QPointF(785.9055118110236, 39.999874015748034); + before << QPointF(785.9055118110236, 3819.527433070866); + before << QPointF(483.54330708661416, 3819.527433070866); + before << QPointF(483.54330708661416, 1929.763653543307); + before << QPointF(407.9527559055629, 984.8817637795973); + before << QPointF(407.9527559055118, 1929.763653543307); + before << QPointF(407.9527559055118, 3819.527433070866); + before << QPointF(30.0, 3819.527433070866); + + QVector<QPointF> expect; + expect << QPointF(30.0, 39.999874015748034); + expect << QPointF(785.9055118110236, 39.999874015748034); + expect << QPointF(785.9055118110236, 3819.527433070866); + expect << QPointF(483.54330708661416, 3819.527433070866); + expect << QPointF(483.54330708661416, 1929.763653543307); + expect << QPointF(407.9527559055629, 984.8817637795973); + expect << QPointF(407.9527559055118, 3819.527433070866); + expect << QPointF(30.0, 3819.527433070866); + + QTest::newRow("Test case issue #548") << before << expect; +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VAbstractPiece::TestCorrectEquidistantPoints() const +{ + QFETCH(QVector<QPointF>, before); + QFETCH(QVector<QPointF>, expect); + + QVector<QPointF> after = VAbstractPiece::CorrectEquidistantPoints(before); + Comparison(after, expect); +} + +#ifndef Q_OS_WIN +//--------------------------------------------------------------------------------------------------------------------- +void TST_VAbstractPiece::PossibleInfiniteClearLoops_data() const +{ + QTest::addColumn<QVector<QPointF>>("path"); + QTest::addColumn<QVector<QPointF>>("expect"); + + QVector<QPointF> path; + path << QPointF(-670.6449010946802, 4046.36220472441); + path << QPointF(-1025.9051277126944, 4046.36220472441); + path << QPointF(-1026.4460203880594, 4010.5247429150854); + path << QPointF(-1027.2972172274538, 3924.202328582098); + path << QPointF(-1028.1383921346433, 3768.5948526129496); + path << QPointF(-1028.5065585022217, 3521.575730066707); + path << QPointF(-1028.2712136539103, 3252.2436039362233); + path << QPointF(-1027.2910122410117, 2850.1024469719814); + path << QPointF(-1025.9446023682538, 2439.350819630564); + path << QPointF(-1025.8983315247287, 2338.629525677473); + path << QPointF(-1025.3536572186458, 2309.970015878699); + path << QPointF(-1024.2100836932389, 2281.714612342931); + path << QPointF(-1022.5102766116828, 2253.846781520112); + path << QPointF(-1020.2969016371525, 2226.349989860186); + path << QPointF(-1017.6126244328227, 2199.207703813094); + path << QPointF(-1014.5001106618688, 2172.403389828782); + path << QPointF(-1011.0020259874652, 2145.9205143571917); + path << QPointF(-1005.1601480132764, 2106.7277181407126); + path << QPointF(-996.3625412018714, 2055.4921956731814); + path << QPointF(-986.7906327138169, 2005.2448233555149); + path << QPointF(-976.785747854512, 1955.8533327872588); + path << QPointF(-961.6606968634906, 1883.0158867454916); + path << QPointF(-947.5864881030896, 1811.4914675744105); + path << QPointF(-939.2629508127773, 1764.2008199992524); + path << QPointF(-933.8852659113251, 1728.8707137815559); + path << QPointF(-930.742733377741, 1705.3464944792456); + path << QPointF(-928.0252775410311, 1681.829576238578); + path << QPointF(-925.7755640643697, 1658.3034255094963); + path << QPointF(-924.036258610932, 1634.7515087419433); + path << QPointF(-922.850026843893, 1611.1572923858625); + path << QPointF(-922.2595344264276, 1587.504242891197); + path << QPointF(-922.3074470217107, 1563.7758267078902); + path << QPointF(-922.613405031688, 1551.8740157480315); + path << QPointF(-960.4086806222392, 841.3228346456693); + path << QPointF(-954.9336313684444, 841.5464781141166); + path << QPointF(-944.0363771538431, 841.3102753632543); + path << QPointF(-933.2160856340209, 840.291423017261); + path << QPointF(-922.4878118569704, 838.5316299985567); + path << QPointF(-911.8666108706839, 836.0726052295611); + path << QPointF(-901.3675377231535, 832.9560576326933); + path << QPointF(-891.005647462372, 829.2236961303737); + path << QPointF(-880.7959951363317, 824.9172296450213); + path << QPointF(-870.7536357930251, 820.0783670990559); + path << QPointF(-860.893624480444, 814.7488174148973); + path << QPointF(-851.2310162465817, 808.9702895149649); + path << QPointF(-841.7808661394299, 802.7844923216785); + path << QPointF(-832.5582292069812, 796.2331347574575); + path << QPointF(-823.578160497228, 789.3579257447218); + path << QPointF(-810.5607800373014, 778.5565764202543); + path << QPointF(-794.2367125298769, 763.3635567727296); + path << QPointF(-779.1539087770976, 747.6258919346988); + path << QPointF(-765.4328091629026, 731.6772532855191); + path << QPointF(-753.193854071231, 715.8513122045474); + path << QPointF(-742.557483886022, 700.4817400711408); + path << QPointF(-733.644138991215, 685.9022082646563); + path << QPointF(-726.5742597707488, 672.446388164451); + path << QPointF(-721.4682866085625, 660.447951149882); + path << QPointF(-718.6229063234249, 651.1532303788147); + path << QPointF(-716.6036430255488, 642.9038041285014); + path << QPointF(-714.137568179324, 630.1235656609365); + path << QPointF(-711.8605525364693, 612.2344502588126); + path << QPointF(-710.4560555432737, 593.4222205889721); + path << QPointF(-709.4234847119759, 563.5940176156308); + path << QPointF(-708.952111561728, 520.4666582691573); + path << QPointF(-708.4401766852314, 497.3858267716535); + path << QPointF(-400.92922424489655, 469.03937007874015); + path << QPointF(-708.4401766852314, 440.6929133858268); + path << QPointF(-708.7078446526739, 341.66122584661264); + path << QPointF(-709.3427685457568, 299.60322373665383); + path << QPointF(-710.6909230403871, 257.048095841136); + path << QPointF(-713.0251717477311, 214.57984397612822); + path << QPointF(-715.632864794307, 183.1716335401434); + path << QPointF(-717.7953694429818, 162.55016633308693); + path << QPointF(-720.3578834261159, 142.27891915519677); + path << QPointF(-723.3545146951046, 122.43089223348173); + path << QPointF(-725.0465030138121, 112.71059563115871); + path << QPointF(-219.59055118110237, -35.52755905511811); + path << QPointF(-218.99352387527398, -33.21125072212394); + path << QPointF(-217.35724543521775, -28.699086141666157); + path << QPointF(-215.20035586903225, -24.33136255454731); + path << QPointF(-212.53403014110648, -20.10796717265881); + path << QPointF(-209.36944321582945, -16.02878720789205); + path << QPointF(-205.71777005759026, -12.093709872138447); + path << QPointF(-201.59018563077785, -8.302622377289406); + path << QPointF(-196.99786489978123, -4.65541193523633); + path << QPointF(-189.3170483291933, 0.5638303631539586); + path << QPointF(-177.47808861476295, 6.996342387787443); + path << QPointF(-163.981333042598, 12.855376387191757); + path << QPointF(-148.91618132781048, 18.141834666235646); + path << QPointF(-132.37203318551252, 22.856619529787864); + path << QPointF(-114.43828833081622, 27.00063328271716); + path << QPointF(-95.20434647883366, 30.574778229892296); + path << QPointF(-74.75960734467688, 33.57995667618201); + path << QPointF(-53.193470643458, 36.01707092645505); + path << QPointF(-30.595336090289106, 37.887023285580185); + path << QPointF(-7.0546034002822875, 39.19071605842615); + path << QPointF(17.339327711450373, 39.929051549861704); + path << QPointF(29.858267716535437, 40.06299212598426); + path << QPointF(-45.73228346456693, 1589.6692913385828); + path << QPointF(-45.73228346456693, 4046.36220472441); + path << QPointF(-297.70078740157487, 4046.36220472441); + path << QPointF(-297.70078740157487, 2118.8031496062995); + path << QPointF(-222.1102362204725, 1589.6692913385828); + path << QPointF(-297.70078740157487, 1060.535433070866); + path << QPointF(-373.2913385826772, 1589.6692913385828); + path << QPointF(-297.70078740157487, 2118.8031496062995); + path << QPointF(-297.70078740157487, 4046.36220472441); + path << QPointF(-670.6449010946802, 4046.36220472441); + path << QPointF(-670.6449010946802, 2024.3149606299214); + path << QPointF(-622.7555214134819, 1570.7716535433071); + path << QPointF(-670.6449010946802, 1117.2283464566929); + path << QPointF(-718.5342807758785, 1570.7716535433071); + path << QPointF(-670.6449010946802, 2024.3149606299214); + + QVector<QPointF> expect; + expect << QPointF(-670.6449010946802, 4046.36220472441); + expect << QPointF(-670.6449010946802, 4046.36220472441); + expect << QPointF(-670.6449010946802, 2024.3149606299214); + expect << QPointF(-670.6449010946802, 2024.3149606299214); + expect << QPointF(-670.6449010946802, 2024.3149606299214); + + // See the file "collection/bugs/possible_inf_loop.val" + QTest::newRow("Possible infinite loop") << path << expect; +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VAbstractPiece::PossibleInfiniteClearLoops() const +{ + QFETCH(QVector<QPointF>, path); + QFETCH(QVector<QPointF>, expect); + + QVector<QPointF> res = VAbstractPiece::CheckLoops(path); + Comparison(res, expect); +} +#endif //#ifndef Q_OS_WIN + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VAbstractPiece::Case3() const +{ + const QVector<QPointF> points = InputPointsCase3a(); // Input points. + + const qreal result = VAbstractPiece::SumTrapezoids(points); + QVERIFY(result < 0); +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VAbstractPiece::Case4() const +{ + const QVector<QPointF> points = InputPointsCase4a(); // Input points. + + const qreal result = VAbstractPiece::SumTrapezoids(points); + QVERIFY(result > 0); +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VAbstractPiece::Case5() const +{ + const QVector<QPointF> points = InputPointsCase5a(); // Input points. + + const qreal result = VAbstractPiece::SumTrapezoids(points); + QVERIFY(qFuzzyIsNull(result)); +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<VSAPoint> TST_VAbstractPiece::InputPointsIssue298Case1() const +{ + QVector<VSAPoint> points; + + points += VSAPoint(35, 39.9999); + points += VSAPoint(412.953, 39.9999); + points += VSAPoint(417.135, 417.929); + points += VSAPoint(417.135, 417.929); + points += VSAPoint(408.797, 405.589); + points += VSAPoint(390.909, 377.669); + points += VSAPoint(362.315, 330.86); + points += VSAPoint(323.075, 264.247); + points += VSAPoint(286.15, 201.448); + points += VSAPoint(262.477, 162.745); + points += VSAPoint(249.22, 142.455); + points += VSAPoint(241.092, 131.261); + points += VSAPoint(236.545, 125.75); + points += VSAPoint(232.808, 122.058); + points += VSAPoint(230.6, 120.629); + points += VSAPoint(229.393, 120.277); + points += VSAPoint(228.421, 120.456); + points += VSAPoint(227.69, 121.185); + points += VSAPoint(227.033, 123.272); + points += VSAPoint(227.112, 128.232); + points += VSAPoint(228.29, 135.699); + points += VSAPoint(230.625, 145.81); + points += VSAPoint(234.173, 158.703); + points += VSAPoint(241.73, 183.168); + points += VSAPoint(248.796, 204.144); + points += VSAPoint(248.796, 204.144); + points += VSAPoint(251.528, 212.406); + points += VSAPoint(255.482, 227.075); + points += VSAPoint(257.717, 239.591); + points += VSAPoint(258.279, 247.554); + points += VSAPoint(258.203, 252.278); + points += VSAPoint(257.756, 256.51); + points += VSAPoint(256.949, 260.264); + points += VSAPoint(255.795, 263.547); + points += VSAPoint(254.308, 266.372); + points += VSAPoint(252.501, 268.749); + points += VSAPoint(250.385, 270.688); + points += VSAPoint(247.974, 272.201); + points += VSAPoint(245.281, 273.296); + points += VSAPoint(242.319, 273.986); + points += VSAPoint(239.1, 274.28); + points += VSAPoint(233.846, 274.05); + points += VSAPoint(226.022, 272.393); + points += VSAPoint(217.402, 269.345); + points += VSAPoint(208.09, 264.991); + points += VSAPoint(198.186, 259.414); + points += VSAPoint(187.795, 252.7); + points += VSAPoint(177.019, 244.933); + points += VSAPoint(165.96, 236.197); + points += VSAPoint(154.721, 226.576); + points += VSAPoint(143.405, 216.157); + points += VSAPoint(132.113, 205.022); + points += VSAPoint(120.95, 193.257); + points += VSAPoint(110.017, 180.946); + points += VSAPoint(99.4167, 168.174); + points += VSAPoint(89.2522, 155.024); + points += VSAPoint(79.626, 141.582); + points += VSAPoint(70.6405, 127.933); + points += VSAPoint(62.3985, 114.16); + points += VSAPoint(55.0025, 100.348); + points += VSAPoint(48.5551, 86.5823); + points += VSAPoint(43.159, 72.9466); + points += VSAPoint(38.9167, 59.5258); + points += VSAPoint(35.9309, 46.4042); + points += VSAPoint(35, 39.9999); + + return points; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<QPointF> TST_VAbstractPiece::OutputPointsIssue298Case1() const +{ + QVector<QPointF> points; + points += QPointF(-52.3724798442221, -35.5907); + points += QPointF(487.7117748779425, -35.5907); + points += QPointF(493.3432017362585, 473.32371517914754); + points += QPointF(385.98559977345093, 506.8445742667132); + points += QPointF(345.64704646524604, 447.1446764706891); + points += QPointF(326.82411403464874, 417.76541252489994); + points += QPointF(297.4844355409708, 369.73572061014266); + points += QPointF(280.35686644039447, 340.63425704493835); + points += QPointF(268.2336759982877, 345.56366422433183); + points += QPointF(254.38869069377708, 348.78886336684104); + points += QPointF(240.8928242225697, 350.0214774527481); + points += QPointF(224.29748398011193, 349.2949970081793); + points += QPointF(205.50330859478322, 345.31468660256957); + points += QPointF(188.72568121178054, 339.38217984347546); + points += QPointF(173.487571907339, 332.2573164509149); + points += QPointF(159.09346043909582, 324.15190856941325); + points += QPointF(145.1562378134811, 315.1465661857729); + points += QPointF(131.46917217609203, 305.28136213922494); + points += QPointF(117.9345600633141, 294.589765121662); + points += QPointF(104.5254725457231, 283.11108988305153); + points += QPointF(91.25156649455745, 270.88938370179534); + points += QPointF(78.14294517511125, 257.9630200468154); + points += QPointF(65.25722328495372, 244.3823949426573); + points += QPointF(52.65759889494496, 230.19470850111355); + points += QPointF(40.412239584772514, 215.4406233233806); + points += QPointF(28.600027181043494, 200.15894757848054); + points += QPointF(17.304913602921047, 184.38648111018338); + points += QPointF(6.6105681133211736, 168.14173996194046); + points += QPointF(-3.3897319816688407, 151.43048866270516); + points += QPointF(-12.592267484961765, 134.24479093805914); + points += QPointF(-20.880547263016442, 116.54866956498358); + points += QPointF(-28.111192294561146, 98.27715746242171); + points += QPointF(-34.098213657706594, 79.33681465062016); + points += QPointF(-38.441724866417594, 60.24852451858777); + points += QPointF(-52.3724798442221, -35.5907); + + return points; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<VSAPoint> TST_VAbstractPiece::InputPointsIssue298Case2() const +{ + QVector<VSAPoint> points; + + points += VSAPoint(35, 39.9999); + points += VSAPoint(35, 39.9999); + points += VSAPoint(35.9309, 46.4042); + points += VSAPoint(38.9167, 59.5258); + points += VSAPoint(43.159, 72.9466); + points += VSAPoint(48.5551, 86.5823); + points += VSAPoint(55.0025, 100.348); + points += VSAPoint(62.3985, 114.16); + points += VSAPoint(70.6405, 127.933); + points += VSAPoint(79.626, 141.582); + points += VSAPoint(89.2522, 155.024); + points += VSAPoint(99.4167, 168.174); + points += VSAPoint(110.017, 180.946); + points += VSAPoint(120.95, 193.257); + points += VSAPoint(132.113, 205.022); + points += VSAPoint(143.405, 216.157); + points += VSAPoint(154.721, 226.576); + points += VSAPoint(165.96, 236.197); + points += VSAPoint(177.019, 244.933); + points += VSAPoint(187.795, 252.7); + points += VSAPoint(198.186, 259.414); + points += VSAPoint(208.09, 264.991); + points += VSAPoint(217.402, 269.345); + points += VSAPoint(226.022, 272.393); + points += VSAPoint(233.846, 274.05); + points += VSAPoint(239.1, 274.28); + points += VSAPoint(242.319, 273.986); + points += VSAPoint(245.281, 273.296); + points += VSAPoint(247.974, 272.201); + points += VSAPoint(250.385, 270.688); + points += VSAPoint(252.501, 268.749); + points += VSAPoint(254.308, 266.372); + points += VSAPoint(255.795, 263.547); + points += VSAPoint(256.949, 260.264); + points += VSAPoint(257.756, 256.51); + points += VSAPoint(258.203, 252.278); + points += VSAPoint(258.279, 247.554); + points += VSAPoint(257.717, 239.591); + points += VSAPoint(255.482, 227.075); + points += VSAPoint(251.528, 212.406); + points += VSAPoint(248.796, 204.144); + points += VSAPoint(248.796, 204.144); + points += VSAPoint(241.73, 183.168); + points += VSAPoint(234.173, 158.703); + points += VSAPoint(230.625, 145.81); + points += VSAPoint(228.29, 135.699); + points += VSAPoint(227.112, 128.232); + points += VSAPoint(227.033, 123.272); + points += VSAPoint(227.69, 121.185); + points += VSAPoint(228.421, 120.456); + points += VSAPoint(229.393, 120.277); + points += VSAPoint(230.6, 120.629); + points += VSAPoint(232.808, 122.058); + points += VSAPoint(236.545, 125.75); + points += VSAPoint(241.092, 131.261); + points += VSAPoint(249.22, 142.455); + points += VSAPoint(262.477, 162.745); + points += VSAPoint(286.15, 201.448); + points += VSAPoint(323.075, 264.247); + points += VSAPoint(362.315, 330.86); + points += VSAPoint(390.909, 377.669); + points += VSAPoint(408.797, 405.589); + points += VSAPoint(417.135, 417.929); + points += VSAPoint(417.135, 417.929); + points += VSAPoint(35, 417.953); + + return points; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<QPointF> TST_VAbstractPiece::OutputPointsIssue298Case2() const +{ + QVector<QPointF> points; + + points += QPointF(-2.7952999999999975, 4.8384699505981095); + points += QPointF(67.34448942068963, -0.23248582689164274); + points += QPointF(73.11721243320879, 39.48203774070609); + points += QPointF(75.42415682885321, 49.62029267468959); + points += QPointF(78.79409614728041, 60.281321268788744); + points += QPointF(83.27292363150828, 71.59911521750833); + points += QPointF(88.79988374248082, 83.39960453097031); + points += QPointF(95.2926159908344, 95.5247556686474); + points += QPointF(102.65546594334339, 107.82863001903641); + points += QPointF(110.78654319853989, 120.17975944490887); + points += QPointF(119.5782864094781, 132.4565262107595); + points += QPointF(128.91893020761376, 144.54068833830968); + points += QPointF(138.69670055252752, 156.3216457494432); + points += QPointF(148.79638835752286, 167.69430252867102); + points += QPointF(159.09802741244354, 178.55148997659143); + points += QPointF(169.48171675272164, 188.79080814910267); + points += QPointF(179.81876372713828, 198.30845505847407); + points += QPointF(189.9727199683426, 207.00061743916868); + points += QPointF(199.7939139119543, 214.75881893038778); + points += QPointF(209.1143810932559, 221.476716907111); + points += QPointF(216.03386663545683, 225.9476461661168); + points += QPointF(215.3306509043856, 223.3387762725701); + points += QPointF(205.75073516810195, 194.75155680967347); + points += QPointF(197.88802785264718, 169.29686123304236); + points += QPointF(193.97579117825833, 155.08026950731082); + points += QPointF(191.1640933645057, 142.90507610480435); + points += QPointF(189.3638602852325, 131.49392126360493); + points += QPointF(189.14507682295456, 117.75764312564759); + points += QPointF(194.42693552963567, 100.97950138920423); + points += QPointF(210.03879336533757, 85.41035725481989); + points += QPointF(231.36634627769158, 81.48275234606332); + points += QPointF(246.4916615881645, 85.89378050620131); + points += QPointF(256.60614755001956, 92.43979519799973); + points += QPointF(264.4750900046005, 100.21398185636762); + points += QPointF(270.9888544453203, 108.1087159300009); + points += QPointF(280.35077918473866, 121.00209505562212); + points += QPointF(294.42535276480356, 142.5434013797918); + points += QPointF(318.5597512322288, 182.00074197391842); + points += QPointF(394.73028222951507, 311.42213969492946); + points += QPointF(422.9514429826756, 357.62079373755); + points += QPointF(440.37197676737753, 384.8111617646563); + points += QPointF(488.2841719585649, 455.71983154868764); + points += QPointF(-2.795300000000013, 455.7506738094777); + points += QPointF(-2.7952999999999975, 4.8384699505981095); + + return points; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<VSAPoint> TST_VAbstractPiece::InputPointsIssue548Case1() const +{ + QVector<VSAPoint> points; + + points += VSAPoint(236.97989607468364, 65.89325192030674); + points += VSAPoint(198.93409106041895, 172.04876297154925); + points += VSAPoint(260.32251114299453, 75.38027418944861); + points += VSAPoint(324.54110236213444, 101.48031496062993); + points += VSAPoint(29.858267716535437, 300.85039370078744); + points += VSAPoint(99.86433649395013, 10.166060970128015); + + return points; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<QPointF> TST_VAbstractPiece::OutputPointsIssue548Case1() const +{ + QVector<QPointF> points; + + points += QPointF(251.32210577118798, 59.48301432799721); + points += QPointF(243.9841262159756, 79.95746530820585); + points += QPointF(255.82424817748586, 61.31279754390509); + points += QPointF(348.48337789725855, 98.9717841021069); + points += QPointF(29.780382054543473, 314.59289909613994); + points += QPointF(17.01672179602679, 305.7450049304056); + points += QPointF(91.92616539550944, -5.299480329501037); + points += QPointF(251.32210577118798, 59.48301432799721); + + return points; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<VSAPoint> TST_VAbstractPiece::InputPointsIssue548Case2() const +{ + QVector<VSAPoint> points; + points << VSAPoint(99.86433649395013, 10.166060970128015); + points << VSAPoint(236.97989607468364, 65.89325192030674); + points << VSAPoint(198.93409106041895, 172.04876297154925); + points << VSAPoint(260.32251114299453, 75.38027418944861); + points << VSAPoint(324.54110236213444, 101.48031496062993); + points << VSAPoint(29.858267716535437, 300.85039370078744); + + return points; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<QPointF> TST_VAbstractPiece::OutputPointsIssue548Case2() const +{ + QVector<QPointF> points; + points << QPointF(73.40376616581447, -41.38574336196901); + points << QPointF(404.3486874792147, 93.11854543221973); + points << QPointF(29.59864884322894, 346.6587450186291); + points << QPointF(-12.946885351826726, 317.1657644661815); + points << QPointF(73.40376616581447, -41.38574336196901); + + return points; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<VSAPoint> TST_VAbstractPiece::InputPointsIssue548Case3() const +{ + QVector<VSAPoint> points; + + points += VSAPoint(99.86433649395013, 10.166060970128015); + points += VSAPoint(236.97989607468364, 65.89325192030674); + points += VSAPoint(198.93409106041895, 172.04876297154925); + points += VSAPoint(260.32251114299453, 75.38027418944861); + points += VSAPoint(324.54110236213444, 101.48031496062993); + points += VSAPoint(29.858267716535437, 300.85039370078744); + + return points; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<QPointF> TST_VAbstractPiece::OutputPointsIssue548Case3() const +{ + QVector<QPointF> points; + + points += QPointF(46.94319583767885, -92.9375476940661); + points += QPointF(484.15627259629446, 84.75677590380938); + points += QPointF(29.339029969922702, 392.46709633647066); + points += QPointF(-55.75203842018885, 333.48113523157537); + points += QPointF(46.94319583767885, -92.9375476940661); + + return points; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<QPointF> TST_VAbstractPiece::InputPointsCase3a() const +{ + QVector<QPointF> points; + + points += QPointF(35, 35); + points += QPointF(50, 50); + points += QPointF(15, 50); + + return points; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<QPointF> TST_VAbstractPiece::InputPointsCase4a() const +{ + QVector<QPointF> points; + + points += QPointF(15, 15); + points += QPointF(15, 50); + points += QPointF(50, 50); + + return points; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector<QPointF> TST_VAbstractPiece::InputPointsCase5a() const +{ + QVector<QPointF> points; + + points += QPointF(35, 35); + + return points; +} diff --git a/src/test/ValentinaTest/tst_vabstractdetail.h b/src/test/ValentinaTest/tst_vabstractpiece.h similarity index 68% rename from src/test/ValentinaTest/tst_vabstractdetail.h rename to src/test/ValentinaTest/tst_vabstractpiece.h index 3ae4094dd..d46f53f6b 100644 --- a/src/test/ValentinaTest/tst_vabstractdetail.h +++ b/src/test/ValentinaTest/tst_vabstractpiece.h @@ -1,14 +1,14 @@ /************************************************************************ ** - ** @file tst_vabstractdetail.h + ** @file ** @author Roman Telezhynskyi <dismine(at)gmail.com> - ** @date 16 4, 2015 + ** @date 17 11, 2016 ** ** @brief ** @copyright ** This source code is part of the Valentine project, a pattern making ** program, whose allow create and modeling patterns of clothing. - ** Copyright (C) 2015 Valentina project + ** Copyright (C) 2016 Valentina project ** <https://bitbucket.org/dismine/valentina> All Rights Reserved. ** ** Valentina is free software: you can redistribute it and/or modify @@ -26,18 +26,18 @@ ** *************************************************************************/ -#ifndef TST_VABSTRACTDETAIL_H -#define TST_VABSTRACTDETAIL_H +#ifndef TST_VABSTRACTPIECE_H +#define TST_VABSTRACTPIECE_H #include "../vmisc/abstracttest.h" -class TST_VAbstractDetail : public AbstractTest +class VSAPoint; + +class TST_VAbstractPiece : public AbstractTest { Q_OBJECT public: - explicit TST_VAbstractDetail(QObject *parent = nullptr); - -signals: + explicit TST_VAbstractPiece(QObject *parent = nullptr); private slots: void EquidistantRemoveLoop_data(); @@ -59,29 +59,37 @@ private slots: #endif private: + QVector<VSAPoint> InputPointsCase1() const; + QVector<QPointF> OutputPointsCase1() const; + + QVector<VSAPoint> InputPointsCase2() const; + QVector<QPointF> OutputPointsCase2() const; + + QVector<VSAPoint> InputPointsCase3() const; + QVector<QPointF> OutputPointsCase3() const; + void Case3() const; void Case4() const; void Case5() const; - QVector<QPointF> InputPointsIssue298Case1() const; + QVector<VSAPoint> InputPointsIssue298Case1() const; QVector<QPointF> OutputPointsIssue298Case1() const; - QVector<QPointF> InputPointsIssue298Case2() const; + QVector<VSAPoint> InputPointsIssue298Case2() const; QVector<QPointF> OutputPointsIssue298Case2() const; - QVector<QPointF> InputPointsIssue548Case1() const; + QVector<VSAPoint> InputPointsIssue548Case1() const; QVector<QPointF> OutputPointsIssue548Case1() const; - QVector<QPointF> InputPointsIssue548Case2() const; + QVector<VSAPoint> InputPointsIssue548Case2() const; QVector<QPointF> OutputPointsIssue548Case2() const; - QVector<QPointF> InputPointsIssue548Case3() const; + QVector<VSAPoint> InputPointsIssue548Case3() const; QVector<QPointF> OutputPointsIssue548Case3() const; - QVector<QPointF> InputPointsCase3() const; - QVector<QPointF> InputPointsCase4() const; - QVector<QPointF> InputPointsCase5() const; - + QVector<QPointF> InputPointsCase3a() const; + QVector<QPointF> InputPointsCase4a() const; + QVector<QPointF> InputPointsCase5a() const; }; -#endif // TST_VABSTRACTDETAIL_H +#endif // TST_VABSTRACTPIECE_H diff --git a/src/test/ValentinaTest/tst_varc.cpp b/src/test/ValentinaTest/tst_varc.cpp index 207050c34..20d35574b 100644 --- a/src/test/ValentinaTest/tst_varc.cpp +++ b/src/test/ValentinaTest/tst_varc.cpp @@ -28,7 +28,7 @@ #include "tst_varc.h" #include "../vgeometry/varc.h" -#include "../vlayout/vabstractdetail.h" +#include "../vlayout/vabstractpiece.h" #include "../vmisc/logging.h" #include <QtTest> @@ -203,7 +203,7 @@ void TST_VArc::TestGetPoints() } // calculated square - const qreal cSquare = qAbs(VAbstractDetail::SumTrapezoids(points)/2.0); + const qreal cSquare = qAbs(VAbstractPiece::SumTrapezoids(points)/2.0); const qreal value = qAbs(gSquere - cSquare); const QString errorMsg = QString("Broken the second rule. Interpolation has too big computing error. Error ='%1'.").arg(value); diff --git a/src/test/ValentinaTest/tst_vellipticalarc.cpp b/src/test/ValentinaTest/tst_vellipticalarc.cpp index 5abd8b583..794af45ef 100644 --- a/src/test/ValentinaTest/tst_vellipticalarc.cpp +++ b/src/test/ValentinaTest/tst_vellipticalarc.cpp @@ -28,7 +28,7 @@ #include "tst_vellipticalarc.h" #include "../vgeometry/vellipticalarc.h" -#include "../vlayout/vabstractdetail.h" +#include "../vlayout/vabstractpiece.h" #include "../vmisc/logging.h" #include <QtGlobal> @@ -372,7 +372,7 @@ void TST_VEllipticalArc::TestGetPoints3() {// calculated full ellipse square const qreal ellipseSquare = M_PI * radius1 * radius2; const qreal epsSquare = ellipseSquare * 0.5 / 100; // computing error 0.5 % from origin squere - const qreal arcSquare = qAbs(VAbstractDetail::SumTrapezoids(points)/2.0); + const qreal arcSquare = qAbs(VAbstractPiece::SumTrapezoids(points)/2.0); const qreal diffSquare = qAbs(ellipseSquare - arcSquare); const QString errorMsg1 = QString("Broken the second rule. Interpolation has too big computing error. " "Difference ='%1' bigger than eps = '%2'.").arg(diffSquare).arg(epsSquare); diff --git a/src/test/ValentinaTest/tst_vlayoutdetail.cpp b/src/test/ValentinaTest/tst_vlayoutdetail.cpp index cf29172ef..f440e813a 100644 --- a/src/test/ValentinaTest/tst_vlayoutdetail.cpp +++ b/src/test/ValentinaTest/tst_vlayoutdetail.cpp @@ -27,7 +27,7 @@ *************************************************************************/ #include "tst_vlayoutdetail.h" -#include "../vlayout/vlayoutdetail.h" +#include "../vlayout/vlayoutpiece.h" #include <QtDebug> @@ -56,7 +56,7 @@ void TST_VLayoutDetail::Case1() const // See issue #304. Layout appears different than my pattern. // https://bitbucket.org/dismine/valentina/issue/304/layout-appears-different-than-my-pattern - VLayoutDetail det = VLayoutDetail(); + VLayoutPiece det = VLayoutPiece(); det.SetCountourPoints(InputPointsCase1()); // Begin comparison @@ -118,7 +118,7 @@ QVector<QPointF> TST_VLayoutDetail::OutputPointsCase1() const //-V524 //--------------------------------------------------------------------------------------------------------------------- void TST_VLayoutDetail::Case2() const { - VLayoutDetail det = VLayoutDetail(); + VLayoutPiece det = VLayoutPiece(); det.SetCountourPoints(InputPointsCase2()); // Begin comparison @@ -159,7 +159,7 @@ QVector<QPointF> TST_VLayoutDetail::OutputPointsCase2() const //--------------------------------------------------------------------------------------------------------------------- void TST_VLayoutDetail::Case3() const { - VLayoutDetail det = VLayoutDetail(); + VLayoutPiece det = VLayoutPiece(); det.SetCountourPoints(InputPointsCase3()); // Begin comparison diff --git a/src/test/ValentinaTest/tst_vdetail.cpp b/src/test/ValentinaTest/tst_vpiece.cpp similarity index 87% rename from src/test/ValentinaTest/tst_vdetail.cpp rename to src/test/ValentinaTest/tst_vpiece.cpp index 486ec5ea5..3e0927e40 100644 --- a/src/test/ValentinaTest/tst_vdetail.cpp +++ b/src/test/ValentinaTest/tst_vpiece.cpp @@ -26,20 +26,23 @@ ** *************************************************************************/ -#include "tst_vdetail.h" +#include "tst_vpiece.h" #include "../vpatterndb/vcontainer.h" +#include "../vpatterndb/vpiece.h" +#include "../vpatterndb/vpiecenode.h" +#include "../vpatterndb/vpiecepath.h" #include "../vgeometry/vsplinepath.h" #include <QtTest> //--------------------------------------------------------------------------------------------------------------------- -TST_VDetail::TST_VDetail(QObject *parent) +TST_VPiece::TST_VPiece(QObject *parent) :AbstractTest(parent) { } //--------------------------------------------------------------------------------------------------------------------- -void TST_VDetail::ClearLoop() +void TST_VPiece::ClearLoop() { // Input data taken from real case // See file <root>/src/app/share/collection/jacketМ6_30-110.val @@ -86,15 +89,17 @@ void TST_VDetail::ClearLoop() data->UpdateGObject(310, new VPointF(802.08718110236236, 1653.9337322834645, "Н5", 5.0000125984251973, 9.9999874015748045)); - VDetail detail; - detail.setSeamAllowance(true); - detail.setWidth(7); - detail.setClosed(false); - detail.append(VNodeDetail(304, Tool::NodePoint, NodeDetail::Contour)); - detail.append(VNodeDetail(307, Tool::NodePoint, NodeDetail::Contour)); - detail.append(VNodeDetail(308, Tool::NodeSplinePath, NodeDetail::Contour)); - detail.append(VNodeDetail(309, Tool::NodePoint, NodeDetail::Contour)); - detail.append(VNodeDetail(310, Tool::NodePoint, NodeDetail::Contour)); + VPiece detail; + detail.SetSeamAllowance(true); + detail.SetSAWidth(7); + detail.GetPath().Append(VPieceNode(304, Tool::NodePoint)); + detail.GetPath().Append(VPieceNode(307, Tool::NodePoint)); + detail.GetPath().Append(VPieceNode(308, Tool::NodeSplinePath)); + detail.GetPath().Append(VPieceNode(309, Tool::NodePoint)); + detail.GetPath().Append(VPieceNode(310, Tool::NodePoint)); + // Closed + detail.GetPath()[0].SetFormulaSABefore("0"); + detail.GetPath()[detail.GetPath().CountNodes()-1].SetFormulaSAAfter("0"); const QVector<QPointF> pointsEkv = detail.SeamAllowancePoints(data); @@ -129,8 +134,9 @@ void TST_VDetail::ClearLoop() origPoints.append(QPointF(773.6735265709667, 824.7970381873482)); origPoints.append(QPointF(780.6615727577812, 825.0343457026618)); origPoints.append(QPointF(792.1099959092389, 824.8480813766124)); - origPoints.append(QPointF(825.8245486890017, 822.4865245986581)); + origPoints.append(QPointF(826.0032661558732, 877.1274330708662)); origPoints.append(QPointF(828.6858753986579, 1697.305833468011)); + origPoints.append(QPointF(42.46405659601934, 415.2845470563871)); // Begin comparison Comparison(pointsEkv, origPoints); diff --git a/src/test/ValentinaTest/tst_vdetail.h b/src/test/ValentinaTest/tst_vpiece.h similarity index 91% rename from src/test/ValentinaTest/tst_vdetail.h rename to src/test/ValentinaTest/tst_vpiece.h index ef7034caa..d2b8898b0 100644 --- a/src/test/ValentinaTest/tst_vdetail.h +++ b/src/test/ValentinaTest/tst_vpiece.h @@ -31,17 +31,17 @@ #include "../vmisc/abstracttest.h" -class TST_VDetail : public AbstractTest +class TST_VPiece : public AbstractTest { Q_OBJECT public: - explicit TST_VDetail(QObject *parent = nullptr); + explicit TST_VPiece(QObject *parent = nullptr); private slots: void ClearLoop(); private: - Q_DISABLE_COPY(TST_VDetail) + Q_DISABLE_COPY(TST_VPiece) }; #endif // TST_VDETAIL_H