fixed and new options for contour scanner
This commit is contained in:
parent
7c2de7d7e3
commit
7d863c7040
@ -6,7 +6,7 @@
|
|||||||
<page name="tab_settings" gui-text="Settings">
|
<page name="tab_settings" gui-text="Settings">
|
||||||
<label appearance="header">General</label>
|
<label appearance="header">General</label>
|
||||||
<param name="show_debug" type="bool" gui-text="Show debug infos">false</param>
|
<param name="show_debug" type="bool" gui-text="Show debug infos">false</param>
|
||||||
<param name="break_apart" type="bool" gui-text="Break apart input" gui-description="Break apart input paths into sub paths. Modifies original paths">false</param>
|
<param name="break_apart" type="bool" gui-text="Break apart input" gui-description="Break apart input paths into sub paths. Modifies original paths: converts to absolute paths and might create additional new path elements.">false</param>
|
||||||
<param name="handle_groups" type="bool" gui-text="Handle groups" gui-description="Also looks for paths in groups which are in the current selection. Note: The generated results have a different structure (less granularity due to grouping) than directly selected paths. The colorization for non-intersected paths will be different too.">false</param>
|
<param name="handle_groups" type="bool" gui-text="Handle groups" gui-description="Also looks for paths in groups which are in the current selection. Note: The generated results have a different structure (less granularity due to grouping) than directly selected paths. The colorization for non-intersected paths will be different too.">false</param>
|
||||||
<param name="path_types" type="optiongroup" appearance="combo" gui-text="Scanning selection" gui-description="Process open paths by other open paths, closed paths by other closed paths, or all paths by all other paths">
|
<param name="path_types" type="optiongroup" appearance="combo" gui-text="Scanning selection" gui-description="Process open paths by other open paths, closed paths by other closed paths, or all paths by all other paths">
|
||||||
<option value="both">all:all paths</option>
|
<option value="both">all:all paths</option>
|
||||||
@ -17,26 +17,32 @@
|
|||||||
<param name="flatness" type="float" min="0.001" max="99999.000" precision="3" gui-text="Flatness (tolerance)" gui-description="Minimum flatness = 0.001. The smaller the value the more fine segments you will get (quantization). Large values might destroy the line continuity.">0.100</param>
|
<param name="flatness" type="float" min="0.001" max="99999.000" precision="3" gui-text="Flatness (tolerance)" gui-description="Minimum flatness = 0.001. The smaller the value the more fine segments you will get (quantization). Large values might destroy the line continuity.">0.100</param>
|
||||||
<param name="decimals" type="int" min="0" max="16" gui-text="Decimals" gui-description="Accuracy for sub split lines / lines trimmed by shapely (default: 3)">3</param>
|
<param name="decimals" type="int" min="0" max="16" gui-text="Decimals" gui-description="Accuracy for sub split lines / lines trimmed by shapely (default: 3)">3</param>
|
||||||
<param name="snap_tolerance" type="float" min="0.01" max="10.0" gui-text="Snap tolerance" gui-description="Snap tolerance for intersection points on paths (default: 0.1)">0.1</param>
|
<param name="snap_tolerance" type="float" min="0.01" max="10.0" gui-text="Snap tolerance" gui-description="Snap tolerance for intersection points on paths (default: 0.1)">0.1</param>
|
||||||
<param name="draw_subsplit" type="bool" gui-text="Draw sub split lines (for debugging purposes)" gui-description="Draws polylines. Will be automatically enabled if any highlighting below is activated.">false</param>
|
<param name="draw_subsplit" type="bool" gui-text="Draw sub split lines (for debugging purposes)" gui-description="Draws polylines. Will be automatically enabled if any highlighting is activated.">false</param>
|
||||||
</page>
|
</page>
|
||||||
<page name="tab_scanning" gui-text="Scanning and Trimming">
|
<page name="tab_scanning" gui-text="Scanning and Trimming">
|
||||||
<hbox>
|
<hbox>
|
||||||
<vbox>
|
<vbox>
|
||||||
<label appearance="header">Removing</label>
|
<label appearance="header">Removing Original Paths</label>
|
||||||
<param name="remove_polylines" type="bool" gui-text="Remove original polylines paths">false</param>
|
<param name="remove_relative" type="bool" gui-text="relative cmd">false</param>
|
||||||
<param name="remove_beziers" type="bool" gui-text="Remove original beziers paths">false</param>
|
<param name="remove_absolute" type="bool" gui-text="absolute cmd">false</param>
|
||||||
<param name="remove_opened" type="bool" gui-text="Remove original opened paths">false</param>
|
<param name="remove_mixed" type="bool" gui-text="mixed cmd" gui-description="combined relative and absolute">false</param>
|
||||||
<param name="remove_closed" type="bool" gui-text="Remove original closed paths">false</param>
|
<param name="remove_polylines" type="bool" gui-text="polylines">false</param>
|
||||||
|
<param name="remove_beziers" type="bool" gui-text="beziers">false</param>
|
||||||
|
<param name="remove_opened" type="bool" gui-text="opened">false</param>
|
||||||
|
<param name="remove_closed" type="bool" gui-text="closed">false</param>
|
||||||
<param name="remove_self_intersecting" type="bool" gui-text="Remove original self-intersecting paths">false</param>
|
<param name="remove_self_intersecting" type="bool" gui-text="Remove original self-intersecting paths">false</param>
|
||||||
<separator/>
|
<separator/>
|
||||||
<label appearance="header">Highlighting</label>
|
<label appearance="header">Highlighting</label>
|
||||||
<param name="highlight_polylines" type="bool" gui-text="Highlight polyline paths">false</param>
|
<param name="highlight_relative" type="bool" gui-text="relative cmd paths">false</param>
|
||||||
<param name="highlight_beziers" type="bool" gui-text="Highlight bezier paths">false</param>
|
<param name="highlight_absolute" type="bool" gui-text="absolute cmd paths">false</param>
|
||||||
<param name="highlight_opened" type="bool" gui-text="Highlight opened paths">false</param>
|
<param name="highlight_mixed" type="bool" gui-text="mixed cmd paths" gui-description="combined relative and absolute">false</param>
|
||||||
<param name="highlight_closed" type="bool" gui-text="Highlight closed paths">false</param>
|
<param name="highlight_polylines" type="bool" gui-text="polyline paths">false</param>
|
||||||
<param name="highlight_self_intersecting" type="bool" gui-text="Highlight self-intersecting paths" gui-description="Requires to draw sub split lines. Will override highlighting colors for open and closed paths (if those options are enabled)">false</param>
|
<param name="highlight_beziers" type="bool" gui-text="bezier paths">false</param>
|
||||||
<param name="visualize_self_intersections" type="bool" gui-text="Visualize self-intersecting path points">false</param>
|
<param name="highlight_opened" type="bool" gui-text="opened paths">false</param>
|
||||||
<param name="visualize_global_intersections" type="bool" gui-text="Visualize global intersection points" gui-description="Will also contain self-intersecting points!">false</param>
|
<param name="highlight_closed" type="bool" gui-text="closed paths">false</param>
|
||||||
|
<param name="highlight_self_intersecting" type="bool" gui-text="self-intersecting paths" gui-description="Requires to draw sub split lines. Will override highlighting colors for open and closed paths (if those options are enabled)">false</param>
|
||||||
|
<param name="visualize_self_intersections" type="bool" gui-text="self-intersecting path points">false</param>
|
||||||
|
<param name="visualize_global_intersections" type="bool" gui-text="global intersection points" gui-description="Will also contain self-intersecting points!">false</param>
|
||||||
</vbox>
|
</vbox>
|
||||||
<separator/>
|
<separator/>
|
||||||
<vbox>
|
<vbox>
|
||||||
@ -59,21 +65,24 @@
|
|||||||
<param name="removefillsetstroke" type="bool" gui-text="Remove fill and define stroke" gui-description="Modifies original path style">false</param>
|
<param name="removefillsetstroke" type="bool" gui-text="Remove fill and define stroke" gui-description="Modifies original path style">false</param>
|
||||||
<param name="apply_original_style" type="bool" gui-text="Original style for trimmed lines" gui-description="Apply original path style to trimmed lines.">true</param>
|
<param name="apply_original_style" type="bool" gui-text="Original style for trimmed lines" gui-description="Apply original path style to trimmed lines.">true</param>
|
||||||
<label appearance="header">Scanning Colors</label>
|
<label appearance="header">Scanning Colors</label>
|
||||||
<param name="color_polyline" type="color" appearance="colorbutton" gui-text="Color for polyline paths">4289703935</param>
|
<param name="color_subsplit" type="color" appearance="colorbutton" gui-text="sub split lines">1630897151</param>
|
||||||
<param name="color_bezier" type="color" appearance="colorbutton" gui-text="Color for bezier paths">258744063</param>
|
<param name="color_relative" type="color" appearance="colorbutton" gui-text="relative cmd paths">3419879935</param>
|
||||||
<param name="color_opened" type="color" appearance="colorbutton" gui-text="Color for opened paths">4012452351</param>
|
<param name="color_absolute" type="color" appearance="colorbutton" gui-text="absolute cmd paths">1592519679</param>
|
||||||
<param name="color_closed" type="color" appearance="colorbutton" gui-text="Color for closed paths">2330080511</param>
|
<param name="color_mixed" type="color" appearance="colorbutton" gui-text="mixed cmd paths" gui-description="combined relative and absolute">3351636735</param>
|
||||||
<param name="color_self_intersecting_paths" type="color" appearance="colorbutton" gui-text="Color for self-intersecting contours">2593756927</param>
|
<param name="color_polyline" type="color" appearance="colorbutton" gui-text="polyline paths">4289703935</param>
|
||||||
<param name="color_subsplit" type="color" appearance="colorbutton" gui-text="Color for sub split lines">1630897151</param>
|
<param name="color_bezier" type="color" appearance="colorbutton" gui-text="bezier paths">258744063</param>
|
||||||
<param name="color_self_intersections" type="color" appearance="colorbutton" gui-text="Color for self-intersecting line points">6320383</param>
|
<param name="color_opened" type="color" appearance="colorbutton" gui-text="opened paths">4012452351</param>
|
||||||
<param name="color_global_intersections" type="color" appearance="colorbutton" gui-text="Color for global intersection points">4239343359</param>
|
<param name="color_closed" type="color" appearance="colorbutton" gui-text="closed paths">2330080511</param>
|
||||||
|
<param name="color_self_intersecting_paths" type="color" appearance="colorbutton" gui-text="self-intersecting contours">2593756927</param>
|
||||||
|
<param name="color_self_intersections" type="color" appearance="colorbutton" gui-text="self-intersecting line points">6320383</param>
|
||||||
|
<param name="color_global_intersections" type="color" appearance="colorbutton" gui-text="global intersection points">4239343359</param>
|
||||||
</vbox>
|
</vbox>
|
||||||
<separator/>
|
<separator/>
|
||||||
<vbox>
|
<vbox>
|
||||||
<label appearance="header">Trimming Colors</label>
|
<label appearance="header">Trimming Colors</label>
|
||||||
<param name="color_trimmed" type="color" appearance="colorbutton" gui-text="Color for trimmed lines">3227634687</param>
|
<param name="color_trimmed" type="color" appearance="colorbutton" gui-text="trimmed lines">3227634687</param>
|
||||||
<param name="color_combined" type="color" appearance="colorbutton" gui-text="Color for non-intersected lines" gui-description="Colorize non-trimmed lines differently than the trimmed ones. Does not apply if 'Original style for trimmed lines' is enabled">1923076095</param>
|
<param name="color_combined" type="color" appearance="colorbutton" gui-text="non-intersected lines" gui-description="Colorize non-trimmed lines differently than the trimmed ones. Does not apply if 'Original style for trimmed lines' is enabled">1923076095</param>
|
||||||
<param name="color_nonintersected" type="color" appearance="colorbutton" gui-text="Color for non-intersected paths" gui-description="Colorize the complete path in case it does not contain any trim. Does not apply if 'Original style for trimmed lines' is enabled">3045284607</param>
|
<param name="color_nonintersected" type="color" appearance="colorbutton" gui-text="non-intersected paths" gui-description="Colorize the complete path in case it does not contain any trim. Does not apply if 'Original style for trimmed lines' is enabled">3045284607</param>
|
||||||
</vbox>
|
</vbox>
|
||||||
</hbox>
|
</hbox>
|
||||||
</page>
|
</page>
|
||||||
|
@ -4,7 +4,14 @@
|
|||||||
Extension for InkScape 1.0+
|
Extension for InkScape 1.0+
|
||||||
- WARNING: HORRIBLY SLOW CODE. PLEASE HELP TO MAKE IT USEFUL FOR LARGE AMOUNT OF PATHS
|
- WARNING: HORRIBLY SLOW CODE. PLEASE HELP TO MAKE IT USEFUL FOR LARGE AMOUNT OF PATHS
|
||||||
- add options:
|
- add options:
|
||||||
- find line parts which are included in other lines and perform intersections/splittings (overlapping colinear lines)
|
- efficiently find overlapping colinear lines by checking their slope/gradient
|
||||||
|
- get all lines and sort by slope; kick out all slopes which are unique. We only want re-occuring slopes
|
||||||
|
- intersects() is equivalent to the OR-ing of contains(), crosses(), equals(), touches(), and within().
|
||||||
|
So there might be some cases where two lines intersect eachother without crossing,
|
||||||
|
in particular when one line contains another or when two lines are equals.
|
||||||
|
- crosses() returns True if the dimension of the intersection is less than the dimension of the one or the other.
|
||||||
|
So if two lines overlap, they won't be considered as "crossing". intersection() will return a geometric object.
|
||||||
|
|
||||||
- replace trimmed paths by bezier paths (calculating lengths and required t parameter)
|
- replace trimmed paths by bezier paths (calculating lengths and required t parameter)
|
||||||
- find more duplicates
|
- find more duplicates
|
||||||
- overlapping lines in sub splits
|
- overlapping lines in sub splits
|
||||||
@ -25,6 +32,7 @@ Extension for InkScape 1.0+
|
|||||||
each other line (line1.intersection(line2) using two for-loops) because this
|
each other line (line1.intersection(line2) using two for-loops) because this
|
||||||
kind of logic is really really slow for huge amount. You could use that only
|
kind of logic is really really slow for huge amount. You could use that only
|
||||||
for ~50-100 elements. So we use special algorihm (Bentley-Ottmann)
|
for ~50-100 elements. So we use special algorihm (Bentley-Ottmann)
|
||||||
|
- Cool tool to visualize sweep line algorithm Bentley-Ottmann: https://bl.ocks.org/1wheel/464141fe9b940153e636
|
||||||
|
|
||||||
- things to look at more closely:
|
- things to look at more closely:
|
||||||
- https://gis.stackexchange.com/questions/203048/split-lines-at-points-using-shapely
|
- https://gis.stackexchange.com/questions/203048/split-lines-at-points-using-shapely
|
||||||
@ -39,24 +47,9 @@ Extension for InkScape 1.0+
|
|||||||
Author: Mario Voigt / FabLab Chemnitz
|
Author: Mario Voigt / FabLab Chemnitz
|
||||||
Mail: mario.voigt@stadtfabrikanten.org
|
Mail: mario.voigt@stadtfabrikanten.org
|
||||||
Date: 09.08.2020 (extension originally called "Contour Scanner")
|
Date: 09.08.2020 (extension originally called "Contour Scanner")
|
||||||
Last patch: 01.06.2021
|
Last patch: 04.06.2021
|
||||||
License: GNU GPL v3
|
License: GNU GPL v3
|
||||||
|
|
||||||
|
|
||||||
efficiently find overlapping lines
|
|
||||||
- loope durch alle straihgt lines und berechne deren steigung -< einsortieren der linien nach steigung
|
|
||||||
- wenn die steigung noch nicht erfasst wurde, dann adde die line in eine collection aller in frage kommenden linien
|
|
||||||
- loope durch die vorfilterung und check für shapely
|
|
||||||
|
|
||||||
intersects() is equivalent to the OR-ing of contains(), crosses(), equals(), touches(), and within().
|
|
||||||
So there might be some cases where two lines intersect eachother without crossing,
|
|
||||||
in particular when one line contains another or when two lines are equals.
|
|
||||||
More specifically:
|
|
||||||
crosses() returns True [...] if the dimension of the intersection is less than the dimension of the one or the other.
|
|
||||||
So if two lines overlap, they won't be considered as "crossing".
|
|
||||||
intersection() will return a geometric object.
|
|
||||||
|
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
@ -306,13 +299,12 @@ class ContourScannerAndTrimmer(inkex.EffectExtension):
|
|||||||
|
|
||||||
def combine_nonintersects(self, allTrimGroups, apply_original_style):
|
def combine_nonintersects(self, allTrimGroups, apply_original_style):
|
||||||
'''
|
'''
|
||||||
combine and chain all non intersected sub split lines which were trimmed at intersection points before.
|
combine and chain all non intersected sub split lines which were trimmed at intersection points before.
|
||||||
- At first we sort out all lines by their id:
|
- At first we sort out all lines by their id:
|
||||||
- if the lines id contains intersectedVerb, we ignore it
|
- if the lines id contains intersectedVerb, we ignore it
|
||||||
- we combine all lines which do not contain intersectedVerb
|
- we combine all lines which do not contain intersectedVerb
|
||||||
- Then we loop through that combined structure and chain their segments which touch each other
|
- Then we loop through that combined structure and chain their segments which touch each other
|
||||||
Changes the style according to user setting.
|
Changes the style according to user setting.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
nonTrimLineStyle = {'stroke': str(self.options.color_nonintersected), 'fill': 'none', 'stroke-width': self.options.strokewidth}
|
nonTrimLineStyle = {'stroke': str(self.options.color_nonintersected), 'fill': 'none', 'stroke-width': self.options.strokewidth}
|
||||||
@ -412,12 +404,20 @@ class ContourScannerAndTrimmer(inkex.EffectExtension):
|
|||||||
pars.add_argument("--decimals", type=int, default=3, help="Accuracy for sub split lines / lines trimmed by shapely")
|
pars.add_argument("--decimals", type=int, default=3, help="Accuracy for sub split lines / lines trimmed by shapely")
|
||||||
pars.add_argument("--snap_tolerance", type=float, default=0.1, help="Snap tolerance for intersection points")
|
pars.add_argument("--snap_tolerance", type=float, default=0.1, help="Snap tolerance for intersection points")
|
||||||
|
|
||||||
#Settings - Scanning
|
#Scanning - Removing
|
||||||
|
pars.add_argument("--remove_relative", type=inkex.Boolean, default=False, help="Remove original relative cmd paths")
|
||||||
|
pars.add_argument("--remove_absolute", type=inkex.Boolean, default=False, help="Remove original absolute cmd paths")
|
||||||
|
pars.add_argument("--remove_mixed", type=inkex.Boolean, default=False, help="Remove original mixed cmd (relative + absolute) paths")
|
||||||
pars.add_argument("--remove_polylines", type=inkex.Boolean, default=False, help="Remove original polyline paths")
|
pars.add_argument("--remove_polylines", type=inkex.Boolean, default=False, help="Remove original polyline paths")
|
||||||
pars.add_argument("--remove_beziers", type=inkex.Boolean, default=False, help="Remove original bezier paths")
|
pars.add_argument("--remove_beziers", type=inkex.Boolean, default=False, help="Remove original bezier paths")
|
||||||
pars.add_argument("--remove_opened", type=inkex.Boolean, default=False, help="Remove original opened paths")
|
pars.add_argument("--remove_opened", type=inkex.Boolean, default=False, help="Remove original opened paths")
|
||||||
pars.add_argument("--remove_closed", type=inkex.Boolean, default=False, help="Remove original closed paths")
|
pars.add_argument("--remove_closed", type=inkex.Boolean, default=False, help="Remove original closed paths")
|
||||||
pars.add_argument("--remove_self_intersecting", type=inkex.Boolean, default=False, help="Remove original self-intersecting paths")
|
pars.add_argument("--remove_self_intersecting", type=inkex.Boolean, default=False, help="Remove original self-intersecting paths")
|
||||||
|
|
||||||
|
#Scanning - Highlighting
|
||||||
|
pars.add_argument("--highlight_relative", type=inkex.Boolean, default=False, help="Highlight relative cmd paths")
|
||||||
|
pars.add_argument("--highlight_absolute", type=inkex.Boolean, default=False, help="Highlight absolute cmd paths")
|
||||||
|
pars.add_argument("--highlight_mixed", type=inkex.Boolean, default=False, help="Highlight mixed cmd (relative + absolute) paths")
|
||||||
pars.add_argument("--highlight_polylines", type=inkex.Boolean, default=False, help="Highlight polyline paths")
|
pars.add_argument("--highlight_polylines", type=inkex.Boolean, default=False, help="Highlight polyline paths")
|
||||||
pars.add_argument("--highlight_beziers", type=inkex.Boolean, default=False, help="Highlight bezier paths")
|
pars.add_argument("--highlight_beziers", type=inkex.Boolean, default=False, help="Highlight bezier paths")
|
||||||
pars.add_argument("--highlight_opened", type=inkex.Boolean, default=False, help="Highlight opened paths")
|
pars.add_argument("--highlight_opened", type=inkex.Boolean, default=False, help="Highlight opened paths")
|
||||||
@ -442,12 +442,15 @@ class ContourScannerAndTrimmer(inkex.EffectExtension):
|
|||||||
pars.add_argument("--apply_original_style", type=inkex.Boolean, default=True, help="Apply original path style to trimmed lines")
|
pars.add_argument("--apply_original_style", type=inkex.Boolean, default=True, help="Apply original path style to trimmed lines")
|
||||||
|
|
||||||
#Style - Scanning Colors
|
#Style - Scanning Colors
|
||||||
|
pars.add_argument("--color_subsplit", type=Color, default='1630897151', help="Color for sub split lines")
|
||||||
|
pars.add_argument("--color_relative", type=Color, default='3419879935', help="Color for relative cmd paths")
|
||||||
|
pars.add_argument("--color_absolute", type=Color, default='1592519679', help="Color for absolute cmd paths")
|
||||||
|
pars.add_argument("--color_mixed", type=Color, default='3351636735', help="Color for mixed cmd (relative + absolute) paths")
|
||||||
pars.add_argument("--color_polyline", type=Color, default='4289703935', help="Color for polyline paths")
|
pars.add_argument("--color_polyline", type=Color, default='4289703935', help="Color for polyline paths")
|
||||||
pars.add_argument("--color_bezier", type=Color, default='258744063', help="Color for bezier paths")
|
pars.add_argument("--color_bezier", type=Color, default='258744063', help="Color for bezier paths")
|
||||||
pars.add_argument("--color_opened", type=Color, default='4012452351', help="Color for opened paths")
|
pars.add_argument("--color_opened", type=Color, default='4012452351', help="Color for opened paths")
|
||||||
pars.add_argument("--color_closed", type=Color, default='2330080511', help="Color for closed paths")
|
pars.add_argument("--color_closed", type=Color, default='2330080511', help="Color for closed paths")
|
||||||
pars.add_argument("--color_self_intersecting_paths", type=Color, default='2593756927', help="Color for self-intersecting contours")
|
pars.add_argument("--color_self_intersecting_paths", type=Color, default='2593756927', help="Color for self-intersecting contours")
|
||||||
pars.add_argument("--color_subsplit", type=Color, default='1630897151', help="Color for sub split lines")
|
|
||||||
pars.add_argument("--color_self_intersections", type=Color, default='6320383', help="Color for self-intersecting line points")
|
pars.add_argument("--color_self_intersections", type=Color, default='6320383', help="Color for self-intersecting line points")
|
||||||
pars.add_argument("--color_global_intersections", type=Color, default='4239343359', help="Color for global intersection points")
|
pars.add_argument("--color_global_intersections", type=Color, default='4239343359', help="Color for global intersection points")
|
||||||
|
|
||||||
@ -458,11 +461,13 @@ class ContourScannerAndTrimmer(inkex.EffectExtension):
|
|||||||
|
|
||||||
|
|
||||||
def effect(self):
|
def effect(self):
|
||||||
|
|
||||||
so = self.options
|
so = self.options
|
||||||
|
|
||||||
#some dependent configuration for drawing modes
|
#some dependent configuration for drawing modes
|
||||||
if \
|
if \
|
||||||
|
so.highlight_relative is True or \
|
||||||
|
so.highlight_absolute is True or \
|
||||||
|
so.highlight_mixed is True or \
|
||||||
so.highlight_beziers is True or \
|
so.highlight_beziers is True or \
|
||||||
so.highlight_polylines is True or \
|
so.highlight_polylines is True or \
|
||||||
so.highlight_opened is True or \
|
so.highlight_opened is True or \
|
||||||
@ -470,13 +475,22 @@ class ContourScannerAndTrimmer(inkex.EffectExtension):
|
|||||||
so.highlight_self_intersecting is True:
|
so.highlight_self_intersecting is True:
|
||||||
so.draw_subsplit = True
|
so.draw_subsplit = True
|
||||||
if so.draw_subsplit is False:
|
if so.draw_subsplit is False:
|
||||||
|
so.highlight_relative = False
|
||||||
|
so.highlight_absolute = False
|
||||||
|
so.highlight_mixed = False
|
||||||
so.highlight_beziers = False
|
so.highlight_beziers = False
|
||||||
so.highlight_polylines = False
|
so.highlight_polylines = False
|
||||||
so.highlight_open = False
|
so.highlight_open = False
|
||||||
so.highlight_closed = False
|
so.highlight_closed = False
|
||||||
so.highlight_self_intersecting = False
|
so.highlight_self_intersecting = False
|
||||||
|
|
||||||
|
if so.break_apart is True and so.show_debug is True:
|
||||||
|
self.msg("Warning: 'Break apart input' setting is enabled. Cannot check for relative, absolute or mixed paths!")
|
||||||
|
|
||||||
#some constant stuff / styles
|
#some constant stuff / styles
|
||||||
|
relativePathStyle = {'stroke': str(so.color_relative), 'fill': 'none', 'stroke-width': so.strokewidth}
|
||||||
|
absolutePathStyle = {'stroke': str(so.color_absolute), 'fill': 'none', 'stroke-width': so.strokewidth}
|
||||||
|
mixedPathStyle = {'stroke': str(so.color_mixed), 'fill': 'none', 'stroke-width': so.strokewidth}
|
||||||
polylinePathStyle = {'stroke': str(so.color_polyline), 'fill': 'none', 'stroke-width': so.strokewidth}
|
polylinePathStyle = {'stroke': str(so.color_polyline), 'fill': 'none', 'stroke-width': so.strokewidth}
|
||||||
bezierPathStyle = {'stroke': str(so.color_bezier), 'fill': 'none', 'stroke-width': so.strokewidth}
|
bezierPathStyle = {'stroke': str(so.color_bezier), 'fill': 'none', 'stroke-width': so.strokewidth}
|
||||||
openPathStyle = {'stroke': str(so.color_opened), 'fill': 'none', 'stroke-width': so.strokewidth}
|
openPathStyle = {'stroke': str(so.color_opened), 'fill': 'none', 'stroke-width': so.strokewidth}
|
||||||
@ -484,14 +498,7 @@ class ContourScannerAndTrimmer(inkex.EffectExtension):
|
|||||||
selfIntersectingPathStyle = {'stroke': str(so.color_self_intersecting_paths), 'fill': 'none', 'stroke-width': so.strokewidth}
|
selfIntersectingPathStyle = {'stroke': str(so.color_self_intersecting_paths), 'fill': 'none', 'stroke-width': so.strokewidth}
|
||||||
basicSubSplitLineStyle = {'stroke': str(so.color_subsplit), 'fill': 'none', 'stroke-width': so.strokewidth}
|
basicSubSplitLineStyle = {'stroke': str(so.color_subsplit), 'fill': 'none', 'stroke-width': so.strokewidth}
|
||||||
|
|
||||||
''' 1 //
|
#get all paths which are within selection or in document and generate sub split lines
|
||||||
get all paths which are within selection or in document and generate sub split lines
|
|
||||||
If flatten is enabled, we do the best approximation into a set of fine line segments.
|
|
||||||
To quickly find all intersections we use Bentley-Ottmann algorithm.
|
|
||||||
To use it we have to split all paths into subpaths and each sub path's will puzzled into single straight lines
|
|
||||||
Cool tool to visualize: https://bl.ocks.org/1wheel/464141fe9b940153e636
|
|
||||||
'''
|
|
||||||
|
|
||||||
pathElements = self.getPathElements()
|
pathElements = self.getPathElements()
|
||||||
|
|
||||||
allSubSplitLines = []
|
allSubSplitLines = []
|
||||||
@ -510,7 +517,7 @@ class ContourScannerAndTrimmer(inkex.EffectExtension):
|
|||||||
for pathElement in pathElements:
|
for pathElement in pathElements:
|
||||||
path = pathElement.path.transform(pathElement.composed_transform())
|
path = pathElement.path.transform(pathElement.composed_transform())
|
||||||
#path = pathElement.path
|
#path = pathElement.path
|
||||||
|
|
||||||
'''
|
'''
|
||||||
Some original path checkings for analysis/highlighting purposes
|
Some original path checkings for analysis/highlighting purposes
|
||||||
Note: highlighting open/closed/self-intersecting contours does work best if you break apart
|
Note: highlighting open/closed/self-intersecting contours does work best if you break apart
|
||||||
@ -537,6 +544,33 @@ class ContourScannerAndTrimmer(inkex.EffectExtension):
|
|||||||
elif so.path_types == 'closed_paths' and isClosed is False: continue #skip this loop iteration
|
elif so.path_types == 'closed_paths' and isClosed is False: continue #skip this loop iteration
|
||||||
elif so.path_types == 'both': pass
|
elif so.path_types == 'both': pass
|
||||||
|
|
||||||
|
#check for relative or absolute paths. Does not work if break apart is enabled
|
||||||
|
isRelative = False
|
||||||
|
isAbsolute = False
|
||||||
|
isMixed = False
|
||||||
|
relCmds = ['m', 'l', 'h', 'v', 'c', 's', 'q', 't', 'a', 'z']
|
||||||
|
if any(relCmd in pathElement.attrib['d'] for relCmd in relCmds):
|
||||||
|
isRelative = True
|
||||||
|
if any(relCmd.upper() in pathElement.attrib['d'] for relCmd in relCmds):
|
||||||
|
isAbsolute = True
|
||||||
|
if isRelative is True and isAbsolute is True:
|
||||||
|
isMixed = True
|
||||||
|
isRelative = False
|
||||||
|
isAbsolute = False
|
||||||
|
#self.msg("isRelative = {}".format(isRelative))
|
||||||
|
#self.msg("isAbsolute = {}".format(isAbsolute))
|
||||||
|
#self.msg("isMixed = {}".format(isMixed))
|
||||||
|
|
||||||
|
if so.remove_absolute is True and isAbsolute is True:
|
||||||
|
pathElement.delete()
|
||||||
|
continue #skip this loop iteration
|
||||||
|
if so.remove_relative is True and isRelative is True:
|
||||||
|
pathElement.delete()
|
||||||
|
continue #skip this loop iteration
|
||||||
|
if so.remove_mixed is True and isMixed is True:
|
||||||
|
pathElement.delete()
|
||||||
|
continue #skip this loop iteration
|
||||||
|
|
||||||
#adjust the style of original paths if desired. Has influence to the finally trimmed lines style results too!
|
#adjust the style of original paths if desired. Has influence to the finally trimmed lines style results too!
|
||||||
if so.removefillsetstroke:
|
if so.removefillsetstroke:
|
||||||
self.adjustStyle(pathElement)
|
self.adjustStyle(pathElement)
|
||||||
@ -609,8 +643,11 @@ class ContourScannerAndTrimmer(inkex.EffectExtension):
|
|||||||
if pathElement.getparent() != self.svg.root:
|
if pathElement.getparent() != self.svg.root:
|
||||||
line.path = line.path.transform(-pathElement.getparent().composed_transform())
|
line.path = line.path.transform(-pathElement.getparent().composed_transform())
|
||||||
line.style = basicSubSplitLineStyle
|
line.style = basicSubSplitLineStyle
|
||||||
line.attrib['isBezier'] = str(isBezier)
|
line.attrib['isRelative'] = str(isRelative)
|
||||||
line.attrib['isClosed'] = str(isClosed)
|
line.attrib['isAbsolute'] = str(isAbsolute)
|
||||||
|
line.attrib['isMixed'] = str(isMixed)
|
||||||
|
line.attrib['isBezier'] = str(isBezier)
|
||||||
|
line.attrib['isClosed'] = str(isClosed)
|
||||||
subSplitTrimLineGroup.add(line)
|
subSplitTrimLineGroup.add(line)
|
||||||
|
|
||||||
subSplitLines.append([(x1, y1), (x2, y2)])
|
subSplitLines.append([(x1, y1), (x2, y2)])
|
||||||
@ -630,6 +667,18 @@ class ContourScannerAndTrimmer(inkex.EffectExtension):
|
|||||||
# subPathIsClosed = True
|
# subPathIsClosed = True
|
||||||
|
|
||||||
for subSplitLine in subSplitTrimLineGroup:
|
for subSplitLine in subSplitTrimLineGroup:
|
||||||
|
if subSplitLine.attrib['isRelative'] == 'True':
|
||||||
|
if so.highlight_relative is True:
|
||||||
|
subSplitLine.style = relativePathStyle
|
||||||
|
|
||||||
|
if subSplitLine.attrib['isAbsolute'] == 'True':
|
||||||
|
if so.highlight_absolute is True:
|
||||||
|
subSplitLine.style = absolutePathStyle
|
||||||
|
|
||||||
|
if subSplitLine.attrib['isMixed'] == 'True':
|
||||||
|
if so.highlight_mixed is True:
|
||||||
|
subSplitLine.style = mixedPathStyle
|
||||||
|
|
||||||
if subSplitLine.attrib['isBezier'] == 'True':
|
if subSplitLine.attrib['isBezier'] == 'True':
|
||||||
if so.highlight_beziers is True:
|
if so.highlight_beziers is True:
|
||||||
subSplitLine.style = bezierPathStyle
|
subSplitLine.style = bezierPathStyle
|
||||||
@ -643,9 +692,9 @@ class ContourScannerAndTrimmer(inkex.EffectExtension):
|
|||||||
subSplitLine.style = closedPathStyle
|
subSplitLine.style = closedPathStyle
|
||||||
else:
|
else:
|
||||||
if so.highlight_opened is True:
|
if so.highlight_opened is True:
|
||||||
subSplitLine.style = openPathStyle
|
subSplitLine.style = openPathStyle
|
||||||
|
|
||||||
#check for self intersections
|
#check for self intersections using Bentley-Ottmann algorithm.
|
||||||
selfIntersectionPoints = isect_segments(subSplitLines, validate=True)
|
selfIntersectionPoints = isect_segments(subSplitLines, validate=True)
|
||||||
if len(selfIntersectionPoints) > 0:
|
if len(selfIntersectionPoints) > 0:
|
||||||
if so.show_debug is True:
|
if so.show_debug is True:
|
||||||
@ -689,8 +738,8 @@ class ContourScannerAndTrimmer(inkex.EffectExtension):
|
|||||||
if so.show_debug is True:
|
if so.show_debug is True:
|
||||||
self.msg("sub split line count: {}".format(len(allSubSplitLines)))
|
self.msg("sub split line count: {}".format(len(allSubSplitLines)))
|
||||||
|
|
||||||
''' 2 //
|
'''
|
||||||
now we intersect the sub split lines to find the global intersection points (contains self-intersections too!)
|
now we intersect the sub split lines to find the global intersection points using Bentley-Ottmann algorithm (contains self-intersections too!)
|
||||||
'''
|
'''
|
||||||
try:
|
try:
|
||||||
globalIntersectionPoints = MultiPoint(isect_segments(allSubSplitData[0], validate=True))
|
globalIntersectionPoints = MultiPoint(isect_segments(allSubSplitData[0], validate=True))
|
||||||
@ -700,9 +749,9 @@ class ContourScannerAndTrimmer(inkex.EffectExtension):
|
|||||||
if so.visualize_global_intersections is True:
|
if so.visualize_global_intersections is True:
|
||||||
self.visualize_global_intersections(globalIntersectionPoints)
|
self.visualize_global_intersections(globalIntersectionPoints)
|
||||||
|
|
||||||
''' 3 //
|
'''
|
||||||
now we trim the sub split lines at all calculated intersection points.
|
now we trim the sub split lines at all calculated intersection points.
|
||||||
We do this path by path to keep the logic between original paths, sub split lines and the final output
|
We do this path by path to keep the logic between original paths, sub split lines and the final output
|
||||||
'''
|
'''
|
||||||
if so.draw_trimmed is True:
|
if so.draw_trimmed is True:
|
||||||
allTrimGroups = [] #container to collect all trim groups for later on processing
|
allTrimGroups = [] #container to collect all trim groups for later on processing
|
||||||
|
Reference in New Issue
Block a user