Merge with feature.

Resolved issue #406. New feature: Seam allowance tool -> Preview.
Resolved issue #88. New feature: Variable width seam allowances.
Resolved issue #280. New tool: 'Hem' in Detail mode.
Resolved issue #509. Improve feature: Support internal Paths in Detail tool.

--HG--
branch : develop
This commit is contained in:
Roman Telezhynskyi 2017-01-25 17:21:10 +02:00
commit d91903f1ee
172 changed files with 21810 additions and 10758 deletions

View file

@ -50,6 +50,10 @@
- [#589] Valentina lock up if not enough space for label.
- [#606] Mac OS X. Cant 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.

View file

@ -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/>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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)
{

View file

@ -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())
{

View file

@ -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();
}
}

View file

@ -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);
}
}

View file

@ -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);
};

View file

@ -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

View file

@ -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(&currentScene);
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)

View file

@ -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);

View file

@ -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>

View file

@ -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;
}
}

View file

@ -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();

View file

@ -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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 572 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 752 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -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>

After

Width:  |  Height:  |  Size: 3.4 KiB

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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

View file

@ -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;

View file

@ -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>

View file

@ -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}*/&amp;|!&lt;&gt;^\-()+=?:;'\&quot;]){1,1}([^\p{Zs}*/&amp;|!&lt;&gt;^\-()+=?:;\&quot;]){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}*/&amp;|!&lt;&gt;^\-()+=?:;'\&quot;]){1,1}([^\p{Zs}*/&amp;|!&lt;&gt;^\-()+=?:;\&quot;]){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>

View file

@ -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">

View file

@ -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}*/&amp;|!&lt;&gt;^\-()+=?:;'\&quot;]){1,1}([^\p{Zs}*/&amp;|!&lt;&gt;^\-()+=?:;\&quot;]){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>

View file

@ -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}*/&amp;|!&lt;&gt;^\-()+=?:;'\&quot;]){1,1}([^\p{Zs}*/&amp;|!&lt;&gt;^\-()+=?:;\&quot;]){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}*/&amp;|!&lt;&gt;^\-()+=?:;'\&quot;]){1,1}([^\p{Zs}*/&amp;|!&lt;&gt;^\-()+=?:;\&quot;]){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>

View file

@ -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
{

View file

@ -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

View file

@ -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.");

View file

@ -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);

View file

@ -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);
}
}
}

View file

@ -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);
};
//---------------------------------------------------------------------------------------------------------------------

View file

@ -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();

View file

@ -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();
}

View file

@ -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)

View file

@ -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;

View file

@ -539,28 +539,6 @@ int VGObject::PointInCircle(const QPointF &p, const QPointF &center, 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.

View file

@ -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 &center, 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

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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;

View file

@ -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();

View file

@ -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);

View file

@ -29,8 +29,8 @@
#include "vgraphicsfillitem.h"
//---------------------------------------------------------------------------------------------------------------------
VGraphicsFillItem::VGraphicsFillItem()
:QGraphicsPathItem()
VGraphicsFillItem::VGraphicsFillItem(QGraphicsItem *parent)
:QGraphicsPathItem(parent)
{}
//---------------------------------------------------------------------------------------------------------------------

View file

@ -38,7 +38,7 @@ public:
/**
* @brief VGraphicsFillItem Constructor
*/
VGraphicsFillItem();
explicit VGraphicsFillItem(QGraphicsItem *parent = nullptr);
/**
* @brief ~VGraphicsFillItem Destructor
*/

View file

@ -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

View file

@ -33,8 +33,6 @@
#include <ciso646>
#endif /* Q_CC_MSVC */
enum class EquidistantType : char { OpenEquidistant, CloseEquidistant };
enum class LayoutErrors : char
{
NoError,

View file

@ -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);
}

View file

@ -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;

View file

@ -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();
}

View file

@ -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);
};

View file

@ -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;

View file

@ -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())
{

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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);
};

View file

@ -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));
}

View file

@ -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

View file

@ -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;
}

View file

@ -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;

View file

@ -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();
}
//---------------------------------------------------------------------------------------------------------------------

View file

@ -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);
}
}
}

View file

@ -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;
}

View file

@ -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

View file

@ -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();
}

View file

@ -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;
};

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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",

View file

@ -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

View file

@ -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)
{

View file

@ -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;

View file

@ -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"

File diff suppressed because it is too large Load diff

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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());
}

View file

@ -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

Some files were not shown because too many files have changed in this diff Show more