22
22
from enaml .qt .QtGui import QPainterPath , QTransform
23
23
from enaml .qt .QtCore import QPointF , QRectF
24
24
from enaml .colors import ColorMember
25
+
26
+ import inkcut .core .utils
25
27
from inkcut .core .api import Model , AreaBase
26
28
from inkcut .core .svg import QtSvgDoc
27
29
from inkcut .core .utils import split_painter_path , log
30
32
from . import filters
31
33
from . import ordering
32
34
33
-
34
35
class Material (AreaBase ):
35
36
""" Model representing the plot media
36
37
"""
@@ -291,7 +292,7 @@ def _default_optimized_path(self):
291
292
292
293
return doc
293
294
294
- def _default_content_direction (self ):
295
+ def _default_quadrant_direction (self ):
295
296
return QPointF (1 , 1 )
296
297
297
298
@observe ('path' , 'order' , 'filters' )
@@ -477,6 +478,58 @@ def create(self, expansion_direction: QPointF):
477
478
478
479
return model
479
480
481
+ def create_transform_filtered (self , device ):
482
+ config = device .config
483
+ model = self .create (config .expansion_direction )
484
+
485
+ from inkcut .device .plugin import DeviceFilter
486
+
487
+ # Apply device filters
488
+ has_polyline_filter = False
489
+ for f in device .filters :
490
+ log .debug (" filter | Running {} on model" .format (f ))
491
+ if f .stage & DeviceFilter .FILTER_STAGE_POLYLINE :
492
+ has_polyline_filter = True
493
+ if f .stage & DeviceFilter .FILTER_STAGE_PATH_COMBINED :
494
+ model = f .apply_to_model (model , job = device )
495
+
496
+ # Only apply polyline transformation if necessary. So that original curves can be preserved
497
+ # and sent to device directly when supported.
498
+ if has_polyline_filter :
499
+ # Since Qt's toSubpathPolygons converts curves without accepting
500
+ # a parameter to set the minimum distance between points on the
501
+ # curve, we need to prescale by a "quality factor" before
502
+ # converting then undo the scaling to effectively adjust the
503
+ # number of points on a curve.
504
+ quality_factor = config .quality_factor
505
+ m = QTransform .fromScale (
506
+ quality_factor , quality_factor )
507
+ # Some versions of Qt seem to require a value in toSubpathPolygons
508
+ polypath = model .toSubpathPolygons (m )
509
+
510
+ if config .quality_factor != 1 :
511
+ # Undo the prescaling, if the quality_factor > 1 the curve
512
+ # quality will be improved.
513
+ m_inv = QTransform .fromScale (
514
+ 1 / quality_factor , 1 / quality_factor )
515
+ polypath = list (map (m_inv .map , polypath ))
516
+
517
+ # Apply device filters to polypath
518
+ for f in device .filters :
519
+ log .debug (" filter | Running {} on polypath" .format (f ))
520
+ if f .stage & DeviceFilter .FILTER_STAGE_POLYLINE :
521
+ polypath = f .apply_to_polypath (polypath )
522
+
523
+ end_point = model .currentPosition ()
524
+ model = QPainterPath ()
525
+ for path in polypath :
526
+ model .addPolygon (path )
527
+
528
+ model .moveTo (end_point )
529
+
530
+ return model
531
+
532
+
480
533
def _check_bounds (self , plot , area ):
481
534
""" Checks that the width and height of plot are less than the width
482
535
and height of area
@@ -558,15 +611,7 @@ def move_path(self):
558
611
""" Returns the path the head moves when not cutting
559
612
560
613
"""
561
- # Compute the negative
562
- path = QPainterPath ()
563
- for i in range (self .model .elementCount ()):
564
- e = self .model .elementAt (i )
565
- if e .isMoveTo ():
566
- path .lineTo (e .x , e .y )
567
- else :
568
- path .moveTo (e .x , e .y )
569
- return path
614
+ return inkcut .core .utils .make_move_path (self .model )
570
615
571
616
@property
572
617
def cut_path (self ):
@@ -575,30 +620,6 @@ def cut_path(self):
575
620
"""
576
621
return self .model
577
622
578
- # def get_offset_path(self,device):
579
- # """ Returns path where it is cutting """
580
- # path = QPainterPath()
581
- # _p = QPointF(0,0) # previous point
582
- # step = 0.1
583
- # for subpath in QtSvgDoc.toSubpathList(self.model):#.toSubpathPolygons():
584
- # e = subpath.elementAt(0)
585
- # path.moveTo(QPointF(e.x,e.y))
586
- # length = subpath.length()
587
- # distance = 0
588
- # while distance<=length:
589
- # t = subpath.percentAtLength(distance)
590
- # p = subpath.pointAtPercent(t)
591
- # a = subpath.angleAtPercent(t)+90
592
- # #path.moveTo(p)#QPointF(x,y))
593
- # # TOOD: Do i need numpy here???
594
- # x = p.x()+np.multiply(self.device.blade_offset,np.sin(np.deg2rad(a)))
595
- # y = p.y()+np.multiply(self.device.blade_offset,np.cos(np.deg2rad(a)))
596
- # path.lineTo(QPointF(x,y))
597
- # distance+=step
598
- # #_p = p # update last
599
- #
600
- # return path
601
-
602
623
def add_stack (self ):
603
624
""" Add a complete stack or fill the row
604
625
0 commit comments