Compare commits

...

41 Commits

Author SHA1 Message Date
DeepSOIC
50f4372b02 Resample: re-implement, + reference placement support
Now uses ValueSeriesGenerator for extra flexibility
2018-09-07 17:40:32 +03:00
DeepSOIC
af75a3a0f0 fixup 2018-09-07 16:38:21 +03:00
DeepSOIC
f874b338e7 fixup 2018-09-07 16:18:14 +03:00
DeepSOIC
e18a270636 ProjectArray: reference placement support 2018-09-07 16:05:14 +03:00
DeepSOIC
dfa4377013 PopulateCopies: change command logic
collapse into one command
2018-09-07 02:48:07 +03:00
DeepSOIC
0224b6f98a JoinArrays: improve reference placement support 2018-09-07 01:18:56 +03:00
DeepSOIC
f7bbd41b2c BaseFeature: add dereferencing to getPlacementsList 2018-09-07 01:18:02 +03:00
DeepSOIC
e4c342f5ba BaseFeature: fix reference marker sometimes show up on non-placement results 2018-09-07 00:24:08 +03:00
DeepSOIC
b8d3df590c BaseFeature: fix readonlyness 2018-09-07 00:17:43 +03:00
DeepSOIC
56c39bd493 ArrayFilter: fix reference placement support 2018-09-06 23:38:30 +03:00
DeepSOIC
870ef63088 ReferencePlacement: refactor CS 2018-09-06 23:38:00 +03:00
DeepSOIC
a192e19209 BaseFeature: improve attacher disabling 2018-09-06 01:33:56 +03:00
DeepSOIC
7d2d62bdea BaseFeature: add updateReadonlyness global method
+ make basic Lattice properties such as MarkerSize hidden on objects with shape results.
2018-09-06 01:33:56 +03:00
DeepSOIC
32e840a941 AttachableArray, LinearArray, PolarArray: add 'external' reference option 2018-09-06 01:33:56 +03:00
DeepSOIC
d8a3293dbc ReferencePlacement: fix viewprovider update when setting refplm to None 2018-09-06 01:33:56 +03:00
DeepSOIC
64879965ba ReferencePlacement: add reference placement link 2018-09-06 01:33:56 +03:00
DeepSOIC
3a2662685e AttachedPlacement: subsequence-array reference placement support 2018-09-06 01:33:56 +03:00
DeepSOIC
22925c8187 BaseFeature: add assureProperties method 2018-09-06 01:33:56 +03:00
DeepSOIC
c3bb345c3f AttachedPlacement: subsequence-array an attached array support
now, one can "array an attached placement" a polar array.
2018-09-06 01:33:55 +03:00
DeepSOIC
7331c60ce5 ReferencePlacement: all arrays have reference placement 2018-09-06 01:33:55 +03:00
DeepSOIC
340c51b108 ReferencePlacement: workaround for FC bug 3564
https://freecadweb.org/tracker/view.php?id=3564
2018-09-06 01:33:55 +03:00
DeepSOIC
c566979574 fix refplm visibility after restore 2018-09-06 01:33:55 +03:00
DeepSOIC
a80c075b4a JoinArrays: reference placement support 2018-09-06 01:33:55 +03:00
DeepSOIC
8cb8ab7bd9 ReferencePlacement: fix expose placement 2018-09-06 01:33:55 +03:00
DeepSOIC
1e4416dd9f ArrayFilter: reference placement support 2018-09-06 01:33:55 +03:00
DeepSOIC
fb031132e3 ArrayFilter: fix 2018-09-06 01:33:55 +03:00
DeepSOIC
5a72dedd4c Invert: clean up imports 2018-09-06 01:33:55 +03:00
DeepSOIC
8f15765047 PolarArray: 'center' reference option 2018-09-06 01:33:55 +03:00
DeepSOIC
65c6dad39f Invert: support for reference placement 2018-09-06 01:33:55 +03:00
DeepSOIC
9d2043f546 ReferencePlacement: add missing tetra-marker 2018-09-06 01:33:55 +03:00
DeepSOIC
7d0d5d63a3 PopulateChildren: reference inheritance 2018-09-06 01:33:55 +03:00
DeepSOIC
618bbc331f LinearArray: fix 2018-09-06 01:33:55 +03:00
DeepSOIC
bd3ac15fd2 fixup for icons 2018-09-06 01:33:55 +03:00
DeepSOIC
681c7330ba LinearArray: reference placement support 2018-09-06 01:33:55 +03:00
DeepSOIC
c97e733c6a Populate tools: icons 2018-09-06 01:33:55 +03:00
DeepSOIC
eecd808a22 ReferencePlacement: tweak
increase refplm marker a bit, to make it more visible
2018-09-06 01:33:55 +03:00
DeepSOIC
62c6b6d7cc PopulateCopies: Reference placement propagation 2018-09-06 01:33:55 +03:00
DeepSOIC
f4b88d1a2e ReferencePlacement: fixes 2018-09-06 01:33:55 +03:00
DeepSOIC
6c620b130f ReferencePlacement: show on screen
initial implementation. to be improved...
2018-09-06 01:33:55 +03:00
DeepSOIC
9449dd9352 fixup
fix basefeature source function
2018-09-06 01:33:55 +03:00
DeepSOIC
c7dd44868e ReferencePlacement: the very basics
* ref plm support in polar array
* referencing options for populate features
2018-09-06 01:33:55 +03:00
29 changed files with 3095 additions and 272 deletions

View File

@ -63,7 +63,7 @@ class Lattice2Workbench (Workbench):
+ Lattice2.ArrayFeatures.JoinArrays.exportedCommands
+ Lattice2.ArrayFeatures.ArrayFilter.exportedCommands
+ Lattice2.ArrayFeatures.ProjectArray.exportedCommands
+ Lattice2.ArrayFeatures.Resample.exportedCommands
+ Lattice2.ArrayFeatures.Resample2.exportedCommands
+ Lattice2.ArrayFeatures.PopulateCopies.exportedCommands
+ Lattice2.ArrayFeatures.PopulateChildren.exportedCommands
+ Lattice2.ArrayFeatures.Mirror.exportedCommands

View File

@ -12,4 +12,5 @@ import lattice2PopulateChildren as PopulateChildren
import lattice2PopulateCopies as PopulateCopies
import lattice2ProjectArray as ProjectArray
import lattice2Resample as Resample
import lattice2Resample2 as Resample2
import lattice2Mirror as Mirror

View File

@ -9,3 +9,4 @@ import lattice2ValueSeriesGenerator as ValueSeriesGenerator
import lattice2ShapeCopy as ShapeCopy
import lattice2Subsequencer as Subsequencer
import lattice2Utils as Utils
import lattice2CoinGlue as CoinGlue

View File

@ -34,15 +34,19 @@
<file>icons/Lattice2_PopulateChildren_Array.svg</file>
<file>icons/Lattice2_PopulateChildren_Move.svg</file>
<file>icons/Lattice2_PopulateChildren_Normal.svg</file>
<file>icons/Lattice2_PopulateChildren_Ref.svg</file>
<file>icons/Lattice2_PopulateChildren_Plms_Array.svg</file>
<file>icons/Lattice2_PopulateChildren_Plms_Normal.svg</file>
<file>icons/Lattice2_PopulateChildren_Plms_Move.svg</file>
<file>icons/Lattice2_PopulateChildren_Plms_Ref.svg</file>
<file>icons/Lattice2_PopulateCopies_Array.svg</file>
<file>icons/Lattice2_PopulateCopies_Move.svg</file>
<file>icons/Lattice2_PopulateCopies_Normal.svg</file>
<file>icons/Lattice2_PopulateCopies_Ref.svg</file>
<file>icons/Lattice2_PopulateCopies_Plms_Array.svg</file>
<file>icons/Lattice2_PopulateCopies_Plms_Normal.svg</file>
<file>icons/Lattice2_PopulateCopies_Plms_Move.svg</file>
<file>icons/Lattice2_PopulateCopies_Plms_Ref.svg</file>
<file>icons/Lattice2_ProjectArray.svg</file>
<file>icons/Lattice2_RecomputeLocker_ForceRecompute.svg</file>
<file>icons/Lattice2_RecomputeLocker_Locked.svg</file>

View File

@ -0,0 +1,448 @@
<?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:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64px"
height="64px"
id="svg2568"
sodipodi:version="0.32"
inkscape:version="0.48.4 r9939"
sodipodi:docname="Lattice2_PopulateChildren_Plms_Move.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.1"
inkscape:export-filename="/home/user/Downloads/cad/mystuff/icons/Part/mystuff/Part_Compound_5_32px.png"
inkscape:export-xdpi="45"
inkscape:export-ydpi="45">
<defs
id="defs2570">
<linearGradient
id="linearGradient3864">
<stop
id="stop3866"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3868"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 32 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="64 : 32 : 1"
inkscape:persp3d-origin="32 : 21.333333 : 1"
id="perspective2576" />
<linearGradient
id="linearGradient3377">
<stop
id="stop3379"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3381"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<linearGradient
id="linearGradient3023">
<stop
id="stop3025"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3027"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3692"
cx="45.883327"
cy="28.869568"
fx="45.883327"
fy="28.869568"
r="19.467436"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3030">
<stop
id="stop3032"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3034"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3837"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.98773287,-0.06324662,0.02642229,1.230404,-216.68819,-80.013158)"
cx="148.88333"
cy="81.869568"
fx="148.88333"
fy="81.869568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3839"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.69474204,0.27707782,-0.32964185,2.4645588,-139.05338,-247.09727)"
cx="135.38333"
cy="97.369568"
fx="135.38333"
fy="97.369568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3841"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.71303129,0,0,1.2312496,-173.62652,-89.498759)"
cx="45.883327"
cy="28.869568"
fx="45.883327"
fy="28.869568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3804"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.98773287,-0.06324662,0.02642229,1.230404,-216.68819,-80.013158)"
cx="148.88333"
cy="81.869568"
fx="148.88333"
fy="81.869568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3806"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.69474204,0.27707782,-0.32964185,2.4645588,-139.05338,-247.09727)"
cx="135.38333"
cy="97.369568"
fx="135.38333"
fy="97.369568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3808"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.71303129,0,0,1.2312496,-173.62652,-89.498759)"
cx="45.883327"
cy="28.869568"
fx="45.883327"
fy="28.869568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-5"
id="radialGradient3804-3"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.98773287,-0.06324662,0.02642229,1.230404,-216.68819,-80.013158)"
cx="148.88333"
cy="81.869568"
fx="148.88333"
fy="81.869568"
r="19.467436" />
<linearGradient
id="linearGradient3377-5">
<stop
id="stop3379-4"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3381-8"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-5"
id="radialGradient3806-9"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.69474204,0.27707782,-0.32964185,2.4645588,-139.05338,-247.09727)"
cx="135.38333"
cy="97.369568"
fx="135.38333"
fy="97.369568"
r="19.467436" />
<linearGradient
id="linearGradient3080">
<stop
id="stop3082"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3084"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-5"
id="radialGradient3808-3"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.71303129,0,0,1.2312496,-173.62652,-89.498759)"
cx="45.883327"
cy="28.869568"
fx="45.883327"
fy="28.869568"
r="19.467436" />
<linearGradient
id="linearGradient3087">
<stop
id="stop3089"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3091"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-5"
id="radialGradient4366"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.98773287,-0.06324662,0.02642229,1.230404,-216.68819,-80.013158)"
cx="148.88333"
cy="81.869568"
fx="148.88333"
fy="81.869568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-5"
id="radialGradient4368"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.69474204,0.27707782,-0.32964185,2.4645588,-139.05338,-247.09727)"
cx="135.38333"
cy="97.369568"
fx="135.38333"
fy="97.369568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-5"
id="radialGradient4370"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.71303129,0,0,1.2312496,-173.62652,-89.498759)"
cx="45.883327"
cy="28.869568"
fx="45.883327"
fy="28.869568"
r="19.467436" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="8.4172297"
inkscape:cx="41.893894"
inkscape:cy="31.769057"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:document-units="px"
inkscape:grid-bbox="true"
inkscape:window-width="1920"
inkscape:window-height="1001"
inkscape:window-x="-9"
inkscape:window-y="-9"
inkscape:window-maximized="1"
inkscape:object-nodes="true"
inkscape:snap-global="false"
showguides="true"
inkscape:guide-bbox="true" />
<metadata
id="metadata2573">
<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></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<g
id="g3794"
transform="matrix(0.66209119,0,0,0.66209119,16.510051,9.6145811)">
<path
inkscape:connector-curvature="0"
id="path3018"
d="m -18.909091,25.818182 4.272727,17 30.454546,-11.545455 z"
style="fill:none;stroke:#000000;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3020"
d="M -14.636364,42.818182 15.818182,31.272727 -15.090909,28.545455 z"
style="fill:#e9a60a;fill-opacity:1;stroke:#000000;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3022"
d="m -18.909091,25.818182 4.272727,17 -0.454545,-14.272727 z"
style="fill:#4c390a;fill-opacity:1;stroke:#000000;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3024"
d="m -15.090909,28.545455 30.909091,2.727272 -34.727273,-5.454545 z"
style="fill:#2f240a;fill-opacity:1;stroke:#000000;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
id="g3049"
style="stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none"
transform="matrix(0.77833186,0,0,0.71925582,-2.7462371,5.126137)">
<path
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path3045"
d="m 10.351377,24.493827 -5.6980057,0 0,25.925926 5.6980057,0"
style="fill:none;stroke:#000000;stroke-width:2.67304277;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<use
height="64"
width="64"
transform="matrix(-1,0,0,1,47.081698,0)"
id="use3047"
xlink:href="#path3045"
y="0"
x="0"
style="stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none" />
</g>
<path
sodipodi:type="arc"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="path3823"
sodipodi:cx="53.466286"
sodipodi:cy="26.488129"
sodipodi:rx="7.5973411"
sodipodi:ry="7.5973411"
d="m 61.063627,26.488129 a 7.5973411,7.5973411 0 1 1 -15.194682,0 7.5973411,7.5973411 0 1 1 15.194682,0 z"
transform="translate(-1.0080847,-16.969427)" />
<path
style="fill:none;stroke:#000000;stroke-width:1.49999988;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 33.365217,54.049894 18.817583,0 0,-36.737441"
id="path3866"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.50000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 32.813497,9.2273923 12.494629,0"
id="path3868"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 60.821116,9.5634205 7.392622,0"
id="path3868-3"
inkscape:connector-curvature="0" />
<path
sodipodi:type="arc"
style="fill:#000000;fill-opacity:1;stroke:none"
id="path3888"
sodipodi:cx="51.748352"
sodipodi:cy="14.099802"
sodipodi:rx="2.3521979"
sodipodi:ry="2.3521979"
d="m 54.10055,14.099802 a 2.3521979,2.3521979 0 1 1 -4.704396,0 2.3521979,2.3521979 0 1 1 4.704396,0 z"
transform="translate(0.84007066,-4.5363816)" />
<path
transform="translate(-0.88928087,5.3103559)"
d="m 61.063627,26.488129 a 7.5973411,7.5973411 0 1 1 -15.194682,0 7.5973411,7.5973411 0 1 1 15.194682,0 z"
sodipodi:ry="7.5973411"
sodipodi:rx="7.5973411"
sodipodi:cy="26.488129"
sodipodi:cx="53.466286"
id="path4352"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
sodipodi:type="arc" />
<path
style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 48.072426,31.793994 9.072763,0"
id="path4358"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 32.730167,31.744784 11.756572,0"
id="path4376"
inkscape:connector-curvature="0" />
<g
id="g3794-9"
transform="matrix(0.66209119,0,0,0.66209119,16.746967,-12.543942)">
<path
inkscape:connector-curvature="0"
id="path3018-4"
d="m -18.909091,25.818182 4.272727,17 30.454546,-11.545455 z"
style="fill:none;stroke:#000000;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3020-5"
d="M -14.636364,42.818182 15.818182,31.272727 -15.090909,28.545455 z"
style="fill:#e9a60a;fill-opacity:1;stroke:#000000;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3022-5"
d="m -18.909091,25.818182 4.272727,17 -0.454545,-14.272727 z"
style="fill:#4c390a;fill-opacity:1;stroke:#000000;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3024-4"
d="m -15.090909,28.545455 30.909091,2.727272 -34.727273,-5.454545 z"
style="fill:#2f240a;fill-opacity:1;stroke:#000000;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<use
x="0"
y="0"
xlink:href="#g3049"
id="use3040"
width="64"
height="64"
transform="translate(0.11880393,-21.6427)" />
<g
transform="matrix(0.66209119,0,0,0.66209119,16.586547,31.892723)"
id="use4372">
<path
style="fill:none;stroke:#007ce0;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -18.909091,25.818182 4.272727,17 30.454546,-11.545455 z"
id="path3042"
inkscape:connector-curvature="0" />
<path
style="fill:#1798ff;fill-opacity:0.50210972;stroke:#007ce0;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M -14.636364,42.818182 15.818182,31.272727 -15.090909,28.545455 z"
id="path3044"
inkscape:connector-curvature="0" />
<path
style="fill:#006eca;fill-opacity:0.50196078;stroke:#1798ff;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:0.50196078"
d="m -18.909091,25.818182 4.272727,17 -0.454545,-14.272727 z"
id="path3046"
inkscape:connector-curvature="0" />
<path
style="fill:#0065b7;fill-opacity:0.63291141;stroke:#007ce0;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -15.090909,28.545455 30.909091,2.727272 -34.727273,-5.454545 z"
id="path3048"
inkscape:connector-curvature="0" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -0,0 +1,461 @@
<?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:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64px"
height="64px"
id="svg2568"
sodipodi:version="0.32"
inkscape:version="0.48.4 r9939"
sodipodi:docname="Lattice2_PopulateChildren_Move.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.1"
inkscape:export-filename="/home/user/Downloads/cad/mystuff/icons/Part/mystuff/Part_Compound_5_32px.png"
inkscape:export-xdpi="45"
inkscape:export-ydpi="45">
<defs
id="defs2570">
<linearGradient
id="linearGradient3864">
<stop
id="stop3866"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3868"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 32 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="64 : 32 : 1"
inkscape:persp3d-origin="32 : 21.333333 : 1"
id="perspective2576" />
<linearGradient
id="linearGradient3377">
<stop
id="stop3379"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3381"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<linearGradient
id="linearGradient3023">
<stop
id="stop3025"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3027"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3692"
cx="45.883327"
cy="28.869568"
fx="45.883327"
fy="28.869568"
r="19.467436"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3030">
<stop
id="stop3032"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3034"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3837"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.98773287,-0.06324662,0.02642229,1.230404,-216.68819,-80.013158)"
cx="148.88333"
cy="81.869568"
fx="148.88333"
fy="81.869568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3839"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.69474204,0.27707782,-0.32964185,2.4645588,-139.05338,-247.09727)"
cx="135.38333"
cy="97.369568"
fx="135.38333"
fy="97.369568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3841"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.71303129,0,0,1.2312496,-173.62652,-89.498759)"
cx="45.883327"
cy="28.869568"
fx="45.883327"
fy="28.869568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3804"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.98773287,-0.06324662,0.02642229,1.230404,-216.68819,-80.013158)"
cx="148.88333"
cy="81.869568"
fx="148.88333"
fy="81.869568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3806"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.69474204,0.27707782,-0.32964185,2.4645588,-139.05338,-247.09727)"
cx="135.38333"
cy="97.369568"
fx="135.38333"
fy="97.369568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3808"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.71303129,0,0,1.2312496,-173.62652,-89.498759)"
cx="45.883327"
cy="28.869568"
fx="45.883327"
fy="28.869568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-5"
id="radialGradient3804-3"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.98773287,-0.06324662,0.02642229,1.230404,-216.68819,-80.013158)"
cx="148.88333"
cy="81.869568"
fx="148.88333"
fy="81.869568"
r="19.467436" />
<linearGradient
id="linearGradient3377-5">
<stop
id="stop3379-4"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3381-8"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-5"
id="radialGradient3806-9"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.69474204,0.27707782,-0.32964185,2.4645588,-139.05338,-247.09727)"
cx="135.38333"
cy="97.369568"
fx="135.38333"
fy="97.369568"
r="19.467436" />
<linearGradient
id="linearGradient3080">
<stop
id="stop3082"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3084"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-5"
id="radialGradient3808-3"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.71303129,0,0,1.2312496,-173.62652,-89.498759)"
cx="45.883327"
cy="28.869568"
fx="45.883327"
fy="28.869568"
r="19.467436" />
<linearGradient
id="linearGradient3087">
<stop
id="stop3089"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3091"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-5"
id="radialGradient4366"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.98773287,-0.06324662,0.02642229,1.230404,-216.68819,-80.013158)"
cx="148.88333"
cy="81.869568"
fx="148.88333"
fy="81.869568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-5"
id="radialGradient4368"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.69474204,0.27707782,-0.32964185,2.4645588,-139.05338,-247.09727)"
cx="135.38333"
cy="97.369568"
fx="135.38333"
fy="97.369568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-5"
id="radialGradient4370"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.71303129,0,0,1.2312496,-173.62652,-89.498759)"
cx="45.883327"
cy="28.869568"
fx="45.883327"
fy="28.869568"
r="19.467436" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.9518802"
inkscape:cx="39.412699"
inkscape:cy="28.156141"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:document-units="px"
inkscape:grid-bbox="true"
inkscape:window-width="1920"
inkscape:window-height="1001"
inkscape:window-x="-9"
inkscape:window-y="-9"
inkscape:window-maximized="1"
inkscape:object-nodes="true"
inkscape:snap-global="false"
showguides="true"
inkscape:guide-bbox="true" />
<metadata
id="metadata2573">
<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></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<g
id="g3794"
transform="matrix(0.66209119,0,0,0.66209119,16.9445,9.1766352)">
<path
inkscape:connector-curvature="0"
id="path3018"
d="m -18.909091,25.818182 4.272727,17 30.454546,-11.545455 z"
style="fill:none;stroke:#000000;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3020"
d="M -14.636364,42.818182 15.818182,31.272727 -15.090909,28.545455 z"
style="fill:#e9a60a;fill-opacity:1;stroke:#000000;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3022"
d="m -18.909091,25.818182 4.272727,17 -0.454545,-14.272727 z"
style="fill:#4c390a;fill-opacity:1;stroke:#000000;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3024"
d="m -15.090909,28.545455 30.909091,2.727272 -34.727273,-5.454545 z"
style="fill:#2f240a;fill-opacity:1;stroke:#000000;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
id="g3049"
style="stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none"
transform="matrix(0.77833186,0,0,0.61958115,-2.2218112,8.2680831)">
<path
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path3045"
d="m 10.351377,24.493827 -5.6980057,0 0,25.925926 5.6980057,0"
style="fill:none;stroke:#000000;stroke-width:2.88003969;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<use
height="64"
width="64"
transform="matrix(-1,0,0,1,47.081698,0)"
id="use3047"
xlink:href="#path3045"
y="0"
x="0"
style="stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none" />
</g>
<path
sodipodi:type="arc"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="path3823"
sodipodi:cx="53.466286"
sodipodi:cy="26.488129"
sodipodi:rx="7.5973411"
sodipodi:ry="7.5973411"
d="m 61.063627,26.488129 a 7.5973411,7.5973411 0 1 1 -15.194682,0 7.5973411,7.5973411 0 1 1 15.194682,0 z"
transform="translate(-1.0080847,-16.969427)" />
<g
id="g3798"
transform="matrix(0.94897349,0,0,0.94897349,-24.695619,-10.087879)">
<g
id="g3843"
transform="matrix(0.57659255,0,0,0.32499812,79.277735,9.6499853)">
<path
style="fill:url(#radialGradient4366);fill-opacity:1;fill-rule:evenodd;stroke:#000137;stroke-width:2.17218089;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m -65.878042,4.7970936 -12.866966,10.1036774 21.744289,5.108296 0.30338,44.045609 11.486763,-13.03934 0.410614,-42.3363302 z"
id="path3845"
sodipodi:nodetypes="ccccccc"
inkscape:connector-curvature="0" />
<path
style="fill:url(#radialGradient4368);fill-opacity:1;fill-rule:evenodd;stroke:#000137;stroke-width:2.17218089;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m -78.552461,15.155385 21.896364,4.143912 0,44.912523 -22.192265,-6.236008 0.295901,-42.820427 z"
id="path3847"
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0" />
<path
style="fill:url(#radialGradient4370);fill-opacity:1;fill-rule:evenodd;stroke:#000137;stroke-width:2.17218089;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="M -56.822875,19.354658 -44.896728,9.001326"
id="path3849"
inkscape:connector-curvature="0" />
</g>
</g>
<path
style="fill:none;stroke:#000000;stroke-width:1.49999988;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 33.602825,52.743051 18.817583,0 0,-35.787009"
id="path3866"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.50000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 34.261979,9.2273923 11.114739,0"
id="path3868"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 60.821116,9.5634205 7.392622,0"
id="path3868-3"
inkscape:connector-curvature="0" />
<path
sodipodi:type="arc"
style="fill:#000000;fill-opacity:1;stroke:none"
id="path3888"
sodipodi:cx="51.748352"
sodipodi:cy="14.099802"
sodipodi:rx="2.3521979"
sodipodi:ry="2.3521979"
d="m 54.10055,14.099802 a 2.3521979,2.3521979 0 1 1 -4.704396,0 2.3521979,2.3521979 0 1 1 4.704396,0 z"
transform="translate(0.84007066,-4.5363816)" />
<path
transform="translate(-1.0080848,3.5282969)"
d="m 61.063627,26.488129 a 7.5973411,7.5973411 0 1 1 -15.194682,0 7.5973411,7.5973411 0 1 1 15.194682,0 z"
sodipodi:ry="7.5973411"
sodipodi:rx="7.5973411"
sodipodi:cy="26.488129"
sodipodi:cx="53.466286"
id="path4352"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
sodipodi:type="arc" />
<path
style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 47.716014,29.893131 9.072763,0"
id="path4358"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 33.266798,29.725117 10.920919,0"
id="path4376"
inkscape:connector-curvature="0" />
<g
transform="matrix(0.81161259,0,0,0.63682405,-2.3339197,-14.471639)"
style="stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none"
id="g3040">
<path
style="fill:none;stroke:#000000;stroke-width:2.78192782;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 10.351377,24.493827 -5.6980057,0 0,25.925926 5.6980057,0"
id="path3042"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<use
style="stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none"
x="0"
y="0"
xlink:href="#path3045"
id="use3044"
transform="matrix(-1,0,0,1,47.081698,0)"
width="64"
height="64" />
</g>
<g
transform="matrix(0.66209119,0,0,0.66209119,16.81656,31.029372)"
id="use4372">
<path
style="fill:none;stroke:#007ce0;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -18.909091,25.818182 4.272727,17 30.454546,-11.545455 z"
id="path3042-7"
inkscape:connector-curvature="0" />
<path
style="fill:#1798ff;fill-opacity:0.50210972;stroke:#007ce0;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M -14.636364,42.818182 15.818182,31.272727 -15.090909,28.545455 z"
id="path3044"
inkscape:connector-curvature="0" />
<path
style="fill:#006eca;fill-opacity:0.50196078;stroke:#1798ff;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:0.50196078"
d="m -18.909091,25.818182 4.272727,17 -0.454545,-14.272727 z"
id="path3046"
inkscape:connector-curvature="0" />
<path
style="fill:#0065b7;fill-opacity:0.63291141;stroke:#007ce0;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -15.090909,28.545455 30.909091,2.727272 -34.727273,-5.454545 z"
id="path3048"
inkscape:connector-curvature="0" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -0,0 +1,440 @@
<?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:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64px"
height="64px"
id="svg2568"
sodipodi:version="0.32"
inkscape:version="0.48.4 r9939"
sodipodi:docname="Lattice2_PopulateCopies_Plms_Move.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.1"
inkscape:export-filename="/home/user/Downloads/cad/mystuff/icons/Part/mystuff/Part_Compound_5_32px.png"
inkscape:export-xdpi="45"
inkscape:export-ydpi="45">
<defs
id="defs2570">
<linearGradient
id="linearGradient3864">
<stop
id="stop3866"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3868"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 32 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="64 : 32 : 1"
inkscape:persp3d-origin="32 : 21.333333 : 1"
id="perspective2576" />
<linearGradient
id="linearGradient3377">
<stop
id="stop3379"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3381"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<linearGradient
id="linearGradient3023">
<stop
id="stop3025"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3027"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3692"
cx="45.883327"
cy="28.869568"
fx="45.883327"
fy="28.869568"
r="19.467436"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3030">
<stop
id="stop3032"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3034"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3837"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.98773287,-0.06324662,0.02642229,1.230404,-216.68819,-80.013158)"
cx="148.88333"
cy="81.869568"
fx="148.88333"
fy="81.869568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3839"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.69474204,0.27707782,-0.32964185,2.4645588,-139.05338,-247.09727)"
cx="135.38333"
cy="97.369568"
fx="135.38333"
fy="97.369568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3841"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.71303129,0,0,1.2312496,-173.62652,-89.498759)"
cx="45.883327"
cy="28.869568"
fx="45.883327"
fy="28.869568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3804"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.98773287,-0.06324662,0.02642229,1.230404,-216.68819,-80.013158)"
cx="148.88333"
cy="81.869568"
fx="148.88333"
fy="81.869568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3806"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.69474204,0.27707782,-0.32964185,2.4645588,-139.05338,-247.09727)"
cx="135.38333"
cy="97.369568"
fx="135.38333"
fy="97.369568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3808"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.71303129,0,0,1.2312496,-173.62652,-89.498759)"
cx="45.883327"
cy="28.869568"
fx="45.883327"
fy="28.869568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-5"
id="radialGradient3804-3"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.98773287,-0.06324662,0.02642229,1.230404,-216.68819,-80.013158)"
cx="148.88333"
cy="81.869568"
fx="148.88333"
fy="81.869568"
r="19.467436" />
<linearGradient
id="linearGradient3377-5">
<stop
id="stop3379-4"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3381-8"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-5"
id="radialGradient3806-9"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.69474204,0.27707782,-0.32964185,2.4645588,-139.05338,-247.09727)"
cx="135.38333"
cy="97.369568"
fx="135.38333"
fy="97.369568"
r="19.467436" />
<linearGradient
id="linearGradient3080">
<stop
id="stop3082"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3084"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-5"
id="radialGradient3808-3"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.71303129,0,0,1.2312496,-173.62652,-89.498759)"
cx="45.883327"
cy="28.869568"
fx="45.883327"
fy="28.869568"
r="19.467436" />
<linearGradient
id="linearGradient3087">
<stop
id="stop3089"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3091"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-5"
id="radialGradient4366"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.98773287,-0.06324662,0.02642229,1.230404,-216.68819,-80.013158)"
cx="148.88333"
cy="81.869568"
fx="148.88333"
fy="81.869568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-5"
id="radialGradient4368"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.69474204,0.27707782,-0.32964185,2.4645588,-139.05338,-247.09727)"
cx="135.38333"
cy="97.369568"
fx="135.38333"
fy="97.369568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-5"
id="radialGradient4370"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.71303129,0,0,1.2312496,-173.62652,-89.498759)"
cx="45.883327"
cy="28.869568"
fx="45.883327"
fy="28.869568"
r="19.467436" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.9518802"
inkscape:cx="39.412699"
inkscape:cy="28.156141"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:document-units="px"
inkscape:grid-bbox="true"
inkscape:window-width="1920"
inkscape:window-height="1001"
inkscape:window-x="-9"
inkscape:window-y="-9"
inkscape:window-maximized="1"
inkscape:object-nodes="true"
inkscape:snap-global="false"
showguides="true"
inkscape:guide-bbox="true" />
<metadata
id="metadata2573">
<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></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<g
id="g3794"
transform="matrix(0.66209119,0,0,0.66209119,16.272443,7.8325221)">
<path
inkscape:connector-curvature="0"
id="path3018"
d="m -18.909091,25.818182 4.272727,17 30.454546,-11.545455 z"
style="fill:none;stroke:#000000;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3020"
d="M -14.636364,42.818182 15.818182,31.272727 -15.090909,28.545455 z"
style="fill:#e9a60a;fill-opacity:1;stroke:#000000;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3022"
d="m -18.909091,25.818182 4.272727,17 -0.454545,-14.272727 z"
style="fill:#4c390a;fill-opacity:1;stroke:#000000;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3024"
d="m -15.090909,28.545455 30.909091,2.727272 -34.727273,-5.454545 z"
style="fill:#2f240a;fill-opacity:1;stroke:#000000;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
id="g3049"
style="stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none"
transform="matrix(0.77833186,0,0,0.77833186,-2.3898253,0.89367113)">
<path
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path3045"
d="m 10.351377,24.493827 -5.6980057,0 0,25.925926 5.6980057,0"
style="fill:none;stroke:#000000;stroke-width:2.56959796;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<use
height="64"
width="64"
transform="matrix(-1,0,0,1,47.081698,0)"
id="use3047"
xlink:href="#path3045"
y="0"
x="0"
style="stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none" />
</g>
<path
sodipodi:type="arc"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="path3823"
sodipodi:cx="53.466286"
sodipodi:cy="26.488129"
sodipodi:rx="7.5973411"
sodipodi:ry="7.5973411"
d="m 61.063627,26.488129 a 7.5973411,7.5973411 0 1 1 -15.194682,0 7.5973411,7.5973411 0 1 1 15.194682,0 z"
transform="translate(-1.0080847,-16.969427)" />
<path
style="fill:none;stroke:#000000;stroke-width:1.49999988;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 33.602825,52.743051 18.817583,0 0,-35.787009"
id="path3866"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.50000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 30.091119,9.2273923 15.088091,0"
id="path3868"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 60.821116,9.5634205 7.392622,0"
id="path3868-3"
inkscape:connector-curvature="0" />
<path
sodipodi:type="arc"
style="fill:#000000;fill-opacity:1;stroke:none"
id="path3888"
sodipodi:cx="51.748352"
sodipodi:cy="14.099802"
sodipodi:rx="2.3521979"
sodipodi:ry="2.3521979"
d="m 54.10055,14.099802 a 2.3521979,2.3521979 0 1 1 -4.704396,0 2.3521979,2.3521979 0 1 1 4.704396,0 z"
transform="translate(0.84007066,-4.5363816)" />
<path
transform="translate(-1.0080848,3.5282969)"
d="m 61.063627,26.488129 a 7.5973411,7.5973411 0 1 1 -15.194682,0 7.5973411,7.5973411 0 1 1 15.194682,0 z"
sodipodi:ry="7.5973411"
sodipodi:rx="7.5973411"
sodipodi:cy="26.488129"
sodipodi:cx="53.466286"
id="path4352"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
sodipodi:type="arc" />
<path
style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 47.716014,29.893131 9.072763,0"
id="path4358"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 33.266798,29.725117 10.920919,0"
id="path4376"
inkscape:connector-curvature="0" />
<g
id="g3794-9"
transform="matrix(0.66209119,0,0,0.66209119,16.984575,-13.494373)">
<path
inkscape:connector-curvature="0"
id="path3018-4"
d="m -18.909091,25.818182 4.272727,17 30.454546,-11.545455 z"
style="fill:none;stroke:#000000;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3020-5"
d="M -14.636364,42.818182 15.818182,31.272727 -15.090909,28.545455 z"
style="fill:#e9a60a;fill-opacity:1;stroke:#000000;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3022-5"
d="m -18.909091,25.818182 4.272727,17 -0.454545,-14.272727 z"
style="fill:#4c390a;fill-opacity:1;stroke:#000000;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3024-4"
d="m -15.090909,28.545455 30.909091,2.727272 -34.727273,-5.454545 z"
style="fill:#2f240a;fill-opacity:1;stroke:#000000;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
transform="matrix(0.66209119,0,0,0.66209119,16.312518,30.861358)"
id="use4372">
<path
style="fill:none;stroke:#007ce0;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -18.909091,25.818182 4.272727,17 30.454546,-11.545455 z"
id="path3042"
inkscape:connector-curvature="0" />
<path
style="fill:#1798ff;fill-opacity:0.50210972;stroke:#007ce0;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M -14.636364,42.818182 15.818182,31.272727 -15.090909,28.545455 z"
id="path3044"
inkscape:connector-curvature="0" />
<path
style="fill:#006eca;fill-opacity:0.50196078;stroke:#1798ff;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:0.50196078"
d="m -18.909091,25.818182 4.272727,17 -0.454545,-14.272727 z"
id="path3046"
inkscape:connector-curvature="0" />
<path
style="fill:#0065b7;fill-opacity:0.63291141;stroke:#007ce0;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -15.090909,28.545455 30.909091,2.727272 -34.727273,-5.454545 z"
id="path3048"
inkscape:connector-curvature="0" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -0,0 +1,441 @@
<?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:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64px"
height="64px"
id="svg2568"
sodipodi:version="0.32"
inkscape:version="0.48.4 r9939"
sodipodi:docname="Lattice2_PopulateCopies_Move.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.1"
inkscape:export-filename="/home/user/Downloads/cad/mystuff/icons/Part/mystuff/Part_Compound_5_32px.png"
inkscape:export-xdpi="45"
inkscape:export-ydpi="45">
<defs
id="defs2570">
<linearGradient
id="linearGradient3864">
<stop
id="stop3866"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3868"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 32 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="64 : 32 : 1"
inkscape:persp3d-origin="32 : 21.333333 : 1"
id="perspective2576" />
<linearGradient
id="linearGradient3377">
<stop
id="stop3379"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3381"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<linearGradient
id="linearGradient3023">
<stop
id="stop3025"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3027"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3692"
cx="45.883327"
cy="28.869568"
fx="45.883327"
fy="28.869568"
r="19.467436"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3030">
<stop
id="stop3032"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3034"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3837"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.98773287,-0.06324662,0.02642229,1.230404,-216.68819,-80.013158)"
cx="148.88333"
cy="81.869568"
fx="148.88333"
fy="81.869568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3839"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.69474204,0.27707782,-0.32964185,2.4645588,-139.05338,-247.09727)"
cx="135.38333"
cy="97.369568"
fx="135.38333"
fy="97.369568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3841"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.71303129,0,0,1.2312496,-173.62652,-89.498759)"
cx="45.883327"
cy="28.869568"
fx="45.883327"
fy="28.869568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3804"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.98773287,-0.06324662,0.02642229,1.230404,-216.68819,-80.013158)"
cx="148.88333"
cy="81.869568"
fx="148.88333"
fy="81.869568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3806"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.69474204,0.27707782,-0.32964185,2.4645588,-139.05338,-247.09727)"
cx="135.38333"
cy="97.369568"
fx="135.38333"
fy="97.369568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3808"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.71303129,0,0,1.2312496,-173.62652,-89.498759)"
cx="45.883327"
cy="28.869568"
fx="45.883327"
fy="28.869568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-5"
id="radialGradient3804-3"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.98773287,-0.06324662,0.02642229,1.230404,-216.68819,-80.013158)"
cx="148.88333"
cy="81.869568"
fx="148.88333"
fy="81.869568"
r="19.467436" />
<linearGradient
id="linearGradient3377-5">
<stop
id="stop3379-4"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3381-8"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-5"
id="radialGradient3806-9"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.69474204,0.27707782,-0.32964185,2.4645588,-139.05338,-247.09727)"
cx="135.38333"
cy="97.369568"
fx="135.38333"
fy="97.369568"
r="19.467436" />
<linearGradient
id="linearGradient3080">
<stop
id="stop3082"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3084"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-5"
id="radialGradient3808-3"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.71303129,0,0,1.2312496,-173.62652,-89.498759)"
cx="45.883327"
cy="28.869568"
fx="45.883327"
fy="28.869568"
r="19.467436" />
<linearGradient
id="linearGradient3087">
<stop
id="stop3089"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3091"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-5"
id="radialGradient4366"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.98773287,-0.06324662,0.02642229,1.230404,-216.68819,-80.013158)"
cx="148.88333"
cy="81.869568"
fx="148.88333"
fy="81.869568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-5"
id="radialGradient4368"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.69474204,0.27707782,-0.32964185,2.4645588,-139.05338,-247.09727)"
cx="135.38333"
cy="97.369568"
fx="135.38333"
fy="97.369568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-5"
id="radialGradient4370"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.71303129,0,0,1.2312496,-173.62652,-89.498759)"
cx="45.883327"
cy="28.869568"
fx="45.883327"
fy="28.869568"
r="19.467436" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.9518802"
inkscape:cx="8.9181336"
inkscape:cy="28.156141"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:document-units="px"
inkscape:grid-bbox="true"
inkscape:window-width="1920"
inkscape:window-height="1001"
inkscape:window-x="-9"
inkscape:window-y="-9"
inkscape:window-maximized="1"
inkscape:object-nodes="true"
inkscape:snap-global="false"
showguides="true"
inkscape:guide-bbox="true" />
<metadata
id="metadata2573">
<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></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<g
id="g3794"
transform="matrix(0.66209119,0,0,0.66209119,16.272443,7.8325221)">
<path
inkscape:connector-curvature="0"
id="path3018"
d="m -18.909091,25.818182 4.272727,17 30.454546,-11.545455 z"
style="fill:none;stroke:#000000;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3020"
d="M -14.636364,42.818182 15.818182,31.272727 -15.090909,28.545455 z"
style="fill:#e9a60a;fill-opacity:1;stroke:#000000;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3022"
d="m -18.909091,25.818182 4.272727,17 -0.454545,-14.272727 z"
style="fill:#4c390a;fill-opacity:1;stroke:#000000;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3024"
d="m -15.090909,28.545455 30.909091,2.727272 -34.727273,-5.454545 z"
style="fill:#2f240a;fill-opacity:1;stroke:#000000;stroke-width:1.51036596px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
id="g3049"
style="stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none"
transform="matrix(0.77833186,0,0,0.77833186,-2.3898253,0.89367113)">
<path
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path3045"
d="m 10.351377,24.493827 -5.6980057,0 0,25.925926 5.6980057,0"
style="fill:none;stroke:#000000;stroke-width:2.56959796;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<use
height="64"
width="64"
transform="matrix(-1,0,0,1,47.081698,0)"
id="use3047"
xlink:href="#path3045"
y="0"
x="0"
style="stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none" />
</g>
<path
sodipodi:type="arc"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="path3823"
sodipodi:cx="53.466286"
sodipodi:cy="26.488129"
sodipodi:rx="7.5973411"
sodipodi:ry="7.5973411"
d="m 61.063627,26.488129 a 7.5973411,7.5973411 0 1 1 -15.194682,0 7.5973411,7.5973411 0 1 1 15.194682,0 z"
transform="translate(-1.0080847,-16.969427)" />
<g
id="g3798"
transform="matrix(0.94897349,0,0,0.94897349,-24.695619,-10.087879)">
<g
id="g3843"
transform="matrix(0.57659255,0,0,0.32499812,79.277735,9.6499853)">
<path
style="fill:url(#radialGradient4366);fill-opacity:1;fill-rule:evenodd;stroke:#000137;stroke-width:2.17218089;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m -65.878042,4.7970936 -12.866966,10.1036774 21.744289,5.108296 0.30338,44.045609 11.486763,-13.03934 0.410614,-42.3363302 z"
id="path3845"
sodipodi:nodetypes="ccccccc"
inkscape:connector-curvature="0" />
<path
style="fill:url(#radialGradient4368);fill-opacity:1;fill-rule:evenodd;stroke:#000137;stroke-width:2.17218089;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m -78.552461,15.155385 21.896364,4.143912 0,44.912523 -22.192265,-6.236008 0.295901,-42.820427 z"
id="path3847"
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0" />
<path
style="fill:url(#radialGradient4370);fill-opacity:1;fill-rule:evenodd;stroke:#000137;stroke-width:2.17218089;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="M -56.822875,19.354658 -44.896728,9.001326"
id="path3849"
inkscape:connector-curvature="0" />
</g>
</g>
<path
style="fill:none;stroke:#000000;stroke-width:1.49999988;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 33.602825,52.743051 18.817583,0 0,-35.787009"
id="path3866"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.50000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 30.091119,9.2273923 15.088091,0"
id="path3868"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 60.821116,9.5634205 7.392622,0"
id="path3868-3"
inkscape:connector-curvature="0" />
<path
sodipodi:type="arc"
style="fill:#000000;fill-opacity:1;stroke:none"
id="path3888"
sodipodi:cx="51.748352"
sodipodi:cy="14.099802"
sodipodi:rx="2.3521979"
sodipodi:ry="2.3521979"
d="m 54.10055,14.099802 a 2.3521979,2.3521979 0 1 1 -4.704396,0 2.3521979,2.3521979 0 1 1 4.704396,0 z"
transform="translate(0.84007066,-4.5363816)" />
<path
transform="translate(-1.0080848,3.5282969)"
d="m 61.063627,26.488129 a 7.5973411,7.5973411 0 1 1 -15.194682,0 7.5973411,7.5973411 0 1 1 15.194682,0 z"
sodipodi:ry="7.5973411"
sodipodi:rx="7.5973411"
sodipodi:cy="26.488129"
sodipodi:cx="53.466286"
id="path4352"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
sodipodi:type="arc" />
<path
style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 47.716014,29.893131 9.072763,0"
id="path4358"
inkscape:connector-curvature="0" />
<g
transform="matrix(0.66209119,0,0,0.66209119,16.272443,31.186487)"
id="use4372">
<path
style="fill:none;stroke:#007ce0;stroke-width:1.51036595999999990px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -18.909091,25.818182 4.272727,17 30.454546,-11.545455 z"
id="path3042"
inkscape:connector-curvature="0" />
<path
style="fill:#1798ff;fill-opacity:0.50210971000000004;stroke:#007ce0;stroke-width:1.51036595999999990px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M -14.636364,42.818182 15.818182,31.272727 -15.090909,28.545455 z"
id="path3044"
inkscape:connector-curvature="0" />
<path
style="fill:#006eca;fill-opacity:0.50196081;stroke:#1798ff;stroke-width:1.51036595999999990px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:0.50196081000000004"
d="m -18.909091,25.818182 4.272727,17 -0.454545,-14.272727 z"
id="path3046"
inkscape:connector-curvature="0" />
<path
style="fill:#0065b7;fill-opacity:0.63291138;stroke:#007ce0;stroke-width:1.51036595999999990px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -15.090909,28.545455 30.909091,2.727272 -34.727273,-5.454545 z"
id="path3048"
inkscape:connector-curvature="0" />
</g>
<path
style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 33.266798,29.725117 10.920919,0"
id="path4376"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -70,6 +70,20 @@ class LatticeArrayFilter(lattice2BaseFeature.LatticeFeature):
obj.Proxy = self
def updateReadonlyness(self, selfobj, bypass_set = set()):
my_hidden = set([
'ReferencePlacement',
'ReferencePlacementLink',
'ReferencePlacementLinkIndex',
])
super(LatticeArrayFilter, self).updateReadonlyness(selfobj, bypass_set | my_hidden)
for prop in my_hidden:
if prop in bypass_set: continue
if hasattr(selfobj, prop):
selfobj.setEditorMode(prop, 2)
def recomputeReferencePlm(self, selfobj, selfplacements):
pass #suppress standard refplm recompute
def derivedExecute(self,obj):
#validity check
@ -129,6 +143,8 @@ class LatticeArrayFilter(lattice2BaseFeature.LatticeFeature):
else:
raise ValueError('Filter mode not implemented:'+obj.FilterType)
self.setReferencePlm(obj, lattice2BaseFeature.getReferencePlm(obj.Base))
return output
@ -192,7 +208,7 @@ def CreateLatticeArrayFilter(name,mode):
iLtc = 0 #index of lattice object in selection
iStc = 1 #index of stencil object in selection
for i in range(0,len(sel)):
if lattice2BaseFeature.isObjectLattice(sel[i]):
if lattice2BaseFeature.isObjectLattice(sel[i].Object):
iLtc = i
iStc = i-1 #this may give negative index, but python accepts negative indexes
break

View File

@ -40,7 +40,7 @@ EDIT_ATTACHMENT = 56 # Viewprovider edit mode number
def makeAttachablePlacement(name):
'''makeAttachablePlacement(name): makes an attachable Placement object.'''
if Compat.attach_extension_era:
obj = lattice2BaseFeature.makeLatticeFeature(name, AttachablePlacement, ViewProviderAttachablePlacement, no_disable_attacher= True)
obj = lattice2BaseFeature.makeLatticeFeature(name, AttachablePlacement, ViewProviderAttachablePlacement)
else:
#obsolete!
obj = FreeCAD.ActiveDocument.addObject("Part::AttachableObjectPython",name)
@ -53,16 +53,13 @@ def makeAttachablePlacement(name):
class AttachableFeature(lattice2BaseFeature.LatticeFeature):
"Base class for attachable features"
attachable = True
def derivedInit(self,obj):
if Compat.attach_extension_era:
if not obj.hasExtension('Part::AttachExtension'): #PartDesign-related hack: the placement already has attachextension if created in PD
obj.addExtension('Part::AttachExtensionPython', None)
def onDocumentRestored(self, selfobj):
#PartDesign-related hack: this dummy override disables disabling of attacher
pass
class AttachablePlacement(AttachableFeature):
"Attachable Lattice Placement object"
@ -122,9 +119,26 @@ class AttachedPlacementSubsequence(lattice2BaseFeature.LatticeFeature):
obj.addProperty("App::PropertyLink", "Base", "Lattice Attached Placement Subsequence", "Link to Lattice Attached Placement, which is to be subsequenced.")
obj.addProperty("App::PropertyString", "RefIndexFilter","Lattice Attached Placement Subsequence","Sets which references of attachment to cycle through children. '0000' = no cycle, '1000' = cycle only ref1. '' = cycle all if possible")
obj.addProperty("App::PropertyEnumeration", "CycleMode","Lattice Attached Placement Subsequence", "How to cycle through chidren. Open = advance each link till one reaches the end of array. Periodic = if array end reached, continue from begin if any children left.")
obj.addProperty("App::PropertyEnumeration", "CycleMode","Lattice Attached Placement Subsequence", "How to cycle through children. Open = advance each link till one reaches the end of array. Periodic = if array end reached, continue from begin if any children left.")
obj.CycleMode = ['Open','Periodic']
def assureProperties(self, selfobj, creating_new = False):
super(AttachedPlacementSubsequence, self).assureProperties(selfobj, creating_new)
created = self.assureProperty(selfobj,
'App::PropertyEnumeration',
'ReferencePlacementOption',
['external', 'origin', 'inherit', 'first placement', 'last placement'],
"Lattice Attached Placement Subsequence",
"Reference placement, corresponds to the original occurrence of the object to be populated. 'inherit' = use reference placement of the base attached placement."
)
if created:
selfobj.ReferencePlacementOption = 'inherit'
def recomputeReferencePlm(self, selfobj, selfplacements): #override
if selfobj.ReferencePlacementOption == 'external':
super(AttachedPlacementSubsequence, self).recomputeReferencePlm(selfobj, selfplacements)
#the remaining options are handled in derivedExecute
def derivedExecute(self,obj):
attacher = Part.AttachEngine(screen(obj.Base).AttacherType)
attacher.readParametersFromFeature(screen(obj.Base))
@ -133,10 +147,31 @@ class AttachedPlacementSubsequence(lattice2BaseFeature.LatticeFeature):
sublinks = Subsequencer.Subsequence_auto(attacher.References,
loop= ('Till end' if obj.CycleMode == 'Open' else 'All around'),
index_filter= ifilt)
deref = obj.Base.Placement.inverse()
basearray = [deref.multiply(plm) for plm in lattice2BaseFeature.getPlacementsList(obj.Base)]
plms = []
for lnkval in sublinks:
attacher.References = lnkval
plms.append(attacher.calculateAttachedPlacement(screen(obj.Base).Placement))
attplm = attacher.calculateAttachedPlacement(obj.Base.Placement)
plms.extend([attplm.multiply(plm) for plm in basearray])
#reference
ref = obj.ReferencePlacementOption
if ref == 'external':
pass #gets done in recomputeReferencePlm
elif ref == 'origin':
self.setReferencePlm(obj, None)
elif ref == 'inherit':
self.setReferencePlm(obj, lattice2BaseFeature.getReferencePlm(obj.Base))
elif ref == 'first placement':
self.setReferencePlm(obj, plms[0])
elif ref == 'last placement':
self.setReferencePlm(obj, plms[-1])
else:
raise NotImplementedError("Reference option not implemented: " + ref)
return plms
class ViewProviderAttachedPlacementSubsequence(lattice2BaseFeature.ViewProviderLatticeFeature):

View File

@ -33,6 +33,7 @@ import lattice2CompoundExplorer as LCE
import lattice2Markers
import lattice2Executer
from lattice2ShapeCopy import shallowCopy
import lattice2CoinGlue as CoinGlue
def getDefLatticeFaceColor():
@ -49,11 +50,10 @@ def getDefShapeColor():
return (r/255.0, g/255.0, b/255.0, (255-o)/255.0)
def makeLatticeFeature(name, AppClass, ViewClass, no_body = False, no_disable_attacher = False):
def makeLatticeFeature(name, AppClass, ViewClass, no_body = False):
'''makeLatticeFeature(name, AppClass, ViewClass, no_body = False): makes a document object for a LatticeFeature-derived object.
no_body: if False, the Lattice object will end up in an active body, and Part2DObject will be used.
no_disable_attacher: if True, attachment properties of Part2DObject won't be hidden'''
no_body: if False, the Lattice object will end up in an active body, and Part2DObject will be used.'''
body = activeBody()
if body and not no_body:
@ -73,15 +73,16 @@ def makeLatticeFeature(name, AppClass, ViewClass, no_body = False, no_disable_at
def isObjectLattice(documentObject):
'''isObjectLattice(documentObject): When operating on the object, it is to be treated as a lattice object. If False, treat as a regular shape.'''
transform, src = source(documentObject)
ret = False
if hasattr(documentObject,"isLattice"):
if 'On' in documentObject.isLattice:
if hasattr(src,'isLattice'):
if 'On' in src.isLattice:
ret = True
if documentObject.isDerivedFrom('PartDesign::ShapeBinder'):
if len(documentObject.Support) == 1 and documentObject.Support[0][1] == ('',):
ret = isObjectLattice(documentObject.Support[0][0])
if hasattr(documentObject, 'IAm') and documentObject.IAm == 'PartOMagic.Ghost':
ret = isObjectLattice(documentObject.Base)
#if documentObject.isDerivedFrom('PartDesign::ShapeBinder'):
# if len(documentObject.Support) == 1 and documentObject.Support[0][1] == ('',):
# ret = isObjectLattice(documentObject.Support[0][0])
#if hasattr(documentObject, 'IAm') and documentObject.IAm == 'PartOMagic.Ghost':
# ret = isObjectLattice(documentObject.Base)
return ret
def getMarkerSizeEstimate(ListOfPlacements):
@ -103,13 +104,15 @@ def getMarkerSizeEstimate(ListOfPlacements):
class LatticeFeature(object):
"Base object for lattice objects (arrays of placements)"
attachable = False
def __init__(self,obj):
# please, don't override. Override derivedInit instead.
obj.addProperty('App::PropertyString', 'Type', "Lattice", "module_name.class_name of this object, for proxy recovery", 0, True, True)
obj.Type = self.__module__ + '.' + type(self).__name__
prop = "NumElements"
obj.addProperty("App::PropertyInteger",prop,"Lattice","Info: number of placements in the array")
obj.addProperty("App::PropertyInteger",prop,"Lattice","Info: number of placements in the array", 0, True)
obj.setEditorMode(prop, 1) # set read-only
obj.addProperty("App::PropertyLength","MarkerSize","Lattice","Size of placement markers (set to zero for automatic).")
@ -123,18 +126,106 @@ class LatticeFeature(object):
# Auto-On an Auto-Off can be modified when recomputing. Force values are going to stay.
prop = "ExposePlacement"
obj.addProperty("App::PropertyBool",prop,"Lattice","Makes the placement syncronized to Placement property. This will oftem make this object unmoveable. Not applicable to arrays.")
obj.addProperty("App::PropertyBool",prop,"Lattice","Makes the placement syncronized to Placement property. This will often make this object unmoveable. Not applicable to arrays.")
self.derivedInit(obj)
self.assureProperties(obj, creating_new= True)
self.updateReadonlyness(obj)
if not self.attachable:
self.disableAttacher(obj)
obj.Proxy = self
def assureProperty(self, selfobj, proptype, propname, defvalue, group, tooltip):
def assureProperties(self, selfobj, creating_new = False):
"""#overrideme Method to reconstruct missing properties, that appeared as new functionality was introduced.
Auto called from __init__ (and before derivedInit), and from execute (before derivedExecute)."""
self.assureProperty(selfobj, 'App::PropertyLink', 'ReferencePlacementLink', None, "Lattice", "Link to placement to use as reference placement")
self.assureProperty(selfobj, 'App::PropertyString', 'ReferencePlacementLinkIndex', None, "Lattice", "Index of placement to take from the link. Can also be 'self.0' for own placements.")
self.assureProperty(selfobj, 'App::PropertyBool', 'ReferencePlacementInGlobal', True, "Lattice", "True if reference placement property is in global cs. ", readonly= True)
self.assureProperty(
selfobj,
'App::PropertyPlacement',
'ReferencePlacement',
None,
"Lattice",
"Reference placement, used by 'Populate: build array'. For it, all placements in this array are reinterpreted as relative to this one.",
readonly= True
)
def updateReadonlyness(self, selfobj, bypass_set = set()):
is_lattice = isObjectLattice(selfobj)
extref = 0
if hasattr(selfobj, 'ReferencePlacementOption'):
extref = 0 if selfobj.ReferencePlacementOption == 'external' else 1
rodict = {
'NumElements': 1,
'MarkerSize': 0,
'MarkerShape': 0,
'ReferencePlacement': 1,
'ReferencePlacementLink': extref,
'ReferencePlacementLinkIndex': extref,
'ReferencePlacementInGlobal': 1,
}
for prop in rodict:
if prop in bypass_set: continue
if hasattr(selfobj, prop):
selfobj.setEditorMode(prop, rodict[prop] if is_lattice else 2)
def assureProperty(self, selfobj, proptype, propname, defvalue, group, tooltip, readonly = False, hidden = False):
"""assureProperty(selfobj, proptype, propname, defvalue, group, tooltip): adds
a property if one is missing, and sets its value to default. Does nothing if property
already exists. Returns True if property was created, or False if not."""
return assureProperty(selfobj, proptype, propname, defvalue, group, tooltip)
return assureProperty(selfobj, proptype, propname, defvalue, group, tooltip, readonly, hidden)
def setReferencePlm(self, selfobj, refplm, in_global = False):
"""setReferencePlm(selfobj, refplm, in_global = False): sets reference placement, in internal CS."""
attr = 'ReferencePlacement'
if refplm is None:
refplm = App.Placement()
in_global = True
if selfobj.ExposePlacement:
in_global = True
selfobj.ReferencePlacementInGlobal = in_global
selfobj.ReferencePlacement = refplm
def getReferencePlm(self, selfobj, in_global = False):
"""getReferencePlm(self, selfobj): Returns reference placement in internal CS, or in global CS."""
if not isObjectLattice(selfobj):
return None
if not hasattr(selfobj, 'ReferencePlacement'):
return App.Placement() if in_global else selfobj.Placement.inverse()
if in_global == selfobj.ReferencePlacementInGlobal:
return selfobj.ReferencePlacement
elif in_global == True and selfobj.ReferencePlacementInGlobal == False:
#goal: return == selfobj.Placement * refplm
return selfobj.Placement.multiply(selfobj.ReferencePlacement)
elif in_global == False and selfobj.ReferencePlacementInGlobal == True:
#goal: self.Placement * return == refplm
return selfobj.Placement.inverse().multiply(selfobj.ReferencePlacement)
def recomputeReferencePlm(self, selfobj, selfplacements):
lnk = selfobj.ReferencePlacementLink
strindex = selfobj.ReferencePlacementLinkIndex
is_selfref = lnk is None and strindex.startswith('self.')
ref = selfobj if is_selfref else lnk
if ref is None:
self.setReferencePlm(selfobj, None)
else:
if is_selfref:
index = int(strindex[len('self.'):])
elif len(strindex)>0:
index = int(strindex)
else:
index = 0
if is_selfref:
refplm = selfplacements[index]
self.setReferencePlm(selfobj, refplm, in_global= False)
else:
refplm = getPlacementsList(ref)[index]
self.setReferencePlm(selfobj, refplm, in_global= True)
def derivedInit(self, obj):
'''for overriding by derived classes'''
@ -143,6 +234,8 @@ class LatticeFeature(object):
def execute(self,obj):
# please, don't override. Override derivedExecute instead.
self.assureProperties(obj)
plms = self.derivedExecute(obj)
if plms is not None:
@ -154,6 +247,8 @@ class LatticeFeature(object):
if markerSize < DistConfusion:
markerSize = getMarkerSizeEstimate(plms)
marker = lattice2Markers.getPlacementMarker(scale= markerSize, markerID= obj.MarkerShape)
self.assureProperty(obj, 'App::PropertyLength', 'MarkerSizeActual', markerSize, "Lattice", "Size of placement markers of this array", hidden= True)
obj.MarkerSizeActual = markerSize
bExposing = False
if obj.ExposePlacement:
@ -183,6 +278,7 @@ class LatticeFeature(object):
if obj.isLattice == 'Auto-Off':
obj.isLattice = 'Auto-On'
self.recomputeReferencePlm(obj, plms)
else:
# DerivedExecute didn't return anything. Thus we assume it
# has assigned the shape, and thus we don't do anything.
@ -190,6 +286,7 @@ class LatticeFeature(object):
if obj.isLattice == 'Auto-On':
obj.isLattice = 'Auto-Off'
# i don't remember, wtf is going on here...
if obj.ExposePlacement:
if obj.Shape.ShapeType == "Compound":
children = obj.Shape.childShapes()
@ -201,7 +298,7 @@ class LatticeFeature(object):
else:
#nothing to do - FreeCAD will take care to make obj.Placement and obj.Shape.Placement synchronized.
pass
return
self.updateReadonlyness(obj)
def derivedExecute(self,obj):
'''For overriding by derived class. If this returns a list of placements,
@ -262,13 +359,36 @@ class LatticeFeature(object):
selfobj.MapMode = selfobj.MapMode #trigger attachment, to make it update property states
def onDocumentRestored(self, selfobj):
#override to have attachment!
self.disableAttacher(selfobj)
if not self.attachable:
self.disableAttacher(selfobj)
self.assureProperties(selfobj)
self.updateReadonlyness(selfobj)
class ViewProviderLatticeFeature(object):
"A View Provider for base lattice object"
Object = None # documentobject the vp is attached to
ViewObject = None # viewprovider this proxy is attached to
#coin graph:
# transform #in sync with Placement
# coordinate3 #coordinates for main shape rendering
# switch: #main display mode switch, == self.modenode
# ...
# separator: #reference placement related stuff, == self.refplm_node
# transform #reference placement, == self.refplm_tr
# separator: #actual shape of reference placement, == self.refplm_sh
# ...
# switch: #mode switch of reference placement, == self.modenode_refplm
# ...
modenode = None # main displaymode switch node
refplm_node = None # the node containing everything related to reference placement
refplm_tr = None #transform node of reference placement
refplm_sh = None #node containing the shape of reference placement
modenode_refplm = None # displaymode switch node for reference placement
def __init__(self,vobj):
'''Don't override. Override derivedInit, please!'''
vobj.Proxy = self
@ -292,12 +412,43 @@ class ViewProviderLatticeFeature(object):
except AttributeError as err:
pass # quick-n-dirty fix for Py3. TODO: restore the functionality in Py3, or remove this routine altogether.
def fixProxy(self, vobj):
if vobj is not self.ViewObject:
vobj.Proxy = vobj.ProxyBackup
raise RuntimeError('fixing broken proxy...')
def getIcon(self):
return getIconPath("Lattice.svg")
def attach(self, vobj):
self.ViewObject = vobj
self.Object = vobj.Object
try:
vobj.ProxyBackup = self
except Exception:
vobj.addProperty('App::PropertyPythonObject', 'ProxyBackup', 'Base', "helper property for workaround FC bug #3564", 0, False, True)
vobj.ProxyBackup = self
self.makeRefplmVisual(vobj)
from pivy import coin
self.modenode = next((node for node in vobj.RootNode.getChildren() if node.isOfType(coin.SoSwitch.getClassTypeId())))
def makeRefplmVisual(self, vobj):
import pivy
from pivy import coin
refplm = self.Object.Proxy.getReferencePlm(self.Object)
if refplm is not None:
if not hasattr(self.Object, 'MarkerSizeActual'): return
if self.refplm_node is None:
self.refplm_node, self.refplm_tr, self.refplm_sh = lattice2Markers.getRefPlmMarker(self.Object.MarkerShape)
vobj.RootNode.addChild(self.refplm_node)
self.modenode_refplm = next((node for node in self.refplm_sh.getChildren() if node.isOfType(coin.SoSwitch.getClassTypeId())))
CoinGlue.cointransform(refplm, float(self.Object.MarkerSizeActual) * 1.1, self.refplm_tr)
else:
if hasattr(self, 'refplm_node') and self.refplm_node is not None:
vobj.RootNode.removeChild(self.refplm_node)
self.refplm_node, self.refplm_tr, self.refplm_sh = None, None, None
self.modenode_refplm = None
def __getstate__(self):
return None
@ -325,9 +476,20 @@ class ViewProviderLatticeFeature(object):
FreeCAD.Console.PrintError("Error in onDelete: " + str(err))
return True
def updateData(self, obj, prop):
if prop in ['ReferencePlacement', 'MarkerSizeActual', 'Placement', 'ReferencePlacementInGlobal', 'isLattice']:
self.fixProxy(obj.ViewObject)
self.makeRefplmVisual(obj.ViewObject)
def assureProperty(docobj, proptype, propname, defvalue, group, tooltip):
"""assureProperty(docobj, proptype, propname, defvalue, group, tooltip): adds
def onChanged(self, vobj, prop):
if prop == 'Visibility':
if self.modenode_refplm is not None:
self.modenode_refplm.whichChild.setValue(0 if vobj.Visibility == True else -1)
def assureProperty(docobj, proptype, propname, defvalue, group, tooltip, readonly = False, hidden = False):
"""assureProperty(docobj, proptype, propname, defvalue, group, tooltip, readonly = False, hidden = False): adds
a property if one is missing, and sets its value to default. Does nothing if property
already exists. Returns True if property was created, or False if not."""
@ -335,7 +497,7 @@ def assureProperty(docobj, proptype, propname, defvalue, group, tooltip):
#todo: check type match
return False
docobj.addProperty(proptype, propname, group, tooltip)
docobj.addProperty(proptype, propname, group, tooltip, 0, readonly, hidden)
if defvalue is not None:
setattr(docobj, propname, defvalue)
return True
@ -348,7 +510,7 @@ def makeMoveFromTo(plmFrom, plmTo):
from one placement to another placement'''
return plmTo.multiply(plmFrom.inverse())
def getPlacementsList(documentObject, context = None, suppressWarning = False):
def getPlacementsList(documentObject, context = None, suppressWarning = False, dereferenced = False, torefplm = App.Placement()):
'''getPlacementsList(documentObject, context = None): extract list of placements
from an array object. Context is an object to report as context, when displaying
a warning if the documentObject happens to be a non-lattice.'''
@ -356,7 +518,46 @@ def getPlacementsList(documentObject, context = None, suppressWarning = False):
if not suppressWarning:
lattice2Executer.warning(context, documentObject.Name + " is not a placement or an array of placements. Results may be unexpected.")
leaves = LCE.AllLeaves(documentObject.Shape)
return [leaf.Placement for leaf in leaves]
if not dereferenced:
return [leaf.Placement for leaf in leaves]
else:
# goal: refplm * derefplm == it
# return = torefplm * derefplm
# => return = torefplm * refplm.inverse * it
operator = torefplm.multiply(getReferencePlm(documentObject).inverse())
return [operator.multiply(leaf.Placement) for leaf in leaves]
def getReferencePlm(feature):
"""Obtains reference placement, in container's CS (includes feature.Placement)."""
transform, src = source(feature)
if not isObjectLattice(src):
raise TypeError('getReferencePlm: array of placements expected, got something else.')
return transform.multiply(src.Proxy.getReferencePlm(src))
def source(feature):
"""source(feature): finds the original Lattice array feature from behind shapebinders and such. Returns (transform, lattice_feature).
transform: placement that converts feature's local coordinates into global.
lattice_feature may not actually be an array of placements."""
def _source(feature, visitset):
if hasattr(feature,'isLattice'):
return (feature.Placement, feature)
if feature in visitset:
raise RuntimeError("Dependency loop!")
visitset.append(feature)
if feature.isDerivedFrom('PartDesign::ShapeBinder'):
if len(feature.Support) == 1 and feature.Support[0][1] == ('',):
base = feature.Support[0][0]
transform1, src = _source(base, visitset)
transform = feature.Placement.multiply(base.Placement.inverse().multiply(transform1))
return (transform, src)
if hasattr(feature, 'IAm') and feature.IAm == 'PartOMagic.Ghost':
base = feature.Base
transform1, src = _source(base, visitset)
transform = feature.Placement.multiply(base.Placement.inverse().multiply(transform1))
return (transform, src)
return (feature.Placement, feature)
return _source(feature, list())
def splitSelection(sel):
'''splitSelection(sel): splits sel (use getSelectionEx()) into lattices and non-lattices.

49
lattice2CoinGlue.py Normal file
View File

@ -0,0 +1,49 @@
#***************************************************************************
#* *
#* Copyright (c) 2018 - Victor Titov (DeepSOIC) *
#* <vv.titov@gmail.com> *
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* This program 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 Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with this program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#***************************************************************************
__title__="CoinGlue module of FreeCAD add-on Lattice2"
__author__ = "DeepSOIC"
__url__ = ""
__doc__ = "Glue and conversion routines between coin and freecad"
def cointransform(placement, scale = 1.0, modifyme = None):
"""cointransform(placement, scale = 1.0, modifyme = None): creates/updates SoTransform node from FreeCAD.Placement.
modifyme: the existing node to be modified.
Returns: SoTransform node (new if modifyme is None else modifyme)"""
from pivy import coin
tr = coin.SoTransform() if modifyme is None else modifyme
tr.scaleFactor.setValue(scale,scale,scale)
tr.translation.setValue(*tuple(placement.Base))
tr.rotation.setValue(*placement.Rotation.Q)
return tr
def readNodeFromFile(fullpath):
"""readNodeFromFile(fullpath): reads a file. Returns SoSeparator node, containing the read out stuff."""
from pivy import coin
i = coin.SoInput()
if not i.openFile(fullpath): raise ValueError("Failed to open file: {fn}".format(fn= fullpath))
import pivy
sep = pivy.SoDB.readAll(i)
i.closeFile()
return sep

View File

@ -25,16 +25,11 @@ __title__="Lattice Invert object: creates an array of placements from a compound
__author__ = "DeepSOIC"
__url__ = ""
import math
import FreeCAD as App
import Part
from lattice2Common import *
import lattice2BaseFeature
import lattice2CompoundExplorer as LCE
import lattice2GeomUtils as Utils
import lattice2Executer
# -------------------------- document object --------------------------------------------------
@ -46,8 +41,6 @@ class LatticeInvert(lattice2BaseFeature.LatticeFeature):
"The Lattice Invert object"
def derivedInit(self,obj):
self.Type = "LatticeInvert"
obj.addProperty("App::PropertyLink","Base","Lattice Invert","Lattice, all the placements of which are to be inverted.")
obj.addProperty("App::PropertyEnumeration","TranslateMode","Lattice Invert","What to do with translation part of placements")
@ -58,12 +51,25 @@ class LatticeInvert(lattice2BaseFeature.LatticeFeature):
obj.OrientMode = ['invert', 'keep', 'reset']
obj.OrientMode = 'invert'
def assureProperties(self, selfobj, creating_new = False):
super(LatticeInvert, self).assureProperties(selfobj, creating_new)
self.assureProperty(selfobj, 'App::PropertyEnumeration', 'Referencing', ['Origin', 'Array\'s reference'], "Lattice Invert", "Sets which placement to use as origin")
def derivedExecute(self,obj):
# cache stuff
base = screen(obj.Base).Shape
if not lattice2BaseFeature.isObjectLattice(screen(obj.Base)):
lattice2Executer.warning(obj, "Base is not a lattice, but lattice is expected. Results may be unexpected.\n")
baseChildren = LCE.AllLeaves(base)
placements = lattice2BaseFeature.getPlacementsList(obj.Base)
# dereference
refplm = App.Placement()
if obj.Referencing == 'Origin':
pass
elif obj.Referencing == 'Array\'s reference':
refplm = self.getReferencePlm(obj.Base)
self.setReferencePlm(obj, refplm)
else:
raise NotImplementedError(obj.Referencing)
inv_refplm = refplm.inverse()
locplms = [inv_refplm.multiply(plm) for plm in placements]
#cache mode comparisons, for speed
posIsInvert = obj.TranslateMode == 'invert'
@ -78,26 +84,29 @@ class LatticeInvert(lattice2BaseFeature.LatticeFeature):
outputPlms = [] #list of placements
# the essence
for child in baseChildren:
for plm in locplms:
pos = App.Vector()
ori = App.Rotation()
inverted = child.Placement.inverse()
inverted = plm.inverse()
if posIsInvert:
pos = inverted.Base
elif posIsKeep:
pos = child.Placement.Base
pos = plm.Base
elif posIsReset:
pass
if oriIsInvert:
ori = inverted.Rotation
elif oriIsKeep:
ori = child.Placement.Rotation
ori = plm.Rotation
elif oriIsReset:
pass
plm = App.Placement(pos, ori)
outputPlms.append(plm)
outputPlms.append(App.Placement(pos, ori))
# re-reference
outputPlms = [refplm.multiply(plm) for plm in outputPlms]
return outputPlms
@ -121,6 +130,8 @@ def CreateLatticeInvert(name):
FreeCADGui.addModule("lattice2Executer")
FreeCADGui.doCommand("f = lattice2Invert.makeLatticeInvert(name='"+name+"')")
FreeCADGui.doCommand("f.Base = App.ActiveDocument."+sel[0].ObjectName)
hasref = lattice2BaseFeature.getReferencePlm(sel[0].Object) is not None
FreeCADGui.doCommand("f.Referencing = {r}".format(r= repr('Array\'s reference' if hasref else 'Origin') ))
FreeCADGui.doCommand("for child in f.ViewObject.Proxy.claimChildren():\n"+
" child.ViewObject.hide()")
FreeCADGui.doCommand("lattice2Executer.executeFeature(f)")

View File

@ -49,33 +49,60 @@ class JoinArrays(lattice2BaseFeature.LatticeFeature):
obj.addProperty("App::PropertyBool","Interleave","Lattice JoinArrays","If false, first go all elements of array 1, nect go all elements of array 2, so on. If true, first go all first elements from each array, then all second elements, and so on.")
def assureProperties(self, selfobj, creating_new = False):
super(JoinArrays, self).assureProperties(selfobj, creating_new = False)
created = self.assureProperty(selfobj,
'App::PropertyEnumeration',
'ReferencePlacementOption',
['external', 'origin', 'inherit 1st'],
"Lattice JoinArrays",
"Reference placement, corresponds to the original occurrence of the object to be populated."
)
if created:
selfobj.ReferencePlacementOption = 'inherit 1st'
self.assureProperty(selfobj,
'App::PropertyBool',
'AlignReferences',
False,
"Lattice JoinArrays",
"If true, input arrays will be moved to make their reference placements equal, before joining."
)
def recomputeReferencePlm(self, selfobj, selfplacements): #override
pass #disables standard recompute-reference call. The recompute is handled by derivedExecute
def derivedExecute(self,obj):
#validity check
nonLattices = []
for iArr in range(0, len(obj.Links)):
link = obj.Links[iArr]
if not lattice2BaseFeature.isObjectLattice(link):
nonLattices.append(link.Label)
if len(nonLattices) > 0:
lattice2Executer.warning(obj, "Only lattice objects are expected to be linked as arrays in JoinArrays. There are "
+len(nonLattices)+" objects which are not lattice objects. Results may me unexpected.")
def derivedExecute(self, selfobj):
align = selfobj.AlignReferences
#recompute reference placement
ref = selfobj.ReferencePlacementOption
if ref == 'external':
super(JoinArrays, self).recomputeReferencePlm(selfobj, [])
elif ref == 'origin':
self.setReferencePlm(selfobj, None)
elif ref == 'inherit 1st':
if len(selfobj.Links)>0:
self.setReferencePlm(selfobj, lattice2BaseFeature.getReferencePlm(selfobj.Links[0]))
else:
self.setReferencePlm(selfobj, None)
else:
raise NotImplementedError("Reference option not implemented: " + ref)
refplm = self.getReferencePlm(selfobj)
#extract placements
listlistPlms = []
lengths = []
for link in obj.Links:
leaves = LCE.AllLeaves(link.Shape)
listlistPlms.append([child.Placement for child in leaves])
lengths.append(len(leaves))
for link in selfobj.Links:
plms = lattice2BaseFeature.getPlacementsList(link, context= selfobj, dereferenced= align, torefplm = refplm)
listlistPlms.append(plms)
lengths.append(len(plms))
#processing
output = [] #list of placements
if obj.Interleave:
if selfobj.Interleave:
for l in lengths[1:]:
if l != lengths[0]:
lattice2Executer.warning(obj,"Array lengths are unequal: "+repr(lengths)+". Interleaving will be inconsistent.")
lattice2Executer.warning(selfobj,"Array lengths are unequal: "+repr(lengths)+". Interleaving will be inconsistent.")
break
for iItem in range(0,max(lengths)):
@ -85,6 +112,7 @@ class JoinArrays(lattice2BaseFeature.LatticeFeature):
else:
for list in listlistPlms:
output.extend(list)
return output
class ViewProviderJoinArrays(lattice2BaseFeature.ViewProviderLatticeFeature):
@ -125,14 +153,13 @@ class _CommandJoinArrays:
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Lattice2_JoinArrays","Lattice JoinArrays: concatenate or interleave two or more arrays.")}
def Activated(self):
if len(FreeCADGui.Selection.getSelection()) > 1 :
CreateJoinArrays(name = "Join")
else:
mb = QtGui.QMessageBox()
mb.setIcon(mb.Icon.Warning)
mb.setText(translate("Lattice2_JoinArrays", "Please select at least two lattice objects. Selected lattice objects will be concatenated or interleaved into one array.", None))
mb.setWindowTitle(translate("Lattice2_JoinArrays","Bad selection", None))
mb.exec_()
try:
if len(FreeCADGui.Selection.getSelection()) > 1 :
CreateJoinArrays(name = "Join")
else:
infoMessage("Please select at least two lattice objects. Selected lattice objects will be concatenated or interleaved into one array.")
except Exception as err:
msgError(err)
def IsActive(self):
if FreeCAD.ActiveDocument:

View File

@ -80,16 +80,17 @@ class LinearArray(lattice2BaseFeature.LatticeFeature):
obj.Step = 3.0
obj.Count = 5.0
self.assureProperties(obj)
def updateReadonlyness(self, obj):
super(LinearArray,self).updateReadonlyness(obj)
link = screen(obj.Link)
obj.setEditorMode("Dir", 1 if (link and obj.DirIsDriven) else 0)
obj.setEditorMode("Point", 1 if (link and obj.PointIsDriven) else 0)
obj.setEditorMode("DirIsDriven", 0 if link else 1)
obj.setEditorMode("PointIsDriven", 0 if link else 1)
obj.setEditorMode("DrivenProperty", 0 if link else 1)
obj.setEditorMode('ReferenceValue', 0 if obj.ReferencePlacementOption == 'at custom value' else 2)
self.assureGenerator(obj)
self.generator.updateReadonlyness()
def assureGenerator(self, obj):
@ -101,15 +102,30 @@ class LinearArray(lattice2BaseFeature.LatticeFeature):
groupname_gen= "Lattice Series Generator",
valuesdoc= "List of distances. Distance is measured from Point, along Dir, in millimeters.",
valuestype= "App::PropertyDistance")
self.updateReadonlyness(obj)
def assureProperties(self, selfobj):
def assureProperties(self, selfobj, creating_new = False):
super(LinearArray, self).assureProperties(selfobj, creating_new)
assureProperty(selfobj, "App::PropertyLinkSub", "SubLink", sublinkFromApart(screen(selfobj.Link), selfobj.LinkSubelement), "Lattice Array", "Mirror of Object+SubNames properties")
created = self.assureProperty(selfobj,
'App::PropertyEnumeration',
'ReferencePlacementOption',
['external', 'origin', 'SpanStart', 'SpanEnd', 'at custom value', 'first placement', 'last placement'],
"Lattice Array",
"Reference placement, corresponds to the original occurrence of the object to be populated."
)
if created:
selfobj.ReferencePlacementOption = 'SpanStart'
self.assureProperty(selfobj, 'App::PropertyDistance', 'ReferenceValue', 0.0, "Lattice Array", "Sets the value to use for generating ReferencePlacement. This value sets, what coordinate the object to be populated corresponds to.")
def recomputeReferencePlm(self, selfobj, selfplacements): #override
if selfobj.ReferencePlacementOption == 'external':
super(LinearArray, self).recomputeReferencePlm(selfobj, selfplacements)
#the remaining options are handled in derivedExecute
def derivedExecute(self,obj):
self.assureGenerator(obj)
self.assureProperties(obj)
self.updateReadonlyness(obj)
# Apply links
if screen(obj.Link):
@ -170,9 +186,30 @@ class LinearArray(lattice2BaseFeature.LatticeFeature):
dir.normalize()
# Make the array
def plmByVal(val):
return App.Placement(obj.Point + obj.Dir*val, ori)
output = [] # list of placements
for v in values:
output.append( App.Placement(obj.Point + obj.Dir*v, ori) )
output.append( plmByVal(v) )
# update reference placement
ref = obj.ReferencePlacementOption
if ref == 'external':
pass
elif ref == 'origin':
self.setReferencePlm(obj, None)
elif ref == 'SpanStart':
self.setReferencePlm(obj, plmByVal(float(obj.SpanStart)))
elif ref == 'SpanEnd':
self.setReferencePlm(obj, plmByVal(float(obj.SpanEnd)))
elif ref == 'at custom value':
self.setReferencePlm(obj, plmByVal(float(obj.ReferenceValue)))
elif ref == 'first placement':
self.setReferencePlm(obj, output[0])
elif ref == 'last placement':
self.setReferencePlm(obj, output[-1])
else:
raise NotImplementedError("Reference option not implemented: " + ref)
return output

View File

@ -21,15 +21,19 @@
#* *
#***************************************************************************
import Part, os
import Part
import os
import lattice2CoinGlue as CoinGlue
__title__="latticeMarkers module for FreeCAD"
__author__ = "DeepSOIC"
__url__ = ""
__doc__ = "Module for loading marker shapes for Lattice workbench"
_nullShapeShape = 0
_nullShapeShape = None
_ShapeDict = {}
_NodeDict = {}
def getShapePath(shapeName):
"""
@ -44,7 +48,7 @@ def getNullShapeShape(scale = 1.0):
#read shape from file, if not done this before
global _nullShapeShape
if not _nullShapeShape:
if _nullShapeShape is None:
_nullShapeShape = Part.Shape()
f = open(getShapePath("empty-shape.brep"))
_nullShapeShape.importBrep(f)
@ -75,7 +79,6 @@ def loadShape(shapeID):
_ShapeDict[shapeID] = sh
return sh
def getPlacementMarker(scale = 1.0, markerID = None):
'''getPlacementMarker(scale = 1.0, markerID = None): returns a placement marker shape.
The shape is scaled according to "scale" argument.
@ -87,3 +90,27 @@ def getPlacementMarker(scale = 1.0, markerID = None):
sh = sh.copy()
sh.scale(scale)
return sh
def loadNode(shapeID):
global _NodeDict
nd = _NodeDict.get(shapeID)
if nd is None:
nd = CoinGlue.readNodeFromFile(getShapePath(shapeID + '.iv'))
_NodeDict[shapeID] = nd
nd.ref() # not sure if needed, but won't hurt.
return nd.copy()
def getRefPlmMarker(markerID, placement = None, scale = 1.0):
'''getRefPlmMarker(markerID, placement = None, scale = 1.0): returns a coin placement marker shape, as SoSeparator (+ transform node + shape node).
The shape is scaled according to "scale" argument.
markerID sets the marker file name.'''
sh = loadNode(markerID + '-refplm')
from pivy import coin
sep = coin.SoSeparator()
tr = coin.SoTransform()
if placement is not None:
CoinGlue.cointransform(placement, scale, tr)
sep.addChild(tr)
sep.addChild(sh)
return (sep, tr, sh)

View File

@ -33,7 +33,7 @@ import lattice2BaseFeature
import lattice2Executer
from lattice2ShapeCopy import shallowCopy, transformCopy_Smart
from lattice2PopulateCopies import DereferenceArray
from lattice2PopulateCopies import DereferenceArray, REF_MODES
class FeatureUnsupportedError(RuntimeError):
@ -182,7 +182,7 @@ class LatticePDPattern(object):
obj.addProperty('App::PropertyLink','PlacementsTo',"Lattice Pattern","Target placements")
obj.addProperty('App::PropertyEnumeration','Referencing',"Lattice Pattern","Reference placement mode (sets what to grab the feature by).")
obj.Referencing = ['Origin','First item', 'Last item', 'Use PlacementsFrom']
obj.Referencing = REF_MODES
obj.addProperty('App::PropertyBool', 'IgnoreUnsupported', "Lattice Pattern", "Skip unsupported features such as fillets, instead of throwing errors")
obj.addProperty('App::PropertyBool', 'SkipFirstInBody', "Lattice Pattern", "Skip first body feature (which may be used as support for the important features).")
@ -250,8 +250,7 @@ class LatticePDPattern(object):
raise ScopeError('Reference placement and the feature are not in the same body (use Shapebinder or Ghost to bring the placement in).')
placements = lattice2BaseFeature.getPlacementsList(selfobj.PlacementsTo, selfobj)
placements = DereferenceArray(selfobj, placements, selfobj.PlacementsFrom, selfobj.Referencing)
placements = DereferenceArray(selfobj, selfobj.PlacementsTo, selfobj.PlacementsFrom, selfobj.Referencing)
if selfobj.Referencing == 'First item' and transforms is None:
placements.pop(0) #to not repeat the feature where it was applied already
elif selfobj.Referencing == 'Last item' and transforms is None:

View File

@ -123,12 +123,16 @@ class LatticeParaSeries(lattice2BaseFeature.LatticeFeature):
self.generator.addProperties(groupname= "Lattice ParaSeries",
groupname_gen= "Lattice ParaSeries Generator",
valuesdoc= "List of parameter values to compute object for.")
def updateReadonlyness(self, selfobj):
super(LatticeParaSeries, self).updateReadonlyness(selfobj)
self.assureGenerator(selfobj)
self.generator.updateReadonlyness()
def derivedExecute(self,selfobj):
# values generator should be functional even if recomputing is disabled, so do it first
self.assureGenerator(selfobj)
self.generator.updateReadonlyness()
self.generator.execute()
if selfobj.Recomputing == "Disabled":

View File

@ -75,8 +75,6 @@ class PolarArray(lattice2BaseFeature.LatticeFeature):
obj.EndInclusive = False
obj.Count = 5
self.assureProperties(obj)
def assureGenerator(self, obj):
'''Adds an instance of value series generator, if one doesn't exist yet.'''
if hasattr(self,"generator"):
@ -89,21 +87,24 @@ class PolarArray(lattice2BaseFeature.LatticeFeature):
self.updateReadonlyness(obj)
def updateReadonlyness(self, obj):
super(PolarArray, self).updateReadonlyness(obj)
axislink = screen(obj.AxisLink)
obj.setEditorMode("AxisDir", 1 if (axislink and obj.AxisDirIsDriven) else 0)
obj.setEditorMode("AxisPoint", 1 if (axislink and obj.AxisPointIsDriven) else 0)
obj.setEditorMode("AxisDirIsDriven", 0 if axislink else 1)
obj.setEditorMode("AxisPointIsDriven", 0 if axislink else 1)
self.assureGenerator(obj)
self.generator.updateReadonlyness()
def assureProperties(self, selfobj):
def assureProperties(self, selfobj, creating_new = False):
super(PolarArray, self).assureProperties(selfobj, creating_new)
assureProperty(selfobj, "App::PropertyLinkSub", "AxisSubLink", sublinkFromApart(screen(selfobj.AxisLink), selfobj.AxisLinkSubelement), "Lattice Array", "Mirror of Object+SubNames properties")
def derivedExecute(self,obj):
self.assureGenerator(obj)
self.assureProperties(obj)
self.updateReadonlyness(obj)
# Apply links
if screen(obj.AxisLink):

View File

@ -45,7 +45,7 @@ V = App.Vector
def make():
'''make(): makes a PolarArray object.'''
obj = lattice2BaseFeature.makeLatticeFeature('PolarArray', PolarArray, ViewProviderPolarArray, no_disable_attacher= True)
obj = lattice2BaseFeature.makeLatticeFeature('PolarArray', PolarArray, ViewProviderPolarArray)
return obj
def fetchArc(obj, sub):
@ -86,6 +86,21 @@ class PolarArray(APlm.AttachableFeature):
selfobj.Step = 55
selfobj.Count = 7
def assureProperties(self, selfobj, creating_new = False):
super(PolarArray, self).assureProperties(selfobj, creating_new)
# upgrades older versions of the feature
created = self.assureProperty(selfobj,
'App::PropertyEnumeration',
'ReferencePlacementOption',
['external', 'origin', 'center', 'SpanStart', 'SpanEnd', 'at custom value', 'first placement', 'last placement'],
"Polar Array",
"Reference placement, corresponds to the original occurrence of the object to be populated."
)
if created:
selfobj.ReferencePlacementOption = 'SpanStart'
self.assureProperty(selfobj, 'App::PropertyFloat', 'ReferenceValue', 0.0, "Polar Array", "Sets the value to use for generating ReferencePlacement. This value sets, what angle the object to be populated corresponds to.")
def assureGenerator(self, selfobj):
'''Adds an instance of value series generator, if one doesn't exist yet.'''
if hasattr(self,'generator'):
@ -95,13 +110,16 @@ class PolarArray(APlm.AttachableFeature):
groupname_gen= "Lattice Series Generator",
valuesdoc= "List of angles, in degrees.",
valuestype= 'App::PropertyFloat')
self.updateReadonlyness(selfobj)
def updateReadonlyness(self, selfobj):
super(PolarArray, self).updateReadonlyness(selfobj)
self.assureGenerator(selfobj)
self.generator.updateReadonlyness()
arc = self.fetchArc(selfobj)
selfobj.setEditorMode('Radius', 1 if arc and selfobj.UseArcRadius else 0)
selfobj.setEditorMode('ReferenceValue', 0 if selfobj.ReferencePlacementOption == 'at custom value' else 2)
self.generator.setPropertyWritable('SpanEnd', False if arc and selfobj.UseArcRange == 'as Span' else True)
self.generator.setPropertyWritable('SpanStart', False if arc and selfobj.UseArcRange == 'as Span' else True)
self.generator.setPropertyWritable('Step', False if arc and selfobj.UseArcRange == 'as Step' else True)
@ -114,6 +132,11 @@ class PolarArray(APlm.AttachableFeature):
#resolve the link
return fetchArc(lnkobj, sub)
def recomputeReferencePlm(self, selfobj, selfplacements): #override
if selfobj.ReferencePlacementOption == 'external':
super(PolarArray, self).recomputeReferencePlm(selfobj, selfplacements)
#the remaining options are handled in derivedExecute
def derivedExecute(self,selfobj):
self.assureGenerator(selfobj)
self.updateReadonlyness(selfobj)
@ -189,7 +212,7 @@ class PolarArray(APlm.AttachableFeature):
angleplus = -90.0 if on_arc else 0.0
mm = -1.0 if selfobj.Reverse else +1.0
output = [] # list of placements
for ang in values:
def plmByVal(ang):
localrot = App.Rotation(App.Vector(0,0,1), ang * mm + angleplus)
localtransl = localrot.multVec(App.Vector(radius,0,0))
localplm = App.Placement(localtransl, localrot)
@ -200,7 +223,29 @@ class PolarArray(APlm.AttachableFeature):
elif is_static:
resultplm.Rotation = App.Rotation()
resultplm = resultplm.multiply(flipplm)
output.append(resultplm)
return resultplm
output = [plmByVal(ang) for ang in values]
# update reference placement
ref = selfobj.ReferencePlacementOption
if ref == 'external':
pass #gets done in recomputeReferencePlm
elif ref == 'origin':
self.setReferencePlm(selfobj, None)
elif ref == 'center':
self.setReferencePlm(selfobj, App.Placement())
elif ref == 'SpanStart':
self.setReferencePlm(selfobj, plmByVal(selfobj.SpanStart))
elif ref == 'SpanEnd':
self.setReferencePlm(selfobj, plmByVal(selfobj.SpanEnd))
elif ref == 'at custom value':
self.setReferencePlm(selfobj, plmByVal(selfobj.ReferenceValue))
elif ref == 'first placement':
self.setReferencePlm(selfobj, output[0])
elif ref == 'last placement':
self.setReferencePlm(selfobj, output[-1])
else:
raise NotImplementedError("Reference option not implemented: " + ref)
return output

View File

@ -34,7 +34,7 @@ from lattice2Common import *
import lattice2BaseFeature
import lattice2CompoundExplorer as LCE
import lattice2Executer
from lattice2PopulateCopies import DereferenceArray, throwBody
from lattice2PopulateCopies import DereferenceArray, throwBody, REF_MODES
import lattice2ShapeCopy as ShapeCopy
# -------------------------- document object --------------------------------------------------
@ -58,7 +58,7 @@ class LatticePopulateChildren(lattice2BaseFeature.LatticeFeature):
obj.addProperty("App::PropertyBool","LoopObjectSequence","Lattice PopulateChildren","If true, children of Object will be traversed in a loop if there are more placements than children. Otherwise, extra placements will be dropped.")
obj.addProperty("App::PropertyEnumeration","Referencing","Lattice PopulateChildren","Reference for array of placements.")
obj.Referencing = ["Origin","First item", "Last item", "Use PlacementsFrom"]
obj.Referencing = REF_MODES
obj.addProperty("App::PropertyLink","PlacementsTo","Lattice PopulateChildren", "Placement or array of placements, containing target locations.")
@ -88,11 +88,10 @@ class LatticePopulateChildren(lattice2BaseFeature.LatticeFeature):
raise ValueError("Traversal mode not implemented: "+obj.ObjectTraversal)
else:
objectPlms = lattice2BaseFeature.getPlacementsList(screen(obj.Object), obj)
placements = lattice2BaseFeature.getPlacementsList(screen(obj.PlacementsTo), obj)
# Precompute referencing
placements = DereferenceArray(obj, placements, screen(obj.PlacementsFrom), obj.Referencing)
placements = DereferenceArray(obj, obj.PlacementsTo, screen(obj.PlacementsFrom), obj.Referencing)
# initialize output containers and loop variables
outputShapes = [] #output list of shapes
@ -101,6 +100,20 @@ class LatticePopulateChildren(lattice2BaseFeature.LatticeFeature):
numChildren = len(objectPlms) if outputIsLattice else len(objectShapes)
copy_method_index = ShapeCopy.getCopyTypeIndex(obj.Copying)
#inherit reference placement from the array being copied
if outputIsLattice:
refplm = None
if obj.Referencing == 'Array\'s reference' or obj.Referencing == 'First item' or obj.Referencing == 'Last item':
#simple cases - we just copy the reference plm from the object
refplm = lattice2BaseFeature.getReferencePlm(obj.Object)
else:
#other cases - apply first transform to reference placement
refplm = lattice2BaseFeature.getReferencePlm(obj.Object)
if refplm is not None and len(placements) > 0:
refplm = placements[0].multiply(refplm)
self.setReferencePlm(obj, refplm)
# the essence
for iPlm in range(len(placements)):
if iChild == numChildren:
@ -176,6 +189,11 @@ def CreateLatticePopulateChildren(name, label, shapeObj, latticeObjFrom, lattice
FreeCADGui.doCommand("f.PlacementsTo = App.ActiveDocument."+latticeObjTo.Name)
if latticeObjFrom is not None:
FreeCADGui.doCommand("f.PlacementsFrom = App.ActiveDocument."+latticeObjFrom.Name)
if refmode == 'Auto':
if lattice2BaseFeature.getReferencePlm(latticeObjTo) is not None:
refmode = 'Array\'s reference'
else:
refmode = 'First item'
FreeCADGui.doCommand("f.Referencing = "+repr(refmode))
FreeCADGui.doCommand("f.Label = " + repr(label))

View File

@ -37,13 +37,16 @@ import lattice2Executer
import lattice2ShapeCopy as ShapeCopy
# ---------------------------shared code--------------------------------------
def DereferenceArray(obj,placements, lnkFrom, refmode):
REF_MODES = ['Origin', 'First item', 'Last item', 'Use PlacementsFrom', 'Array\'s reference']
def DereferenceArray(obj, lnkTo, lnkFrom, refmode):
'''common implementation of treatment Referencing property. Returns a list of placements to use directly.
obj - feature being executed (used for error reporting; can be None)
placements - the array, converted into a list of placements.
obj - feature being executed
lnkTo - the array of target placements (documentobject).
lnkFrom - object linked as a lattice of 'from' placements. Can be None, if mode is not 'Use PlacemenetsFrom'
refmode - a string - enum property item'''
placements = lattice2BaseFeature.getPlacementsList(lnkTo, obj)
plmDeref = App.Placement() #inverse placement of reference (reference is a substitute of origin)
if lnkFrom is not None and refmode != "Use PlacementsFrom":
lattice2Executer.warning(obj,"Referencing mode is '"+refmode+"', doesn't need PlacementsFrom link to be set. The link is set, but it will be ignored.")
@ -52,7 +55,7 @@ def DereferenceArray(obj,placements, lnkFrom, refmode):
elif refmode == "First item":
plmDeref = placements[0].inverse()
elif refmode == "Last item":
plmDeref = placements[0].inverse()
plmDeref = placements[-1].inverse()
elif refmode == "Use PlacementsFrom":
if lnkFrom is None:
raise ValueError("Referencing mode is 'Move from to', but PlacementsFrom link is not set.")
@ -63,8 +66,13 @@ def DereferenceArray(obj,placements, lnkFrom, refmode):
return [lattice2BaseFeature.makeMoveFromTo(placementsFrom[i], placements[i]) for i in range(0, len(placements))]
else:
lattice2Executer.warning(obj,"Lengths of arrays linked as PlacementsTo and PlacementsFrom must equal, or PlacementsFrom can be one placement. Violation: lengths are "+str(len(placements))+ " and "+str(len(placementsFrom)))
elif refmode == 'Array\'s reference':
plmRef = lattice2BaseFeature.getReferencePlm(lnkTo)
if plmRef is None:
raise AttributeError('Object {obj} does not expose a reference placement.')
plmDeref = plmRef.inverse()
else:
raise ValueError("Referencing mode not implemented: "+refmode)
raise ValueError("Referencing mode not implemented: " + refmode)
return [plm.multiply(plmDeref) for plm in placements]
@ -85,40 +93,54 @@ class LatticePopulateCopies(lattice2BaseFeature.LatticeFeature):
obj.addProperty("App::PropertyLink","Object","Lattice PopulateCopies","Base object. Can be any generic shape, as well as another lattice object.")
obj.addProperty("App::PropertyEnumeration","Referencing","Lattice PopulateCopies","Reference for array of placements.")
obj.Referencing = ["Origin","First item", "Last item", "Use PlacementsFrom"]
obj.Referencing = REF_MODES
obj.addProperty("App::PropertyLink","PlacementsTo","Lattice PopulateCopies", "Placement or array of placements, containing target locations.")
obj.addProperty("App::PropertyLink","PlacementsFrom", "Lattice PopulateCopies","Placement or array of placements to be treated as origins for PlacementsTo.")
self.assureProperties(obj)
obj.OutputCompounding = "(autosettle)" # this is default value for new features.
def assureProperties(self, obj):
def assureProperties(self, obj, creating_new = False):
'''Adds properties that might be missing, because of loaded project made with older version. Handles version compatibility.'''
super(LatticePopulateCopies, self).assureProperties(obj, creating_new)
propname = 'OutputCompounding'
if not hasattr(obj,propname):
obj.addProperty("App::PropertyEnumeration", propname, "Lattice PopulateCopies","In case single object copy is made, this property controls, if it's packed into compoud or not.")
setattr(obj,propname,["(autosettle)","always", "only if many"])
setattr(obj,propname,"always") # this is to match the old behavior. This is not the default setting for new features.
if creating_new:
obj.OutputCompounding = "(autosettle)" # this is default value for new features.
else:
setattr(obj,propname,"always") # this is to match the old behavior. This is not the default setting for new features.
if self.assureProperty(obj, "App::PropertyEnumeration","Copying", ShapeCopy.copy_types, "Lattice PopulateChildren", "Sets, what method to use for copying shapes."):
self.Copying = ShapeCopy.copy_types[0]
def derivedExecute(self,obj):
self.assureProperties(obj)
# cache stuff
objectShape = screen(obj.Object).Shape
placements = lattice2BaseFeature.getPlacementsList(screen(obj.PlacementsTo), obj)
outputIsLattice = lattice2BaseFeature.isObjectLattice(screen(obj.Object))
# Pre-collect base placement list, if base is a lattice. For speed.
if outputIsLattice:
objectPlms = lattice2BaseFeature.getPlacementsList(screen(obj.Object),obj)
placements = DereferenceArray(obj, placements, screen(obj.PlacementsFrom), obj.Referencing)
placements = DereferenceArray(obj, obj.PlacementsTo, screen(obj.PlacementsFrom), obj.Referencing)
#inherit reference placement from the array being copied
if outputIsLattice:
refplm = None
if obj.Referencing == 'Array\'s reference' or obj.Referencing == 'First item' or obj.Referencing == 'Last item':
#simple cases - we just copy the reference plm from the object
refplm = lattice2BaseFeature.getReferencePlm(obj.Object)
else:
#other cases - apply first transform to reference placement
refplm = lattice2BaseFeature.getReferencePlm(obj.Object)
if refplm is not None and len(placements) > 0:
refplm = placements[0].multiply(refplm)
self.setReferencePlm(obj, refplm)
# initialize output containers and loop variables
outputShapes = [] #output list of shapes
@ -161,18 +183,20 @@ class ViewProviderLatticePopulateCopies(lattice2BaseFeature.ViewProviderLatticeF
def getIcon(self):
if lattice2BaseFeature.isObjectLattice(self.Object):
return getIconPath(
{"Origin":"Lattice2_PopulateCopies_Plms_Normal.svg",
"First item":"Lattice2_PopulateCopies_Plms_Array.svg",
"Last item":"Lattice2_PopulateCopies_Plms_Array.svg",
"Use PlacementsFrom":"Lattice2_PopulateCopies_Plms_Move.svg",
{'Origin':'Lattice2_PopulateCopies_Plms_Normal.svg',
'First item':'Lattice2_PopulateCopies_Plms_Array.svg',
'Last item':'Lattice2_PopulateCopies_Plms_Array.svg',
'Use PlacementsFrom':'Lattice2_PopulateCopies_Plms_Move.svg',
'Array\'s reference':'Lattice2_PopulateCopies_Plms_Ref.svg',
}[self.Object.Referencing]
)
else:
return getIconPath(
{"Origin":"Lattice2_PopulateCopies_Normal.svg",
"First item":"Lattice2_PopulateCopies_Array.svg",
"Last item":"Lattice2_PopulateCopies_Array.svg",
"Use PlacementsFrom":"Lattice2_PopulateCopies_Move.svg",
{'Origin':'Lattice2_PopulateCopies_Normal.svg',
'First item':'Lattice2_PopulateCopies_Array.svg',
'Last item':'Lattice2_PopulateCopies_Array.svg',
'Use PlacementsFrom':'Lattice2_PopulateCopies_Move.svg',
'Array\'s reference':'Lattice2_PopulateCopies_Ref.svg',
}[self.Object.Referencing]
)
@ -199,6 +223,11 @@ def CreateLatticePopulateCopies(name, label, shapeObj, latticeObjFrom, latticeOb
FreeCADGui.doCommand("f.PlacementsTo = App.ActiveDocument."+latticeObjTo.Name)
if latticeObjFrom is not None:
FreeCADGui.doCommand("f.PlacementsFrom = App.ActiveDocument."+latticeObjFrom.Name)
if refmode == 'Auto':
if lattice2BaseFeature.getReferencePlm(latticeObjTo) is not None:
refmode = 'Array\'s reference'
else:
refmode = 'First item'
FreeCADGui.doCommand("f.Referencing = "+repr(refmode))
FreeCADGui.doCommand("f.Label = " + repr(label))
@ -220,72 +249,83 @@ def CreateLatticePopulateCopies(name, label, shapeObj, latticeObjFrom, latticeOb
def throwBody():
raise SelectionError("PartDesign mode", "You can't use population tools on shapes in partdesign body. Use Lattice PartDesign Pattern instead. Or deactivate active body to use populate tools on shapes.")
def cmdPopulate_shapes_nonFromTo(refmode):
def cmdPopulateCopies():
sel = FreeCADGui.Selection.getSelectionEx()
(lattices, shapes) = lattice2BaseFeature.splitSelection(sel)
if activeBody() and len(shapes)>0:
throwBody()
if len(shapes) > 0 and len(lattices) == 1:
FreeCAD.ActiveDocument.openTransaction("Populate with copies")
lattice = lattices[0]
for shape in shapes:
CreateLatticePopulateCopies("Populate",u"Populate "+lattice.Object.Label+u" with "+shape.Object.Label,shape.Object,None,lattice.Object,refmode)
deselect(sel)
FreeCAD.ActiveDocument.commitTransaction()
elif len(shapes) == 1 and len(lattices) > 1:
shape = shapes[0]
FreeCAD.ActiveDocument.openTransaction("Populate with copies")
for lattice in lattices:
CreateLatticePopulateCopies("Populate",u"Populate "+lattice.Object.Label+u" with "+shape.Object.Label,shape.Object,None,lattice.Object,refmode)
deselect(sel)
FreeCAD.ActiveDocument.commitTransaction()
elif len(shapes) == 0 and len(lattices) == 2:
shape = lattices[0]
lattice = lattices[1]
FreeCAD.ActiveDocument.openTransaction("Populate with copies")
CreateLatticePopulateCopies("Populate",u"Populate "+lattice.Object.Label+u" with "+shape.Object.Label,shape.Object,None,lattice.Object,refmode)
deselect(sel)
FreeCAD.ActiveDocument.commitTransaction()
else:
raise SelectionError("Bad selection","Please select some shapes and some arrays, first. You can select multiple shapes and one array, or multiple arrays and one shape.")
def cmdPopulate_shapes_FromTo():
sel = FreeCADGui.Selection.getSelectionEx()
(lattices, shapes) = lattice2BaseFeature.splitSelection(sel)
if activeBody() and len(shapes)>0:
throwBody()
if len(shapes) == 0 and len(sel) >= 3:
shapes = sel[:-2]
lattices = sel[-2:]
if len(shapes) > 0 and len(lattices) == 2:
FreeCAD.ActiveDocument.openTransaction("Populate with copies")
# move shapes from to
FreeCAD.ActiveDocument.openTransaction("Transport")
latticeFrom = lattices[0]
latticeTo = lattices[1]
for shape in shapes:
CreateLatticePopulateCopies("Populate",u"Moved "+shape.Object.Label, shape.Object, latticeFrom.Object, latticeTo.Object,"Use PlacementsFrom")
CreateLatticePopulateCopies("Populate",u"Moved "+shape.Object.Label, shape.Object, latticeFrom.Object, latticeTo.Object,'Use PlacementsFrom')
deselect(sel)
FreeCAD.ActiveDocument.commitTransaction()
elif len(shapes) == 0 and len(lattices) == 3:
# move array from to
FreeCAD.ActiveDocument.openTransaction("Transport")
shape = lattices[0]
latticeFrom = lattices[1]
latticeTo = lattices[2]
for shape in shapes:
CreateLatticePopulateCopies("Populate",u"Moved "+shape.Object.Label, shape.Object, latticeFrom.Object, latticeTo.Object,'Use PlacementsFrom')
deselect(sel)
FreeCAD.ActiveDocument.commitTransaction()
elif len(shapes) > 0 and len(lattices) == 1:
# populate shapes
FreeCAD.ActiveDocument.openTransaction("Populate with copies")
lattice = lattices[0]
for shape in shapes:
CreateLatticePopulateCopies("Populate",u"Populate "+lattice.Object.Label+u" with "+shape.Object.Label,shape.Object,None,lattice.Object,'Auto')
deselect(sel)
FreeCAD.ActiveDocument.commitTransaction()
elif len(shapes) == 0 and (len(lattices) == 2 or len(lattices) > 3):
# populate placements
FreeCAD.ActiveDocument.openTransaction("Populate with copies")
shapes = lattices[:-1]
lattice = lattices[-1]
for shape in shapes:
CreateLatticePopulateCopies("Populate",u"Populate "+lattice.Object.Label+u" with "+shape.Object.Label, shape.Object, None, lattice.Object,'Auto')
deselect(sel)
FreeCAD.ActiveDocument.commitTransaction()
else:
raise SelectionError("Bad selection","Please select either:\n one or more shapes, and two placements/arrays \nor\nthree placements/arrays")
raise SelectionError("Bad selection",
"You selected {n_lattices} arrays of placements and {n_shapes} shapes. This is not supported.\n\n"
"You can select:\n"
" * N shapes and 1 array, to populate that array with the shapes\n"
" * N shapes and 2 arrays, to move shapes from array1 to array2\n"
" * 2 arrays, to populate array2 with array1\n"
" * 3 arrays, to move array1 from array2 to array3\n"
" * 4 or more arrays, to populate last array with all other arrays"
.format(n_lattices= len(lattices), n_shapes= len(shapes))
)
class _CommandLatticePopulateCopies_Normal:
class CommandLatticePopulateCopies:
"Command to create LatticePopulateCopies feature"
def GetResources(self):
return {'Pixmap' : getIconPath("Lattice2_PopulateCopies_Normal.svg"),
'MenuText': QtCore.QT_TRANSLATE_NOOP("Lattice2_PopulateCopies","Populate with copies"),
return {'Pixmap' : getIconPath("Lattice2_PopulateCopies.svg"),
'MenuText': "Populate with copies",
'Accel': "",
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Lattice2_PopulateCopies","Populate with copies: put copies of an object at every placement in an array. Select the object(s) to be copied, and the placement/array.")}
'ToolTip': "Populate with copies: put copies of an object at every placement in an array. Select the object(s) to be copied, and the placement/array."}
def Activated(self):
try:
if len(FreeCADGui.Selection.getSelection())==0:
infoMessage("Populate with copies",
"Populate with copies command. Places a copy of a selected object placed under selected placement.\n\n"+
"Populate with copies command. Places a copy of a selected object at every placement in an array of placements.\n\n"+
"Please select some objects, and a placement/an array of placements. Then invoke the command.\n\n"+
"A copy of object will pe made and placed in local coordinate system of each placement in an array. Placement of the object is taken into account, and becomes a placement in local coordinates of a placement of the array item.")
"You can select:\n"
" * N shapes and 1 array, to populate that array with the shapes\n"
" * N shapes and 2 arrays, to move shapes from array1 to array2\n"
" * 2 arrays, to populate array2 with array1\n"
" * 3 arrays, to move array1 from array2 to array3\n"
" * 4 or more arrays, to populate last array with all other arrays"
)
return
cmdPopulate_shapes_nonFromTo("Origin")
cmdPopulateCopies()
except Exception as err:
msgError(err)
@ -296,85 +336,9 @@ class _CommandLatticePopulateCopies_Normal:
return False
if FreeCAD.GuiUp:
FreeCADGui.addCommand('Lattice2_PopulateCopies_Normal', _CommandLatticePopulateCopies_Normal())
FreeCADGui.addCommand('Lattice2_PopulateCopies', CommandLatticePopulateCopies())
class _CommandLatticePopulateCopies_Array:
"Command to create LatticePopulateCopies feature"
def GetResources(self):
return {'Pixmap' : getIconPath("Lattice2_PopulateCopies_Array.svg"),
'MenuText': QtCore.QT_TRANSLATE_NOOP("Lattice2_PopulateCopies","Populate with copies: Build Array"),
'Accel': "",
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Lattice2_PopulateCopies","Populate with copies: Build Array: poplate placements with copies so that the array passes through original shape. Select the object(s) to be copied, and the placement/array.")}
def Activated(self):
try:
if len(FreeCADGui.Selection.getSelection())==0:
infoMessage("Populate with copies: Build Array",
"Populate with copies: Build Array command. Creates an array of shapes.\n\n"+
"Please select some objects, and the array of placements. Then invoke the command. Object can also be a placement/array.\n\n"+
"Compared to plain 'Populate With copies' command, the placements are treated as being relative to the first placement in the array. As a result, the array built always includes the original object as-is.")
return
cmdPopulate_shapes_nonFromTo("First item")
except Exception as err:
msgError(err)
def IsActive(self):
if FreeCAD.ActiveDocument:
return True
else:
return False
if FreeCAD.GuiUp:
FreeCADGui.addCommand('Lattice2_PopulateCopies_Array', _CommandLatticePopulateCopies_Array())
class _CommandLatticePopulateCopies_Move:
"Command to create LatticePopulateCopies feature"
def GetResources(self):
return {'Pixmap' : getIconPath("Lattice2_PopulateCopies_Move.svg"),
'MenuText': QtCore.QT_TRANSLATE_NOOP("Lattice2_PopulateCopies","Moved object"),
'Accel': "",
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Lattice2_PopulateCopies","Moved object: move object from one placement to another placement. Select the object, placement to move from, and placement to move to. Arrays of placements are accepted.")}
def Activated(self):
try:
if len(FreeCADGui.Selection.getSelection())==0:
infoMessage("Moved Object",
"Moved Object command. Creates a moved copy of a shape.\n\n"+
"The shape is moved from one placement to another placement. Please select some shapes, then placement to move from, and placement to move to (order matters).\n"+
"Placement 'to' can be an array of placements; the array of objects will be created in this case. If 'to' is an array, 'from' can be either a single placement, or an array of matching length.\n\n"+
"Object can itself be an array of placements.")
return
cmdPopulate_shapes_FromTo()
except Exception as err:
msgError(err)
def IsActive(self):
if FreeCAD.ActiveDocument:
return True
else:
return False
if FreeCAD.GuiUp:
FreeCADGui.addCommand('Lattice2_PopulateCopies_Move', _CommandLatticePopulateCopies_Move())
class _CommandLatticePopulateCopiesGroup:
def GetCommands(self):
return ("Lattice2_PopulateCopies_Normal","Lattice2_PopulateCopies_Array","Lattice2_PopulateCopies_Move")
def GetDefaultCommand(self): # return the index of the tuple of the default command.
return 0
def GetResources(self):
return { 'MenuText': 'Populate with copies:',
'ToolTip': 'Populate with copies: put a copy of an object at every placement in an array of placements.'}
def IsActive(self): # optional
return True
if FreeCAD.GuiUp:
FreeCADGui.addCommand('Lattice2_PopulateCopiesGroupCommand',_CommandLatticePopulateCopiesGroup())
exportedCommands = ['Lattice2_PopulateCopiesGroupCommand']
exportedCommands = ['Lattice2_PopulateCopies']
# -------------------------- /Gui command --------------------------------------------------

View File

@ -65,21 +65,37 @@ class LatticeProjectArray(lattice2BaseFeature.LatticeFeature):
obj.addProperty("App::PropertyEnumeration","Multisolution","Lattice ProjectArray","Specify the way of dealing with multiple solutions of projection")
obj.Multisolution = ['use first','use all']
def assureProperties(self, selfobj, creating_new = False):
super(LatticeProjectArray, self).assureProperties(selfobj, creating_new)
created = self.assureProperty(selfobj,
'App::PropertyEnumeration',
'ReferencePlacementOption',
['external', 'origin', 'inherit', 'projected'],
"Lattice ProjectArray",
"Reference placement, corresponds to the original occurrence of the object to be populated."
)
if created:
selfobj.ReferencePlacementOption = 'inherit'
def recomputeReferencePlm(self, selfobj, selfplacements): #override
if selfobj.ReferencePlacementOption == 'external':
super(LinearProjectArray, self).recomputeReferencePlm(selfobj, selfplacements)
#the remaining options are handled in derivedExecute
def derivedExecute(self,obj):
#validity check
if not lattice2BaseFeature.isObjectLattice(screen(obj.Base)):
lattice2Executer.warning(obj,"A lattice object is expected as Base, but a generic shape was provided. It will be treated as a lattice object; results may be unexpected.")
toolShape = screen(obj.Tool).Shape
if lattice2BaseFeature.isObjectLattice(screen(obj.Tool)):
lattice2Executer.warning(obj,"A lattice object was provided as Tool. It will be converted into points; orientations will be ignored.")
leaves = LCE.AllLeaves(toolShape)
points = [Part.Vertex(leaf.Placement.Base) for leaf in leaves]
lattice2Executer.warning(obj, "A lattice object was provided as Tool. It will be converted into points; orientations will be ignored.")
plms = lattice2BaseFeature.getPlacementsList(obj.Tool)
points = [Part.Vertex(plm.Base) for plm in plms]
toolShape = Part.makeCompound(points)
leaves = LCE.AllLeaves(screen(obj.Base).Shape)
input = [leaf.Placement for leaf in leaves]
ref = obj.ReferencePlacementOption
input = lattice2BaseFeature.getPlacementsList(obj.Base, obj)
if ref == 'projected':
input.append(lattice2BaseFeature.getReferencePlm(obj.Base))
output = [] #variable to receive the final list of placements
@ -170,6 +186,17 @@ class LatticeProjectArray(lattice2BaseFeature.LatticeFeature):
if not isMultiSol:
break
if ref == 'external':
pass
elif ref == 'origin':
self.setReferencePlm(obj, None)
elif ref == 'inherit':
self.setReferencePlm(obj, lattice2BaseFeature.getReferencePlm(obj.Base))
elif ref == 'projected':
self.setReferencePlm(obj, output.pop())
else:
raise NotImplementedError("Reference option not implemented: " + ref)
return output
@ -189,7 +216,7 @@ def CreateLatticeProjectArray(name):
iLtc = 0 #index of lattice object in selection
iStc = 1 #index of stencil object in selection
for i in range(0,len(sel)):
if lattice2BaseFeature.isObjectLattice(sel[i]):
if lattice2BaseFeature.isObjectLattice(sel[i].Object):
iLtc = i
iStc = i-1 #this may give negative index, but python accepts negative indexes
break

257
lattice2Resample2.py Normal file
View File

@ -0,0 +1,257 @@
#***************************************************************************
#* *
#* Copyright (c) 2018 - Victor Titov (DeepSOIC) *
#* <vv.titov@gmail.com> *
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* This program 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 Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with this program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#***************************************************************************
__title__="Lattice Resample object: changes the number of placements in an array, maintaining overall path. Aka interpolation."
__author__ = "DeepSOIC"
__url__ = ""
import FreeCAD as App
import Part
from lattice2Common import *
import lattice2BaseFeature
import lattice2InterpolatorUtil as LIU
import lattice2Executer
from lattice2ValueSeriesGenerator import ValueSeriesGenerator
# -------------------------- document object --------------------------------------------------
def dotProduct(list1,list2):
sum = 0
for i in range(0,len(list1)):
sum += list1[i]*list2[i]
return sum
def makeLatticeResample(name):
'''makeLatticeResample(name): makes a LatticeResample object.'''
return lattice2BaseFeature.makeLatticeFeature(name, LatticeResample, ViewProviderLatticeResample)
class LatticeResample(lattice2BaseFeature.LatticeFeature):
"The Lattice Resample object"
def derivedInit(self,selfobj):
selfobj.addProperty("App::PropertyLink","Base","Lattice Resample","Lattice, the array of placements to be interpolated.")
selfobj.addProperty("App::PropertyEnumeration","TranslateMode","Lattice Resample","What to do with translation part of placements")
selfobj.TranslateMode = ['interpolate', 'reset']
selfobj.TranslateMode = 'interpolate'
selfobj.addProperty("App::PropertyEnumeration","OrientMode","Lattice Resample","what to do with orientation part of placements")
selfobj.OrientMode = ['interpolate', 'reset']
selfobj.OrientMode = 'interpolate'
self.assureGenerator(selfobj)
selfobj.ValuesSource = "Generator"
selfobj.GeneratorMode = "SpanN"
selfobj.EndInclusive = True
selfobj.SpanStart = 0.0
selfobj.SpanEnd = 1.0
selfobj.Step = 1.0/51.0
selfobj.Count = 51
def assureProperties(self, selfobj, creating_new = False):
super(LatticeResample, self).assureProperties(selfobj, creating_new)
created = self.assureProperty(selfobj,
'App::PropertyEnumeration',
'ReferencePlacementOption',
['external', 'origin', 'inherit', 'SpanStart', 'SpanEnd', 'at custom value', 'first placement', 'last placement'],
"Lattice Resample",
"Reference placement, corresponds to the original occurrence of the object to be populated."
)
if created:
selfobj.ReferencePlacementOption = 'SpanStart'
self.assureProperty(selfobj, 'App::PropertyFloat', 'ReferenceValue', 0.0, "Lattice Resample", "Sets the value to use for generating ReferencePlacement. This value sets, what coordinate the object to be populated corresponds to.")
def assureGenerator(self, selfobj):
'''Adds an instance of value series generator, if one doesn't exist yet.'''
if hasattr(self,"generator"):
return
self.generator = ValueSeriesGenerator(selfobj)
self.generator.addProperties(groupname= "Lattice Array",
groupname_gen= "Lattice Series Generator",
valuesdoc= "List of parameter values. Values should be in range 0..n-1 for interpolation, and can be outside for extrapolation.",
valuestype= "App::PropertyFloat")
def updateReadonlyness(self, selfobj):
super(LatticeResample, self).updateReadonlyness(selfobj)
self.assureGenerator(selfobj)
self.generator.updateReadonlyness()
selfobj.setEditorMode('ReferenceValue', 0 if selfobj.ReferencePlacementOption == 'at custom value' else 2)
def recomputeReferencePlm(self, selfobj, selfplacements): #override
if selfobj.ReferencePlacementOption == 'external':
super(LatticeResample, self).recomputeReferencePlm(selfobj, selfplacements)
#the remaining options are handled in derivedExecute
def derivedExecute(self,selfobj):
self.assureGenerator(selfobj)
self.generator.execute()
values = [float(strv) for strv in selfobj.Values]
input = lattice2BaseFeature.getPlacementsList(selfobj.Base)
if len(input) < 2:
raise ValueError("At least 2 placements ar needed to interpolate; there are just "+str(len(input))+" in base array.")
#cache mode comparisons, for speed
posIsInterpolate = selfobj.TranslateMode == 'interpolate'
posIsReset = selfobj.TranslateMode == 'reset'
oriIsInterpolate = selfobj.OrientMode == 'interpolate'
oriIsReset = selfobj.OrientMode == 'reset'
# construct interpolation functions
# prepare lists of input samples
IArray = [float(i) for i in range(0,len(input))]
XArray = [plm.Base.x for plm in input]
YArray = [plm.Base.y for plm in input]
ZArray = [plm.Base.z for plm in input]
QArrays = [[],[],[],[]]
prevQ = [0.0]*4
for plm in input:
Q = plm.Rotation.Q
#test if quaernion has changed sign compared to previous one.
# Quaternions of opposite sign are equivalent in terms of rotation,
# but sign changes confuse interpolation, so we are detecting sign
# changes and discarding them
if dotProduct(Q,prevQ) < -ParaConfusion:
Q = [-v for v in Q]
for iQ in [0,1,2,3]:
QArrays[iQ].append( Q[iQ] )
prevQ = Q
# constuct function objects
if posIsInterpolate:
FX = LIU.InterpolateF(IArray,XArray)
FY = LIU.InterpolateF(IArray,YArray)
FZ = LIU.InterpolateF(IArray,ZArray)
if oriIsInterpolate:
FQs = []
for iQ in [0,1,2,3]:
FQs.append(LIU.InterpolateF(IArray,QArrays[iQ]))
def plmByVal(val):
pos = App.Vector()
ori = App.Rotation()
if posIsInterpolate:
pos = App.Vector(FX.value(val), FY.value(val), FZ.value(val))
if oriIsInterpolate:
ori = App.Rotation(FQs[0].value(val),
FQs[1].value(val),
FQs[2].value(val),
FQs[3].value(val))
return App.Placement(pos, ori)
output = [plmByVal(val) for val in values]
# update reference placement
ref = selfobj.ReferencePlacementOption
if ref == 'external':
pass
elif ref == 'origin':
self.setReferencePlm(selfobj, None)
elif ref == 'inherit':
self.setReferencePlm(selfobj, lattice2BaseFeature.getReferencePlm(selfobj.Base))
elif ref == 'SpanStart':
self.setReferencePlm(selfobj, plmByVal(float(selfobj.SpanStart)))
elif ref == 'SpanEnd':
self.setReferencePlm(selfobj, plmByVal(float(selfobj.SpanEnd)))
elif ref == 'at custom value':
self.setReferencePlm(selfobj, plmByVal(float(selfobj.ReferenceValue)))
elif ref == 'first placement':
self.setReferencePlm(selfobj, output[0])
elif ref == 'last placement':
self.setReferencePlm(selfobj, output[-1])
else:
raise NotImplementedError("Reference option not implemented: " + ref)
return output
class ViewProviderLatticeResample(lattice2BaseFeature.ViewProviderLatticeFeature):
def getIcon(self):
return getIconPath('Lattice2_Resample.svg')
def claimChildren(self):
return [screen(self.Object.Base)]
# -------------------------- /document object --------------------------------------------------
# -------------------------- Gui command --------------------------------------------------
def CreateLatticeResample(name):
sel = FreeCADGui.Selection.getSelectionEx()
FreeCAD.ActiveDocument.openTransaction("Create LatticeResample")
FreeCADGui.addModule("lattice2Resample2")
FreeCADGui.addModule("lattice2Executer")
FreeCADGui.doCommand("f = lattice2Resample2.makeLatticeResample(name='"+name+"')")
FreeCADGui.doCommand("f.Base = App.ActiveDocument."+sel[0].ObjectName)
FreeCADGui.doCommand("f.setExpression('SpanEnd', '{base}.NumElements - 1')".format(base= lattice2BaseFeature.source(sel[0].Object)[1].Name))
FreeCADGui.doCommand("for child in f.ViewObject.Proxy.claimChildren():\n"+
" child.ViewObject.hide()")
FreeCADGui.doCommand("lattice2Executer.executeFeature(f)")
FreeCADGui.doCommand("f = None")
FreeCAD.ActiveDocument.commitTransaction()
class _CommandLatticeResample:
"Command to create LatticeResample feature"
def GetResources(self):
return {'Pixmap' : getIconPath("Lattice2_Resample.svg"),
'MenuText': QtCore.QT_TRANSLATE_NOOP("Lattice2_Resample","Resample Array"),
'Accel': "",
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Lattice2_Resample","Lattice Resample: interpolate placement-path using 3-rd degree b-spline interpolation.")}
def Activated(self):
try:
if len(FreeCADGui.Selection.getSelection()) == 1 :
CreateLatticeResample(name = "Resample")
else:
infoMessage(
"Lattice Resample command. Interpolates an array of placements, using 3-rd dergee bsplines.\n\n"
"Please select one object, first. The object must be an array of placements."
)
except Exception as err:
msgError(err)
def IsActive(self):
if FreeCAD.ActiveDocument:
return True
else:
return False
if FreeCAD.GuiUp:
FreeCADGui.addCommand('Lattice2_Resample2', _CommandLatticeResample())
exportedCommands = ['Lattice2_Resample2']
# -------------------------- /Gui command --------------------------------------------------

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -0,0 +1,149 @@
#Inventor V2.1 ascii
PickStyle {
style UNPICKABLE
}
Coordinate3 {
point [ 2.4286127e-017 2.3747374e-017 0,
1 0 0,
-0.28144613 -0.48747897 0,
2.4286127e-017 2.3747374e-017 0,
-0.28144613 0.48747897 0,
1 0 0,
2.4286127e-017 2.3747374e-017 0,
1 0 0,
0 -6.3415941e-017 -0.28560001,
2.4286127e-017 2.3747374e-017 0,
1 0 0,
-0.28144613 -0.48747897 0,
-0.28144613 0.48747897 0,
0 -6.3415941e-017 -0.28560001 ]
}
Switch {
whichChild 0
Separator {
DEF myLines Separator {
MaterialBinding {
value OVERALL
}
Material {
ambientColor 0.2 0.2 0.2
diffuseColor 0.33333334 0.65490198 0.87058824
specularColor 0 0 0
emissiveColor 0 0 0
shininess 1
transparency 0
}
DrawStyle {
style LINES
lineWidth 2
linePattern 0xffff
}
SoBrepEdgeSet {
fields [ SFNode vertexProperty, MFInt32 coordIndex, MFInt32 materialIndex, MFInt32 normalIndex, MFInt32 textureCoordIndex, SFInt32 highlightIndex, MFInt32 selectionIndex ]
coordIndex [ 0, 1, -1, 1, 2, -1, 2, 0,
-1, 3, 4, -1, 4, 5, -1, 8,
6, -1, 7, 8, -1 ]
highlightIndex -1
selectionIndex -1
}
}
PolygonOffset {
}
DEF myFaces Separator {
ShapeHints {
vertexOrdering UNKNOWN_ORDERING
shapeType UNKNOWN_SHAPE_TYPE
}
MaterialBinding {
value OVERALL
}
Material {
ambientColor 0.2 0.2 0.2
diffuseColor 0 0.66666669 1
specularColor 0 0 0
emissiveColor 0 0 0
shininess 0.2
transparency 0.5
}
DrawStyle {
style FILLED
}
Normal {
vector [ 0 0 1,
0 0 1,
0 0 1,
0 0 1,
0 0 1,
0 0 1,
0 -1 2.220446e-016,
0 -1 2.220446e-016,
0 -1 2.220446e-016 ]
}
NormalBinding {
value PER_VERTEX_INDEXED
}
SoBrepFaceSet {
fields [ SFNode vertexProperty, MFInt32 coordIndex, MFInt32 materialIndex, MFInt32 normalIndex, MFInt32 textureCoordIndex, MFInt32 partIndex, SFInt32 highlightIndex, MFInt32 selectionIndex ]
coordIndex [ 1, 0, 2, -1, 5, 4, 3, -1,
7, 6, 8, -1 ]
partIndex [ 1, 1, 1 ]
highlightIndex -1
selectionIndex -1
}
}
DEF myPoints Separator {
MaterialBinding {
value OVERALL
}
Material {
ambientColor 0.2 0.2 0.2
diffuseColor 0.25490198 0.67450982 0.89803922
specularColor 0 0 0
emissiveColor 0 0 0
shininess 1
transparency 0
}
DrawStyle {
style POINTS
pointSize 2
}
SoBrepPointSet {
fields [ SFNode vertexProperty, SFInt32 startIndex, SFInt32 numPoints, SFInt32 highlightIndex, MFInt32 selectionIndex ]
startIndex 9
highlightIndex -1
selectionIndex [ 9, 10, 11, 12, 13 ]
}
}
}
USE myFaces
Separator {
USE myLines
USE myPoints
}
USE myPoints
}

Binary file not shown.

View File

@ -0,0 +1,160 @@
#Inventor V2.1 ascii
PickStyle {
style UNPICKABLE
}
Coordinate3 {
point [ 0 0 0,
-1.7347235e-018 -0.30000001 1.3877788e-017,
1.7347235e-018 0.30000001 -2.1359844e-015,
-1.7347235e-018 8.3193401e-018 0.30000001,
1.7347235e-018 0.30000001 -2.1359844e-015,
0 0 0,
1 -2.7755576e-017 -2.0816682e-017,
-1.7347235e-018 -0.30000001 1.3877788e-017,
-1.7347235e-018 -0.30000001 1.3877788e-017,
1 -2.7755576e-017 -2.0816682e-017,
-1.7347235e-018 8.3193401e-018 0.30000001,
1 -2.7755576e-017 -2.0816682e-017,
-1.7347235e-018 8.3193401e-018 0.30000001,
1.7347235e-018 0.30000001 -2.1359844e-015,
0 0 0,
-1.7347235e-018 -0.30000001 1.3877788e-017,
1.7347235e-018 0.30000001 -2.1359844e-015,
-1.7347235e-018 8.3193401e-018 0.30000001,
1 -2.7755576e-017 -2.0816682e-017 ]
}
Switch {
whichChild 0
Separator {
DEF myLines Separator {
MaterialBinding {
value OVERALL
}
Material {
ambientColor 0.2 0.2 0.2
diffuseColor 0.33333334 0.65490198 0.87058824
specularColor 0 0 0
emissiveColor 0 0 0
shininess 1
transparency 0
}
DrawStyle {
style LINES
lineWidth 2
linePattern 0xffff
}
SoBrepEdgeSet {
fields [ SFNode vertexProperty, MFInt32 coordIndex, MFInt32 materialIndex, MFInt32 normalIndex, MFInt32 textureCoordIndex, SFInt32 highlightIndex, MFInt32 selectionIndex ]
coordIndex [ 0, 1, -1, 2, 0, -1, 1, 3,
-1, 3, 2, -1, 4, 6, -1, 7,
6, -1, 9, 10, -1 ]
highlightIndex 6
selectionIndex -1
}
}
PolygonOffset {
}
DEF myFaces Separator {
ShapeHints {
vertexOrdering UNKNOWN_ORDERING
shapeType UNKNOWN_SHAPE_TYPE
}
MaterialBinding {
value OVERALL
}
Material {
ambientColor 0.2 0.2 0.2
diffuseColor 0 0.66666669 1
specularColor 0 0 0
emissiveColor 0 0 0
shininess 0.2
transparency 0.5
}
DrawStyle {
style FILLED
}
Normal {
vector [ -1 0 0,
-1 0 0,
-1 0 0,
-1 0 0,
0 0 -1,
0 0 -1,
0 0 -1,
0 0 -1,
0.20751435 -0.69171447 0.69171447,
0.20751435 -0.69171447 0.69171447,
0.20751435 -0.69171447 0.69171447,
0.20751435 0.69171447 0.69171447,
0.20751435 0.69171447 0.69171447,
0.20751435 0.69171447 0.69171447 ]
}
NormalBinding {
value PER_VERTEX_INDEXED
}
SoBrepFaceSet {
fields [ SFNode vertexProperty, MFInt32 coordIndex, MFInt32 materialIndex, MFInt32 normalIndex, MFInt32 textureCoordIndex, MFInt32 partIndex, SFInt32 highlightIndex, MFInt32 selectionIndex ]
coordIndex [ 1, 3, 0, -1, 0, 3, 2, -1,
4, 6, 5, -1, 5, 6, 7, -1,
10, 8, 9, -1, 13, 12, 11, -1 ]
partIndex [ 2, 2, 1, 1 ]
highlightIndex -1
selectionIndex -1
}
}
DEF myPoints Separator {
MaterialBinding {
value OVERALL
}
Material {
ambientColor 0.2 0.2 0.2
diffuseColor 0.25490198 0.67450982 0.89803922
specularColor 0 0 0
emissiveColor 0 0 0
shininess 1
transparency 0
}
DrawStyle {
style POINTS
pointSize 2
}
SoBrepPointSet {
fields [ SFNode vertexProperty, SFInt32 startIndex, SFInt32 numPoints, SFInt32 highlightIndex, MFInt32 selectionIndex ]
startIndex 14
highlightIndex -1
selectionIndex [ 14, 15, 16, 17, 18 ]
}
}
}
USE myFaces
Separator {
USE myLines
USE myPoints
}
USE myPoints
}