forked from 1b-agent/opencadstudio-upstream
PCEXTRACTSECTION: Extract Section Lines dialog
Picking the cloud opens the Extract Section Lines from Point Cloud dialog with the reference's settings and defaults: entire cross section or perimeter only, maximum points to process (slider and field, with the estimated time), output layer (Use Current or a layer), colour, lines or 2D polylines with their width, minimum line length and connect lines tolerance (each measurable by two points on screen), collinear angle tolerance (0-10) and Preview result. Create extracts; with the preview it asks [Accept/Settings/Undo] and Settings reopens the dialog. The settings are kept for the session. Automation action pc_section. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
09e9e44c19
commit
331772eac2
30 files changed
+931
-20
No files matched your search
@@ -4011,6 +4011,27 @@ insert =
|
||||
.pc-search = Search
|
||||
.pc-collapse-all = Collapse all
|
||||
.pc-expand-all = Expand all
|
||||
.pcm-scheme-name = Scheme name
|
||||
.pcs-title = Extract Section Lines from Point Cloud
|
||||
.pcs-extract = Extract
|
||||
.pcs-entire = Entire cross section
|
||||
.pcs-perimeter = Perimeter only
|
||||
.pcs-max-points = Maximum points to process
|
||||
.pcs-faster = Faster
|
||||
.pcs-accurate = More accurate
|
||||
.pcs-time = Estimated time: __ocs_fmt_0__ min
|
||||
.pcs-output = Output geometry
|
||||
.pcs-polylines = 2D Polylines
|
||||
.pcs-width = Polyline width
|
||||
.pcs-tolerances = Extraction tolerances
|
||||
.pcs-min-length = Minimum line length
|
||||
.pcs-connect = Connect lines tolerance
|
||||
.pcs-angle = Collinear angle tolerance
|
||||
.pcs-preview = Preview result
|
||||
.pcs-use-current = Use Current
|
||||
.pcs-positive = Requires a positive number.
|
||||
.pcs-positive-int = Requires a positive integer.
|
||||
.pcs-help = Traces the points on the kept side of a live section as lines.
|
||||
model =
|
||||
.create = إنشاء
|
||||
.boolean = عمليات منطقية
|
||||
|
||||
@@ -3998,6 +3998,27 @@ insert =
|
||||
.pc-search = Search
|
||||
.pc-collapse-all = Collapse all
|
||||
.pc-expand-all = Expand all
|
||||
.pcm-scheme-name = Scheme name
|
||||
.pcs-title = Extract Section Lines from Point Cloud
|
||||
.pcs-extract = Extract
|
||||
.pcs-entire = Entire cross section
|
||||
.pcs-perimeter = Perimeter only
|
||||
.pcs-max-points = Maximum points to process
|
||||
.pcs-faster = Faster
|
||||
.pcs-accurate = More accurate
|
||||
.pcs-time = Estimated time: __ocs_fmt_0__ min
|
||||
.pcs-output = Output geometry
|
||||
.pcs-polylines = 2D Polylines
|
||||
.pcs-width = Polyline width
|
||||
.pcs-tolerances = Extraction tolerances
|
||||
.pcs-min-length = Minimum line length
|
||||
.pcs-connect = Connect lines tolerance
|
||||
.pcs-angle = Collinear angle tolerance
|
||||
.pcs-preview = Preview result
|
||||
.pcs-use-current = Use Current
|
||||
.pcs-positive = Requires a positive number.
|
||||
.pcs-positive-int = Requires a positive integer.
|
||||
.pcs-help = Traces the points on the kept side of a live section as lines.
|
||||
model =
|
||||
.create = Създаване
|
||||
.boolean = Булеви операции
|
||||
|
||||
@@ -3996,6 +3996,27 @@ insert =
|
||||
.pc-search = Search
|
||||
.pc-collapse-all = Collapse all
|
||||
.pc-expand-all = Expand all
|
||||
.pcm-scheme-name = Scheme name
|
||||
.pcs-title = Extract Section Lines from Point Cloud
|
||||
.pcs-extract = Extract
|
||||
.pcs-entire = Entire cross section
|
||||
.pcs-perimeter = Perimeter only
|
||||
.pcs-max-points = Maximum points to process
|
||||
.pcs-faster = Faster
|
||||
.pcs-accurate = More accurate
|
||||
.pcs-time = Estimated time: __ocs_fmt_0__ min
|
||||
.pcs-output = Output geometry
|
||||
.pcs-polylines = 2D Polylines
|
||||
.pcs-width = Polyline width
|
||||
.pcs-tolerances = Extraction tolerances
|
||||
.pcs-min-length = Minimum line length
|
||||
.pcs-connect = Connect lines tolerance
|
||||
.pcs-angle = Collinear angle tolerance
|
||||
.pcs-preview = Preview result
|
||||
.pcs-use-current = Use Current
|
||||
.pcs-positive = Requires a positive number.
|
||||
.pcs-positive-int = Requires a positive integer.
|
||||
.pcs-help = Traces the points on the kept side of a live section as lines.
|
||||
model =
|
||||
.create = Vytvořit
|
||||
.boolean = Booleovské operace
|
||||
|
||||
@@ -3997,6 +3997,27 @@ insert =
|
||||
.pc-search = Search
|
||||
.pc-collapse-all = Collapse all
|
||||
.pc-expand-all = Expand all
|
||||
.pcm-scheme-name = Scheme name
|
||||
.pcs-title = Extract Section Lines from Point Cloud
|
||||
.pcs-extract = Extract
|
||||
.pcs-entire = Entire cross section
|
||||
.pcs-perimeter = Perimeter only
|
||||
.pcs-max-points = Maximum points to process
|
||||
.pcs-faster = Faster
|
||||
.pcs-accurate = More accurate
|
||||
.pcs-time = Estimated time: __ocs_fmt_0__ min
|
||||
.pcs-output = Output geometry
|
||||
.pcs-polylines = 2D Polylines
|
||||
.pcs-width = Polyline width
|
||||
.pcs-tolerances = Extraction tolerances
|
||||
.pcs-min-length = Minimum line length
|
||||
.pcs-connect = Connect lines tolerance
|
||||
.pcs-angle = Collinear angle tolerance
|
||||
.pcs-preview = Preview result
|
||||
.pcs-use-current = Use Current
|
||||
.pcs-positive = Requires a positive number.
|
||||
.pcs-positive-int = Requires a positive integer.
|
||||
.pcs-help = Traces the points on the kept side of a live section as lines.
|
||||
model =
|
||||
.create = Erstellen
|
||||
.boolean = Boolesche Operationen
|
||||
|
||||
@@ -3999,6 +3999,27 @@ insert =
|
||||
.pc-search = Search
|
||||
.pc-collapse-all = Collapse all
|
||||
.pc-expand-all = Expand all
|
||||
.pcm-scheme-name = Scheme name
|
||||
.pcs-title = Extract Section Lines from Point Cloud
|
||||
.pcs-extract = Extract
|
||||
.pcs-entire = Entire cross section
|
||||
.pcs-perimeter = Perimeter only
|
||||
.pcs-max-points = Maximum points to process
|
||||
.pcs-faster = Faster
|
||||
.pcs-accurate = More accurate
|
||||
.pcs-time = Estimated time: __ocs_fmt_0__ min
|
||||
.pcs-output = Output geometry
|
||||
.pcs-polylines = 2D Polylines
|
||||
.pcs-width = Polyline width
|
||||
.pcs-tolerances = Extraction tolerances
|
||||
.pcs-min-length = Minimum line length
|
||||
.pcs-connect = Connect lines tolerance
|
||||
.pcs-angle = Collinear angle tolerance
|
||||
.pcs-preview = Preview result
|
||||
.pcs-use-current = Use Current
|
||||
.pcs-positive = Requires a positive number.
|
||||
.pcs-positive-int = Requires a positive integer.
|
||||
.pcs-help = Traces the points on the kept side of a live section as lines.
|
||||
model =
|
||||
.create = Δημιουργία
|
||||
.boolean = Δυαδική πράξη
|
||||
|
||||
@@ -4000,6 +4000,27 @@ insert =
|
||||
.pc-search = Search
|
||||
.pc-collapse-all = Collapse all
|
||||
.pc-expand-all = Expand all
|
||||
.pcm-scheme-name = Scheme name
|
||||
.pcs-title = Extract Section Lines from Point Cloud
|
||||
.pcs-extract = Extract
|
||||
.pcs-entire = Entire cross section
|
||||
.pcs-perimeter = Perimeter only
|
||||
.pcs-max-points = Maximum points to process
|
||||
.pcs-faster = Faster
|
||||
.pcs-accurate = More accurate
|
||||
.pcs-time = Estimated time: __ocs_fmt_0__ min
|
||||
.pcs-output = Output geometry
|
||||
.pcs-polylines = 2D Polylines
|
||||
.pcs-width = Polyline width
|
||||
.pcs-tolerances = Extraction tolerances
|
||||
.pcs-min-length = Minimum line length
|
||||
.pcs-connect = Connect lines tolerance
|
||||
.pcs-angle = Collinear angle tolerance
|
||||
.pcs-preview = Preview result
|
||||
.pcs-use-current = Use Current
|
||||
.pcs-positive = Requires a positive number.
|
||||
.pcs-positive-int = Requires a positive integer.
|
||||
.pcs-help = Traces the points on the kept side of a live section as lines.
|
||||
model =
|
||||
.create = Create
|
||||
.boolean = Boolean
|
||||
|
||||
@@ -3999,6 +3999,27 @@ insert =
|
||||
.pc-search = Search
|
||||
.pc-collapse-all = Collapse all
|
||||
.pc-expand-all = Expand all
|
||||
.pcm-scheme-name = Scheme name
|
||||
.pcs-title = Extract Section Lines from Point Cloud
|
||||
.pcs-extract = Extract
|
||||
.pcs-entire = Entire cross section
|
||||
.pcs-perimeter = Perimeter only
|
||||
.pcs-max-points = Maximum points to process
|
||||
.pcs-faster = Faster
|
||||
.pcs-accurate = More accurate
|
||||
.pcs-time = Estimated time: __ocs_fmt_0__ min
|
||||
.pcs-output = Output geometry
|
||||
.pcs-polylines = 2D Polylines
|
||||
.pcs-width = Polyline width
|
||||
.pcs-tolerances = Extraction tolerances
|
||||
.pcs-min-length = Minimum line length
|
||||
.pcs-connect = Connect lines tolerance
|
||||
.pcs-angle = Collinear angle tolerance
|
||||
.pcs-preview = Preview result
|
||||
.pcs-use-current = Use Current
|
||||
.pcs-positive = Requires a positive number.
|
||||
.pcs-positive-int = Requires a positive integer.
|
||||
.pcs-help = Traces the points on the kept side of a live section as lines.
|
||||
model =
|
||||
.create = Crear
|
||||
.boolean = Booleanas
|
||||
|
||||
@@ -3998,6 +3998,27 @@ insert =
|
||||
.pc-search = Search
|
||||
.pc-collapse-all = Collapse all
|
||||
.pc-expand-all = Expand all
|
||||
.pcm-scheme-name = Scheme name
|
||||
.pcs-title = Extract Section Lines from Point Cloud
|
||||
.pcs-extract = Extract
|
||||
.pcs-entire = Entire cross section
|
||||
.pcs-perimeter = Perimeter only
|
||||
.pcs-max-points = Maximum points to process
|
||||
.pcs-faster = Faster
|
||||
.pcs-accurate = More accurate
|
||||
.pcs-time = Estimated time: __ocs_fmt_0__ min
|
||||
.pcs-output = Output geometry
|
||||
.pcs-polylines = 2D Polylines
|
||||
.pcs-width = Polyline width
|
||||
.pcs-tolerances = Extraction tolerances
|
||||
.pcs-min-length = Minimum line length
|
||||
.pcs-connect = Connect lines tolerance
|
||||
.pcs-angle = Collinear angle tolerance
|
||||
.pcs-preview = Preview result
|
||||
.pcs-use-current = Use Current
|
||||
.pcs-positive = Requires a positive number.
|
||||
.pcs-positive-int = Requires a positive integer.
|
||||
.pcs-help = Traces the points on the kept side of a live section as lines.
|
||||
model =
|
||||
.create = Luo
|
||||
.boolean = Boolen operaatiot
|
||||
|
||||
@@ -3999,6 +3999,27 @@ insert =
|
||||
.pc-search = Search
|
||||
.pc-collapse-all = Collapse all
|
||||
.pc-expand-all = Expand all
|
||||
.pcm-scheme-name = Scheme name
|
||||
.pcs-title = Extract Section Lines from Point Cloud
|
||||
.pcs-extract = Extract
|
||||
.pcs-entire = Entire cross section
|
||||
.pcs-perimeter = Perimeter only
|
||||
.pcs-max-points = Maximum points to process
|
||||
.pcs-faster = Faster
|
||||
.pcs-accurate = More accurate
|
||||
.pcs-time = Estimated time: __ocs_fmt_0__ min
|
||||
.pcs-output = Output geometry
|
||||
.pcs-polylines = 2D Polylines
|
||||
.pcs-width = Polyline width
|
||||
.pcs-tolerances = Extraction tolerances
|
||||
.pcs-min-length = Minimum line length
|
||||
.pcs-connect = Connect lines tolerance
|
||||
.pcs-angle = Collinear angle tolerance
|
||||
.pcs-preview = Preview result
|
||||
.pcs-use-current = Use Current
|
||||
.pcs-positive = Requires a positive number.
|
||||
.pcs-positive-int = Requires a positive integer.
|
||||
.pcs-help = Traces the points on the kept side of a live section as lines.
|
||||
model =
|
||||
.create = Créer
|
||||
.boolean = Opérations booléennes
|
||||
|
||||
@@ -3987,6 +3987,27 @@ insert =
|
||||
.pc-search = Search
|
||||
.pc-collapse-all = Collapse all
|
||||
.pc-expand-all = Expand all
|
||||
.pcm-scheme-name = Scheme name
|
||||
.pcs-title = Extract Section Lines from Point Cloud
|
||||
.pcs-extract = Extract
|
||||
.pcs-entire = Entire cross section
|
||||
.pcs-perimeter = Perimeter only
|
||||
.pcs-max-points = Maximum points to process
|
||||
.pcs-faster = Faster
|
||||
.pcs-accurate = More accurate
|
||||
.pcs-time = Estimated time: __ocs_fmt_0__ min
|
||||
.pcs-output = Output geometry
|
||||
.pcs-polylines = 2D Polylines
|
||||
.pcs-width = Polyline width
|
||||
.pcs-tolerances = Extraction tolerances
|
||||
.pcs-min-length = Minimum line length
|
||||
.pcs-connect = Connect lines tolerance
|
||||
.pcs-angle = Collinear angle tolerance
|
||||
.pcs-preview = Preview result
|
||||
.pcs-use-current = Use Current
|
||||
.pcs-positive = Requires a positive number.
|
||||
.pcs-positive-int = Requires a positive integer.
|
||||
.pcs-help = Traces the points on the kept side of a live section as lines.
|
||||
model =
|
||||
.create = बनाएँ
|
||||
.boolean = बूलियन संक्रियाएँ
|
||||
|
||||
@@ -3998,6 +3998,27 @@ insert =
|
||||
.pc-search = Search
|
||||
.pc-collapse-all = Collapse all
|
||||
.pc-expand-all = Expand all
|
||||
.pcm-scheme-name = Scheme name
|
||||
.pcs-title = Extract Section Lines from Point Cloud
|
||||
.pcs-extract = Extract
|
||||
.pcs-entire = Entire cross section
|
||||
.pcs-perimeter = Perimeter only
|
||||
.pcs-max-points = Maximum points to process
|
||||
.pcs-faster = Faster
|
||||
.pcs-accurate = More accurate
|
||||
.pcs-time = Estimated time: __ocs_fmt_0__ min
|
||||
.pcs-output = Output geometry
|
||||
.pcs-polylines = 2D Polylines
|
||||
.pcs-width = Polyline width
|
||||
.pcs-tolerances = Extraction tolerances
|
||||
.pcs-min-length = Minimum line length
|
||||
.pcs-connect = Connect lines tolerance
|
||||
.pcs-angle = Collinear angle tolerance
|
||||
.pcs-preview = Preview result
|
||||
.pcs-use-current = Use Current
|
||||
.pcs-positive = Requires a positive number.
|
||||
.pcs-positive-int = Requires a positive integer.
|
||||
.pcs-help = Traces the points on the kept side of a live section as lines.
|
||||
model =
|
||||
.create = Létrehozás
|
||||
.boolean = Logikai műveletek
|
||||
|
||||
@@ -3998,6 +3998,27 @@ insert =
|
||||
.pc-search = Search
|
||||
.pc-collapse-all = Collapse all
|
||||
.pc-expand-all = Expand all
|
||||
.pcm-scheme-name = Scheme name
|
||||
.pcs-title = Extract Section Lines from Point Cloud
|
||||
.pcs-extract = Extract
|
||||
.pcs-entire = Entire cross section
|
||||
.pcs-perimeter = Perimeter only
|
||||
.pcs-max-points = Maximum points to process
|
||||
.pcs-faster = Faster
|
||||
.pcs-accurate = More accurate
|
||||
.pcs-time = Estimated time: __ocs_fmt_0__ min
|
||||
.pcs-output = Output geometry
|
||||
.pcs-polylines = 2D Polylines
|
||||
.pcs-width = Polyline width
|
||||
.pcs-tolerances = Extraction tolerances
|
||||
.pcs-min-length = Minimum line length
|
||||
.pcs-connect = Connect lines tolerance
|
||||
.pcs-angle = Collinear angle tolerance
|
||||
.pcs-preview = Preview result
|
||||
.pcs-use-current = Use Current
|
||||
.pcs-positive = Requires a positive number.
|
||||
.pcs-positive-int = Requires a positive integer.
|
||||
.pcs-help = Traces the points on the kept side of a live section as lines.
|
||||
model =
|
||||
.create = Crea
|
||||
.boolean = Operazioni booleane
|
||||
|
||||
@@ -3987,6 +3987,27 @@ insert =
|
||||
.pc-search = Search
|
||||
.pc-collapse-all = Collapse all
|
||||
.pc-expand-all = Expand all
|
||||
.pcm-scheme-name = Scheme name
|
||||
.pcs-title = Extract Section Lines from Point Cloud
|
||||
.pcs-extract = Extract
|
||||
.pcs-entire = Entire cross section
|
||||
.pcs-perimeter = Perimeter only
|
||||
.pcs-max-points = Maximum points to process
|
||||
.pcs-faster = Faster
|
||||
.pcs-accurate = More accurate
|
||||
.pcs-time = Estimated time: __ocs_fmt_0__ min
|
||||
.pcs-output = Output geometry
|
||||
.pcs-polylines = 2D Polylines
|
||||
.pcs-width = Polyline width
|
||||
.pcs-tolerances = Extraction tolerances
|
||||
.pcs-min-length = Minimum line length
|
||||
.pcs-connect = Connect lines tolerance
|
||||
.pcs-angle = Collinear angle tolerance
|
||||
.pcs-preview = Preview result
|
||||
.pcs-use-current = Use Current
|
||||
.pcs-positive = Requires a positive number.
|
||||
.pcs-positive-int = Requires a positive integer.
|
||||
.pcs-help = Traces the points on the kept side of a live section as lines.
|
||||
model =
|
||||
.create = 作成
|
||||
.boolean = ブール演算
|
||||
|
||||
@@ -3998,6 +3998,27 @@ insert =
|
||||
.pc-search = Search
|
||||
.pc-collapse-all = Collapse all
|
||||
.pc-expand-all = Expand all
|
||||
.pcm-scheme-name = Scheme name
|
||||
.pcs-title = Extract Section Lines from Point Cloud
|
||||
.pcs-extract = Extract
|
||||
.pcs-entire = Entire cross section
|
||||
.pcs-perimeter = Perimeter only
|
||||
.pcs-max-points = Maximum points to process
|
||||
.pcs-faster = Faster
|
||||
.pcs-accurate = More accurate
|
||||
.pcs-time = Estimated time: __ocs_fmt_0__ min
|
||||
.pcs-output = Output geometry
|
||||
.pcs-polylines = 2D Polylines
|
||||
.pcs-width = Polyline width
|
||||
.pcs-tolerances = Extraction tolerances
|
||||
.pcs-min-length = Minimum line length
|
||||
.pcs-connect = Connect lines tolerance
|
||||
.pcs-angle = Collinear angle tolerance
|
||||
.pcs-preview = Preview result
|
||||
.pcs-use-current = Use Current
|
||||
.pcs-positive = Requires a positive number.
|
||||
.pcs-positive-int = Requires a positive integer.
|
||||
.pcs-help = Traces the points on the kept side of a live section as lines.
|
||||
model =
|
||||
.create = 생성
|
||||
.boolean = 불리언 연산
|
||||
|
||||
@@ -3997,6 +3997,27 @@ insert =
|
||||
.pc-search = Search
|
||||
.pc-collapse-all = Collapse all
|
||||
.pc-expand-all = Expand all
|
||||
.pcm-scheme-name = Scheme name
|
||||
.pcs-title = Extract Section Lines from Point Cloud
|
||||
.pcs-extract = Extract
|
||||
.pcs-entire = Entire cross section
|
||||
.pcs-perimeter = Perimeter only
|
||||
.pcs-max-points = Maximum points to process
|
||||
.pcs-faster = Faster
|
||||
.pcs-accurate = More accurate
|
||||
.pcs-time = Estimated time: __ocs_fmt_0__ min
|
||||
.pcs-output = Output geometry
|
||||
.pcs-polylines = 2D Polylines
|
||||
.pcs-width = Polyline width
|
||||
.pcs-tolerances = Extraction tolerances
|
||||
.pcs-min-length = Minimum line length
|
||||
.pcs-connect = Connect lines tolerance
|
||||
.pcs-angle = Collinear angle tolerance
|
||||
.pcs-preview = Preview result
|
||||
.pcs-use-current = Use Current
|
||||
.pcs-positive = Requires a positive number.
|
||||
.pcs-positive-int = Requires a positive integer.
|
||||
.pcs-help = Traces the points on the kept side of a live section as lines.
|
||||
model =
|
||||
.create = Maken
|
||||
.boolean = Booleaanse bewerkingen
|
||||
|
||||
@@ -3998,6 +3998,27 @@ insert =
|
||||
.pc-search = Search
|
||||
.pc-collapse-all = Collapse all
|
||||
.pc-expand-all = Expand all
|
||||
.pcm-scheme-name = Scheme name
|
||||
.pcs-title = Extract Section Lines from Point Cloud
|
||||
.pcs-extract = Extract
|
||||
.pcs-entire = Entire cross section
|
||||
.pcs-perimeter = Perimeter only
|
||||
.pcs-max-points = Maximum points to process
|
||||
.pcs-faster = Faster
|
||||
.pcs-accurate = More accurate
|
||||
.pcs-time = Estimated time: __ocs_fmt_0__ min
|
||||
.pcs-output = Output geometry
|
||||
.pcs-polylines = 2D Polylines
|
||||
.pcs-width = Polyline width
|
||||
.pcs-tolerances = Extraction tolerances
|
||||
.pcs-min-length = Minimum line length
|
||||
.pcs-connect = Connect lines tolerance
|
||||
.pcs-angle = Collinear angle tolerance
|
||||
.pcs-preview = Preview result
|
||||
.pcs-use-current = Use Current
|
||||
.pcs-positive = Requires a positive number.
|
||||
.pcs-positive-int = Requires a positive integer.
|
||||
.pcs-help = Traces the points on the kept side of a live section as lines.
|
||||
model =
|
||||
.create = Utwórz
|
||||
.boolean = Operacje boolowskie
|
||||
|
||||
@@ -3999,6 +3999,27 @@ insert =
|
||||
.pc-search = Search
|
||||
.pc-collapse-all = Collapse all
|
||||
.pc-expand-all = Expand all
|
||||
.pcm-scheme-name = Scheme name
|
||||
.pcs-title = Extract Section Lines from Point Cloud
|
||||
.pcs-extract = Extract
|
||||
.pcs-entire = Entire cross section
|
||||
.pcs-perimeter = Perimeter only
|
||||
.pcs-max-points = Maximum points to process
|
||||
.pcs-faster = Faster
|
||||
.pcs-accurate = More accurate
|
||||
.pcs-time = Estimated time: __ocs_fmt_0__ min
|
||||
.pcs-output = Output geometry
|
||||
.pcs-polylines = 2D Polylines
|
||||
.pcs-width = Polyline width
|
||||
.pcs-tolerances = Extraction tolerances
|
||||
.pcs-min-length = Minimum line length
|
||||
.pcs-connect = Connect lines tolerance
|
||||
.pcs-angle = Collinear angle tolerance
|
||||
.pcs-preview = Preview result
|
||||
.pcs-use-current = Use Current
|
||||
.pcs-positive = Requires a positive number.
|
||||
.pcs-positive-int = Requires a positive integer.
|
||||
.pcs-help = Traces the points on the kept side of a live section as lines.
|
||||
model =
|
||||
.create = Criar
|
||||
.boolean = Operações booleanas
|
||||
|
||||
@@ -4000,6 +4000,27 @@ insert =
|
||||
.pc-search = Search
|
||||
.pc-collapse-all = Collapse all
|
||||
.pc-expand-all = Expand all
|
||||
.pcm-scheme-name = Scheme name
|
||||
.pcs-title = Extract Section Lines from Point Cloud
|
||||
.pcs-extract = Extract
|
||||
.pcs-entire = Entire cross section
|
||||
.pcs-perimeter = Perimeter only
|
||||
.pcs-max-points = Maximum points to process
|
||||
.pcs-faster = Faster
|
||||
.pcs-accurate = More accurate
|
||||
.pcs-time = Estimated time: __ocs_fmt_0__ min
|
||||
.pcs-output = Output geometry
|
||||
.pcs-polylines = 2D Polylines
|
||||
.pcs-width = Polyline width
|
||||
.pcs-tolerances = Extraction tolerances
|
||||
.pcs-min-length = Minimum line length
|
||||
.pcs-connect = Connect lines tolerance
|
||||
.pcs-angle = Collinear angle tolerance
|
||||
.pcs-preview = Preview result
|
||||
.pcs-use-current = Use Current
|
||||
.pcs-positive = Requires a positive number.
|
||||
.pcs-positive-int = Requires a positive integer.
|
||||
.pcs-help = Traces the points on the kept side of a live section as lines.
|
||||
model =
|
||||
.create = Создание
|
||||
.boolean = Булевы операции
|
||||
|
||||
@@ -3959,6 +3959,27 @@ insert =
|
||||
.pc-search = Ara
|
||||
.pc-collapse-all = Tümünü daralt
|
||||
.pc-expand-all = Tümünü genişlet
|
||||
.pcm-scheme-name = Şema adı
|
||||
.pcs-title = Nokta Bulutundan Kesit Çizgileri Çıkar
|
||||
.pcs-extract = Çıkar
|
||||
.pcs-entire = Tüm kesit
|
||||
.pcs-perimeter = Yalnız çevre
|
||||
.pcs-max-points = En fazla işlenecek nokta
|
||||
.pcs-faster = Daha hızlı
|
||||
.pcs-accurate = Daha doğru
|
||||
.pcs-time = Tahmini süre: __ocs_fmt_0__ dk
|
||||
.pcs-output = Çıktı geometrisi
|
||||
.pcs-polylines = 2B Çoklu çizgiler
|
||||
.pcs-width = Çoklu çizgi genişliği
|
||||
.pcs-tolerances = Çıkarma toleransları
|
||||
.pcs-min-length = En kısa çizgi uzunluğu
|
||||
.pcs-connect = Çizgi birleştirme toleransı
|
||||
.pcs-angle = Doğrusal açı toleransı
|
||||
.pcs-preview = Sonucu önizle
|
||||
.pcs-use-current = Geçerli katmanı kullan
|
||||
.pcs-positive = Pozitif bir sayı gerekir.
|
||||
.pcs-positive-int = Pozitif bir tamsayı gerekir.
|
||||
.pcs-help = Canlı kesitin korunan tarafındaki noktaları çizgilerle izler.
|
||||
model =
|
||||
.create = Oluştur
|
||||
.boolean = Boole işlemleri
|
||||
|
||||
@@ -3982,6 +3982,27 @@ insert =
|
||||
.pc-search = Search
|
||||
.pc-collapse-all = Collapse all
|
||||
.pc-expand-all = Expand all
|
||||
.pcm-scheme-name = Scheme name
|
||||
.pcs-title = Extract Section Lines from Point Cloud
|
||||
.pcs-extract = Extract
|
||||
.pcs-entire = Entire cross section
|
||||
.pcs-perimeter = Perimeter only
|
||||
.pcs-max-points = Maximum points to process
|
||||
.pcs-faster = Faster
|
||||
.pcs-accurate = More accurate
|
||||
.pcs-time = Estimated time: __ocs_fmt_0__ min
|
||||
.pcs-output = Output geometry
|
||||
.pcs-polylines = 2D Polylines
|
||||
.pcs-width = Polyline width
|
||||
.pcs-tolerances = Extraction tolerances
|
||||
.pcs-min-length = Minimum line length
|
||||
.pcs-connect = Connect lines tolerance
|
||||
.pcs-angle = Collinear angle tolerance
|
||||
.pcs-preview = Preview result
|
||||
.pcs-use-current = Use Current
|
||||
.pcs-positive = Requires a positive number.
|
||||
.pcs-positive-int = Requires a positive integer.
|
||||
.pcs-help = Traces the points on the kept side of a live section as lines.
|
||||
model =
|
||||
.create = 创建
|
||||
.boolean = 布尔运算
|
||||
|
||||
@@ -3994,6 +3994,27 @@ insert =
|
||||
.pc-search = Search
|
||||
.pc-collapse-all = Collapse all
|
||||
.pc-expand-all = Expand all
|
||||
.pcm-scheme-name = Scheme name
|
||||
.pcs-title = Extract Section Lines from Point Cloud
|
||||
.pcs-extract = Extract
|
||||
.pcs-entire = Entire cross section
|
||||
.pcs-perimeter = Perimeter only
|
||||
.pcs-max-points = Maximum points to process
|
||||
.pcs-faster = Faster
|
||||
.pcs-accurate = More accurate
|
||||
.pcs-time = Estimated time: __ocs_fmt_0__ min
|
||||
.pcs-output = Output geometry
|
||||
.pcs-polylines = 2D Polylines
|
||||
.pcs-width = Polyline width
|
||||
.pcs-tolerances = Extraction tolerances
|
||||
.pcs-min-length = Minimum line length
|
||||
.pcs-connect = Connect lines tolerance
|
||||
.pcs-angle = Collinear angle tolerance
|
||||
.pcs-preview = Preview result
|
||||
.pcs-use-current = Use Current
|
||||
.pcs-positive = Requires a positive number.
|
||||
.pcs-positive-int = Requires a positive integer.
|
||||
.pcs-help = Traces the points on the kept side of a live section as lines.
|
||||
model =
|
||||
.create = 建立
|
||||
.boolean = 布林運算
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
//! and its section objects when they start.
|
||||
|
||||
use super::*;
|
||||
use crate::ui::window::pdf_dialogs::PdfDialogMsg;
|
||||
use codec::entities::ExtendedEntityData;
|
||||
use glam::DVec3;
|
||||
|
||||
@@ -80,6 +81,10 @@ impl OpenCADStudio {
|
||||
self.extraction_clouds(i),
|
||||
self.extraction_sections(i),
|
||||
)),
|
||||
"_PCSECTIONDLG" => {
|
||||
self.open_pc_section_dialog(i);
|
||||
return Some(self.finish_dispatch(cmd));
|
||||
}
|
||||
_ => return None,
|
||||
};
|
||||
self.command_line.push_info(&command.prompt());
|
||||
@@ -87,3 +92,108 @@ impl OpenCADStudio {
|
||||
Some(self.finish_dispatch(cmd))
|
||||
}
|
||||
}
|
||||
|
||||
impl OpenCADStudio {
|
||||
/// PCEXTRACTSECTION's settings dialog, filled from the session settings.
|
||||
fn open_pc_section_dialog(&mut self, i: usize) {
|
||||
use crate::modules::insert::pc_extract::{has_job, settings};
|
||||
use crate::ui::window::pdf_dialogs::{LineColor, PcSectionState};
|
||||
if !has_job() {
|
||||
return;
|
||||
}
|
||||
let s = settings();
|
||||
let current = crate::t!("Use Current").into_owned();
|
||||
let mut layers = vec![current.clone()];
|
||||
let mut names: Vec<String> = self.tabs[i].scene.document.layers.iter().map(|l| l.name.clone()).collect();
|
||||
names.sort_by_key(|n| n.to_lowercase());
|
||||
layers.extend(names);
|
||||
let short = |v: f64| {
|
||||
let t = format!("{v:.4}");
|
||||
t.trim_end_matches('0').trim_end_matches('.').to_string()
|
||||
};
|
||||
self.pc_section = Some(PcSectionState {
|
||||
perimeter: s.perimeter,
|
||||
max_points: s.max_points.to_string(),
|
||||
layers,
|
||||
layer: s.layer.clone().unwrap_or(current),
|
||||
color: LineColor(s.color),
|
||||
polylines: s.polylines,
|
||||
width: short(s.width),
|
||||
min_length: short(s.min_length),
|
||||
connect: short(s.connect),
|
||||
angle: short(s.angle),
|
||||
preview: s.preview,
|
||||
});
|
||||
self.active_modal = Some(crate::app::ModalKind::PcSection);
|
||||
}
|
||||
|
||||
pub(in crate::app) fn update_pc_section(&mut self, message: PdfDialogMsg) -> Task<Message> {
|
||||
use crate::modules::insert::pc_extract::{set_settings, settings, SectionCommand, SectionDistanceCommand};
|
||||
use crate::command::CadCommand;
|
||||
let i = self.active_tab;
|
||||
let Some(state) = self.pc_section.as_mut() else {
|
||||
return Task::none();
|
||||
};
|
||||
match message {
|
||||
PdfDialogMsg::SecPerimeter(on) => state.perimeter = on,
|
||||
PdfDialogMsg::SecMaxPoints(v) => state.max_points = v,
|
||||
PdfDialogMsg::SecLayer(v) => state.layer = v,
|
||||
PdfDialogMsg::SecColor(c) => state.color = c,
|
||||
PdfDialogMsg::SecPolylines(on) => state.polylines = on,
|
||||
PdfDialogMsg::SecWidth(v) => state.width = v,
|
||||
PdfDialogMsg::SecMinLength(v) => state.min_length = v,
|
||||
PdfDialogMsg::SecConnect(v) => state.connect = v,
|
||||
PdfDialogMsg::SecAngle(v) => state.angle = v,
|
||||
PdfDialogMsg::SecPreview(on) => state.preview = on,
|
||||
// Measure on screen, then back to the dialog (the extraction waits).
|
||||
PdfDialogMsg::SecPick(connect) => {
|
||||
self.pc_section = None;
|
||||
self.active_modal = None;
|
||||
let command = SectionDistanceCommand::new(connect);
|
||||
self.command_line.push_info(&command.prompt());
|
||||
self.tabs[i].active_cmd = Some(Box::new(command));
|
||||
}
|
||||
PdfDialogMsg::SecCreate => {
|
||||
let number = |t: &str| crate::entities::common::parse_f64(t.trim());
|
||||
let (min_length, connect, width) = (number(&state.min_length), number(&state.connect), number(&state.width));
|
||||
let (Some(min_length), Some(connect)) = (min_length.filter(|v| *v > 0.0), connect.filter(|v| *v > 0.0)) else {
|
||||
self.command_line.push_error(crate::t!("Requires a positive number.").as_ref());
|
||||
return Task::none();
|
||||
};
|
||||
let Some(angle) = state.angle.trim().parse::<i64>().ok().filter(|v| (0..=10).contains(v)) else {
|
||||
self.command_line
|
||||
.push_error("Colinear angle tolerance only accepts integer from 0 to 10.");
|
||||
return Task::none();
|
||||
};
|
||||
let Some(max_points) = state.max_points.trim().parse::<usize>().ok().filter(|v| *v > 0) else {
|
||||
self.command_line.push_error(crate::t!("Requires a positive integer.").as_ref());
|
||||
return Task::none();
|
||||
};
|
||||
let current = crate::t!("Use Current").into_owned();
|
||||
let mut s = settings();
|
||||
s.perimeter = state.perimeter;
|
||||
s.max_points = max_points;
|
||||
s.layer = (state.layer != current).then(|| state.layer.clone());
|
||||
s.color = state.color.0;
|
||||
s.polylines = state.polylines;
|
||||
s.width = width.filter(|v| *v >= 0.0).unwrap_or(0.0);
|
||||
s.min_length = min_length;
|
||||
s.connect = connect;
|
||||
s.angle = angle as f64;
|
||||
s.preview = state.preview;
|
||||
set_settings(s);
|
||||
self.pc_section = None;
|
||||
self.active_modal = None;
|
||||
let Some(mut command) = SectionCommand::resume() else {
|
||||
return Task::none();
|
||||
};
|
||||
let result = command.run();
|
||||
self.command_line.push_info(&command.prompt());
|
||||
self.tabs[i].active_cmd = Some(Box::new(command));
|
||||
return self.apply_cmd_result(result);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
@@ -378,6 +378,7 @@ impl OpenCADStudio {
|
||||
}
|
||||
"attach" => crate::t!("Attaches a PDF file as an underlay."),
|
||||
"pointcloud" => crate::t!("Attaches a point cloud scan or project."),
|
||||
"pcsection" => crate::t!("Traces the points on the kept side of a live section as lines."),
|
||||
"pointcloudcolormap" => {
|
||||
crate::t!("Sets the color schemes and ranges a point cloud is colored by intensity or elevation.")
|
||||
}
|
||||
@@ -503,6 +504,18 @@ impl OpenCADStudio {
|
||||
| PdfDialogMsg::MapCurrent(_)
|
||||
| PdfDialogMsg::MapApply
|
||||
| PdfDialogMsg::MapOk) => return self.update_point_cloud_color_map(message),
|
||||
message @ (PdfDialogMsg::SecPerimeter(_)
|
||||
| PdfDialogMsg::SecMaxPoints(_)
|
||||
| PdfDialogMsg::SecLayer(_)
|
||||
| PdfDialogMsg::SecColor(_)
|
||||
| PdfDialogMsg::SecPolylines(_)
|
||||
| PdfDialogMsg::SecWidth(_)
|
||||
| PdfDialogMsg::SecMinLength(_)
|
||||
| PdfDialogMsg::SecConnect(_)
|
||||
| PdfDialogMsg::SecAngle(_)
|
||||
| PdfDialogMsg::SecPick(_)
|
||||
| PdfDialogMsg::SecPreview(_)
|
||||
| PdfDialogMsg::SecCreate) => return self.update_pc_section(message),
|
||||
PdfDialogMsg::CloudPathType(choice) => {
|
||||
let stored = self.point_cloud_attach.as_ref().map(|s| self.pdf_stored_path(&s.path, choice.0));
|
||||
if let (Some(s), Some(stored)) = (self.point_cloud_attach.as_mut(), stored) {
|
||||
|
||||
@@ -75,6 +75,7 @@ pub(super) const NAMES: &[&str] = &[
|
||||
"pc_manager",
|
||||
"pdf_page_select",
|
||||
"pc_colormap",
|
||||
"pc_section",
|
||||
"ribbon_tab",
|
||||
"ribbon_dropdown",
|
||||
"dialog_ok",
|
||||
@@ -721,6 +722,24 @@ impl OpenCADStudio {
|
||||
_ => return Err(failure("invalid_value", "Unknown color map edit")),
|
||||
})
|
||||
}
|
||||
// Section extraction dialog: "min=0.01", "connect=0.02", "angle=5",
|
||||
// "points=18000", "lines=1", "perimeter=1", "preview=0", "width=0".
|
||||
"pc_section" => {
|
||||
use crate::ui::window::pdf_dialogs::PdfDialogMsg as M;
|
||||
let value = string(req, "value")?;
|
||||
let (key, arg) = value.split_once('=').unwrap_or((value, ""));
|
||||
Message::PdfDialog(match key {
|
||||
"min" => M::SecMinLength(arg.into()),
|
||||
"connect" => M::SecConnect(arg.into()),
|
||||
"angle" => M::SecAngle(arg.into()),
|
||||
"points" => M::SecMaxPoints(arg.into()),
|
||||
"width" => M::SecWidth(arg.into()),
|
||||
"lines" => M::SecPolylines(arg == "0"),
|
||||
"perimeter" => M::SecPerimeter(arg != "0"),
|
||||
"preview" => M::SecPreview(arg != "0"),
|
||||
_ => return Err(failure("invalid_value", "Unknown section setting")),
|
||||
})
|
||||
}
|
||||
// Point Cloud Manager: flip a row's switch, "<handle>:<row>" with
|
||||
// row cloud, unassigned, scans or scan:<name>.
|
||||
"pc_manager_toggle" => {
|
||||
@@ -776,6 +795,7 @@ impl OpenCADStudio {
|
||||
Some(crate::app::ModalKind::PdfAttach) => PdfDialogMsg::AttachOk,
|
||||
Some(crate::app::ModalKind::PointCloudAttach) => PdfDialogMsg::CloudOk,
|
||||
Some(crate::app::ModalKind::PointCloudColorMap) => PdfDialogMsg::MapOk,
|
||||
Some(crate::app::ModalKind::PcSection) => PdfDialogMsg::SecCreate,
|
||||
Some(crate::app::ModalKind::UnderlayLayers) => PdfDialogMsg::LayersOk,
|
||||
Some(crate::app::ModalKind::PdfImportSettings) => PdfDialogMsg::SettingsOk,
|
||||
Some(crate::app::ModalKind::PdfImportFile) => PdfDialogMsg::ImportOk,
|
||||
|
||||
@@ -499,6 +499,7 @@ pub(super) struct OpenCADStudio {
|
||||
pdf_attach: Option<crate::ui::window::pdf_dialogs::PdfAttachState>,
|
||||
point_cloud_attach: Option<crate::ui::window::pdf_dialogs::PointCloudAttachState>,
|
||||
point_cloud_color_map: Option<crate::ui::window::pdf_dialogs::PointCloudColorMapState>,
|
||||
pc_section: Option<crate::ui::window::pdf_dialogs::PcSectionState>,
|
||||
underlay_layers: Option<crate::ui::window::pdf_dialogs::UnderlayLayersState>,
|
||||
pdf_import_settings: Option<crate::modules::insert::pdf_import::PdfImportSettings>,
|
||||
pdf_import_file: Option<crate::ui::window::pdf_dialogs::PdfImportFileState>,
|
||||
@@ -1907,6 +1908,7 @@ pub enum ModalKind {
|
||||
PdfAttach,
|
||||
PointCloudAttach,
|
||||
PointCloudColorMap,
|
||||
PcSection,
|
||||
UnderlayLayers,
|
||||
PdfImportSettings,
|
||||
PdfImportFile,
|
||||
@@ -4041,6 +4043,7 @@ impl OpenCADStudio {
|
||||
pdf_attach: None,
|
||||
point_cloud_attach: None,
|
||||
point_cloud_color_map: None,
|
||||
pc_section: None,
|
||||
underlay_layers: None,
|
||||
pdf_import_settings: None,
|
||||
pdf_import_file: None,
|
||||
|
||||
@@ -8485,6 +8485,11 @@ impl OpenCADStudio {
|
||||
}
|
||||
|
||||
Message::CloseModal => {
|
||||
// Cancelling the section settings drops the waiting extraction.
|
||||
if self.active_modal == Some(super::ModalKind::PcSection) {
|
||||
crate::modules::insert::pc_extract::drop_job();
|
||||
self.pc_section = None;
|
||||
}
|
||||
if self.active_modal == Some(super::ModalKind::RecoveryPrompt) {
|
||||
return self.update(Message::RecoveryDecline);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ impl OpenCADStudio {
|
||||
},
|
||||
Some(K::PointCloudAttach) => crate::t!("Attach Point Cloud").into_owned(),
|
||||
Some(K::PointCloudColorMap) => crate::t!("Point Cloud Color Map").into_owned(),
|
||||
Some(K::PcSection) => crate::t!("Extract Section Lines from Point Cloud").into_owned(),
|
||||
Some(K::UnderlayLayers) => crate::t!("Underlay Layers").into_owned(),
|
||||
Some(K::PdfImportSettings) => crate::t!("PDF Import Settings").into_owned(),
|
||||
Some(K::PdfImportFile) => crate::t!("Import PDF").into_owned(),
|
||||
@@ -536,6 +537,10 @@ impl OpenCADStudio {
|
||||
crate::ui::window::pdf_dialogs::view_point_cloud_color_map(state, flow)
|
||||
})
|
||||
}
|
||||
super::super::ModalKind::PcSection => {
|
||||
let state = self.pc_section.as_ref()?;
|
||||
sized_flow(ex, 760, 470, |flow| crate::ui::window::pdf_dialogs::view_pc_section(state, flow))
|
||||
}
|
||||
super::super::ModalKind::UnderlayLayers => {
|
||||
let state = self.underlay_layers.as_ref()?;
|
||||
sized_flow(ex, 460, 520, |flow| {
|
||||
|
||||
@@ -143,6 +143,26 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static
|
||||
"Collapse all" => Some(("insert", "pc-collapse-all")),
|
||||
"Expand all" => Some(("insert", "pc-expand-all")),
|
||||
"Scheme name" => Some(("insert", "pcm-scheme-name")),
|
||||
"Extract Section Lines from Point Cloud" => Some(("insert", "pcs-title")),
|
||||
"Extract" => Some(("insert", "pcs-extract")),
|
||||
"Entire cross section" => Some(("insert", "pcs-entire")),
|
||||
"Perimeter only" => Some(("insert", "pcs-perimeter")),
|
||||
"Maximum points to process" => Some(("insert", "pcs-max-points")),
|
||||
"Faster" => Some(("insert", "pcs-faster")),
|
||||
"More accurate" => Some(("insert", "pcs-accurate")),
|
||||
"Estimated time: {count} min" => Some(("insert", "pcs-time")),
|
||||
"Output geometry" => Some(("insert", "pcs-output")),
|
||||
"2D Polylines" => Some(("insert", "pcs-polylines")),
|
||||
"Polyline width" => Some(("insert", "pcs-width")),
|
||||
"Extraction tolerances" => Some(("insert", "pcs-tolerances")),
|
||||
"Minimum line length" => Some(("insert", "pcs-min-length")),
|
||||
"Connect lines tolerance" => Some(("insert", "pcs-connect")),
|
||||
"Collinear angle tolerance" => Some(("insert", "pcs-angle")),
|
||||
"Preview result" => Some(("insert", "pcs-preview")),
|
||||
"Use Current" => Some(("insert", "pcs-use-current")),
|
||||
"Requires a positive number." => Some(("insert", "pcs-positive")),
|
||||
"Requires a positive integer." => Some(("insert", "pcs-positive-int")),
|
||||
"Traces the points on the kept side of a live section as lines." => Some(("insert", "pcs-help")),
|
||||
"Stylization" => Some(("properties", "stylization")),
|
||||
"Color scheme" => Some(("properties", "color-scheme")),
|
||||
"Scan Colors" => Some(("properties", "scan-colors")),
|
||||
|
||||
@@ -496,31 +496,61 @@ pub struct Section {
|
||||
|
||||
/// The extraction settings (the reference's dialog defaults), kept for the
|
||||
/// session.
|
||||
#[derive(Clone, Copy)]
|
||||
struct Settings {
|
||||
perimeter: bool,
|
||||
max_points: usize,
|
||||
polylines: bool,
|
||||
width: f64,
|
||||
min_length: f64,
|
||||
connect: f64,
|
||||
angle: f64,
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Settings {
|
||||
pub perimeter: bool,
|
||||
pub max_points: usize,
|
||||
/// The layer the lines go on; `None` is the current layer.
|
||||
pub layer: Option<String>,
|
||||
/// The lines' colour (ACI; 256 ByLayer, 0 ByBlock).
|
||||
pub color: i16,
|
||||
pub polylines: bool,
|
||||
pub width: f64,
|
||||
pub min_length: f64,
|
||||
pub connect: f64,
|
||||
pub angle: f64,
|
||||
/// Show the result and ask to accept it (else create it at once).
|
||||
pub preview: bool,
|
||||
}
|
||||
|
||||
const DEFAULTS: Settings = Settings {
|
||||
perimeter: false,
|
||||
max_points: 18_000,
|
||||
layer: None,
|
||||
color: 3,
|
||||
polylines: true,
|
||||
width: 0.0,
|
||||
min_length: 150.0,
|
||||
connect: 300.0,
|
||||
angle: 5.0,
|
||||
preview: true,
|
||||
};
|
||||
|
||||
static SETTINGS: Mutex<Settings> = Mutex::new(DEFAULTS);
|
||||
|
||||
fn settings() -> Settings {
|
||||
SETTINGS.lock().map(|s| *s).unwrap_or(DEFAULTS)
|
||||
pub fn settings() -> Settings {
|
||||
SETTINGS.lock().map(|s| s.clone()).unwrap_or(DEFAULTS)
|
||||
}
|
||||
|
||||
pub fn set_settings(settings: Settings) {
|
||||
if let Ok(mut stored) = SETTINGS.lock() {
|
||||
*stored = settings;
|
||||
}
|
||||
}
|
||||
|
||||
/// The cloud and section a PCEXTRACTSECTION is extracting from while its
|
||||
/// settings dialog is open.
|
||||
static JOB: Mutex<Option<(Clouds, Section)>> = Mutex::new(None);
|
||||
|
||||
/// Whether an extraction waits for its settings dialog.
|
||||
pub fn has_job() -> bool {
|
||||
JOB.lock().is_ok_and(|job| job.is_some())
|
||||
}
|
||||
|
||||
pub fn drop_job() {
|
||||
if let Ok(mut job) = JOB.lock() {
|
||||
*job = None;
|
||||
}
|
||||
}
|
||||
|
||||
const TOO_FEW: &str = "Too few points to process. No geometry extracted from point cloud.";
|
||||
@@ -734,7 +764,11 @@ impl SectionCommand {
|
||||
.into_iter()
|
||||
.map(|p| plane.to_local(p).truncate())
|
||||
.collect();
|
||||
let color = Color::from_index(3);
|
||||
let color = match s.color {
|
||||
256 => Color::ByLayer,
|
||||
0 => Color::ByBlock,
|
||||
index => Color::from_index(index),
|
||||
};
|
||||
let mut out = Vec::new();
|
||||
for chain in trace(&flat, &s) {
|
||||
if s.polylines {
|
||||
@@ -744,6 +778,9 @@ impl SectionCommand {
|
||||
..Default::default()
|
||||
};
|
||||
pline.common.color = color.clone();
|
||||
if let Some(layer) = &s.layer {
|
||||
pline.common.layer = layer.clone();
|
||||
}
|
||||
out.push(plane.place_entity(EntityType::LwPolyline(pline)));
|
||||
} else {
|
||||
for w in chain.windows(2) {
|
||||
@@ -752,6 +789,9 @@ impl SectionCommand {
|
||||
vector(plane.to_world(w[1].extend(0.0))),
|
||||
);
|
||||
line.common.color = color.clone();
|
||||
if let Some(layer) = &s.layer {
|
||||
line.common.layer = layer.clone();
|
||||
}
|
||||
out.push(EntityType::Line(line));
|
||||
}
|
||||
}
|
||||
@@ -759,11 +799,22 @@ impl SectionCommand {
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
/// PCEXTRACTSECTION after its settings dialog: the waiting cloud and
|
||||
/// section, extracted with the settings.
|
||||
pub fn resume() -> Option<Self> {
|
||||
let (cloud, section) = JOB.lock().ok()?.take()?;
|
||||
let mut command = Self::new(true, Clouds::default(), Vec::new());
|
||||
command.cloud = Some(cloud);
|
||||
command.section = Some(section);
|
||||
command.step = SectionStep::Accept;
|
||||
Some(command)
|
||||
}
|
||||
|
||||
/// Extracts; asks to accept when previewing, else creates.
|
||||
fn run(&mut self) -> CmdResult {
|
||||
pub fn run(&mut self) -> CmdResult {
|
||||
match self.extract() {
|
||||
Err(message) => CmdResult::CancelWithMessage(message.to_string()),
|
||||
Ok(entities) if !self.ask => {
|
||||
Ok(entities) if !self.ask || !settings().preview => {
|
||||
if entities.is_empty() { CmdResult::Cancel } else { CmdResult::CommitEntitiesAndExit(entities) }
|
||||
}
|
||||
Ok(entities) => {
|
||||
@@ -862,21 +913,68 @@ impl SectionCommand {
|
||||
"2" | "2D" | "P" | "POLYLINES" | "2D POLYLINES" => s.polylines = true,
|
||||
_ => return CmdResult::ReportError("Invalid option keyword.".to_string()),
|
||||
}
|
||||
if let Ok(mut stored) = SETTINGS.lock() {
|
||||
*stored = s;
|
||||
}
|
||||
set_settings(s);
|
||||
return self.run();
|
||||
}
|
||||
_ => return CmdResult::NeedPoint,
|
||||
};
|
||||
if let Ok(mut stored) = SETTINGS.lock() {
|
||||
*stored = s;
|
||||
}
|
||||
set_settings(s);
|
||||
self.step = next;
|
||||
CmdResult::NeedPoint
|
||||
}
|
||||
}
|
||||
|
||||
/// The dialog's pick buttons: a distance measured by two points on screen,
|
||||
/// then the dialog again.
|
||||
pub struct SectionDistanceCommand {
|
||||
/// Connect lines tolerance (else minimum line length).
|
||||
connect: bool,
|
||||
first: Option<DVec3>,
|
||||
}
|
||||
|
||||
impl SectionDistanceCommand {
|
||||
pub fn new(connect: bool) -> Self {
|
||||
Self { connect, first: None }
|
||||
}
|
||||
}
|
||||
|
||||
impl CadCommand for SectionDistanceCommand {
|
||||
fn name(&self) -> &'static str {
|
||||
"PCEXTRACTSECTION"
|
||||
}
|
||||
|
||||
fn prompt(&self) -> String {
|
||||
if self.first.is_none() { "Specify first point:" } else { "Specify second point:" }.to_string()
|
||||
}
|
||||
|
||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||
let Some(first) = self.first else {
|
||||
self.first = Some(pt);
|
||||
return CmdResult::NeedPoint;
|
||||
};
|
||||
let mut s = settings();
|
||||
let distance = first.distance(pt);
|
||||
if distance > 0.0 {
|
||||
if self.connect {
|
||||
s.connect = distance;
|
||||
} else {
|
||||
s.min_length = distance;
|
||||
}
|
||||
set_settings(s);
|
||||
}
|
||||
CmdResult::Dispatch("_PCSECTIONDLG".to_string())
|
||||
}
|
||||
|
||||
fn on_enter(&mut self) -> CmdResult {
|
||||
CmdResult::Dispatch("_PCSECTIONDLG".to_string())
|
||||
}
|
||||
|
||||
fn on_mouse_move(&mut self, pt: DVec3) -> Option<WireModel> {
|
||||
let first = self.first?;
|
||||
Some(WireModel::solid_f64("pc_section_distance".into(), vec![first.to_array(), pt.to_array()], [1.0, 1.0, 1.0, 1.0], false))
|
||||
}
|
||||
}
|
||||
|
||||
/// The OCS axes of an entity normal (arbitrary axis algorithm) as columns.
|
||||
fn ocs(normal: Vector3) -> DMat3 {
|
||||
let n = DVec3::new(normal.x, normal.y, normal.z).normalize_or(DVec3::Z);
|
||||
@@ -950,6 +1048,13 @@ impl CadCommand for SectionCommand {
|
||||
let Some(cloud) = self.clouds.of(handle) else {
|
||||
return CmdResult::CancelWithMessage("The point cloud is not loaded.".to_string());
|
||||
};
|
||||
// PCEXTRACTSECTION asks its settings in the dialog first.
|
||||
if self.ask {
|
||||
if let Ok(mut job) = JOB.lock() {
|
||||
*job = Some((cloud, section));
|
||||
}
|
||||
return CmdResult::Dispatch("_PCSECTIONDLG".to_string());
|
||||
}
|
||||
self.cloud = Some(cloud);
|
||||
self.section = Some(section);
|
||||
self.run()
|
||||
@@ -967,6 +1072,13 @@ impl CadCommand for SectionCommand {
|
||||
let entities = std::mem::take(&mut self.result);
|
||||
if entities.is_empty() { CmdResult::Cancel } else { CmdResult::CommitEntitiesAndExit(entities) }
|
||||
}
|
||||
// Back to the settings dialog with the same cloud and section.
|
||||
"" | "S" | "SETTINGS" if self.ask => {
|
||||
if let (Some(cloud), Some(section), Ok(mut job)) = (self.cloud.take(), self.section, JOB.lock()) {
|
||||
*job = Some((cloud, section));
|
||||
}
|
||||
CmdResult::Dispatch("_PCSECTIONDLG".to_string())
|
||||
}
|
||||
"" | "S" | "SETTINGS" => {
|
||||
self.step = SectionStep::Extract;
|
||||
CmdResult::NeedPoint
|
||||
|
||||
@@ -70,6 +70,20 @@ pub enum PdfDialogMsg {
|
||||
MapCurrent(bool),
|
||||
MapApply,
|
||||
MapOk,
|
||||
// Extract Section Lines from Point Cloud
|
||||
SecPerimeter(bool),
|
||||
SecMaxPoints(String),
|
||||
SecLayer(String),
|
||||
SecColor(LineColor),
|
||||
SecPolylines(bool),
|
||||
SecWidth(String),
|
||||
SecMinLength(String),
|
||||
SecConnect(String),
|
||||
SecAngle(String),
|
||||
/// Measure the connect tolerance (else the minimum length) on screen.
|
||||
SecPick(bool),
|
||||
SecPreview(bool),
|
||||
SecCreate,
|
||||
// Underlay Layers
|
||||
LayersUnderlay(String),
|
||||
LayersSearch(String),
|
||||
@@ -1488,3 +1502,171 @@ pub fn view_point_cloud_color_map<'a>(
|
||||
.align_y(iced::Center);
|
||||
column![tabs, body, footer].spacing(10).padding([10, 12]).width(sizing.width).into()
|
||||
}
|
||||
|
||||
// ── Extract Section Lines from Point Cloud ─────────────────────────────────
|
||||
|
||||
/// A colour the extracted lines can take (ACI; 256 ByLayer, 0 ByBlock).
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct LineColor(pub i16);
|
||||
|
||||
impl LineColor {
|
||||
pub const ALL: [LineColor; 9] = [
|
||||
LineColor(256),
|
||||
LineColor(0),
|
||||
LineColor(1),
|
||||
LineColor(2),
|
||||
LineColor(3),
|
||||
LineColor(4),
|
||||
LineColor(5),
|
||||
LineColor(6),
|
||||
LineColor(7),
|
||||
];
|
||||
}
|
||||
|
||||
impl fmt::Display for LineColor {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let label = match self.0 {
|
||||
256 => t!("ByLayer"),
|
||||
0 => t!("ByBlock"),
|
||||
1 => t!("Red"),
|
||||
2 => t!("Yellow"),
|
||||
3 => t!("Green"),
|
||||
4 => t!("Cyan"),
|
||||
5 => t!("Blue"),
|
||||
6 => t!("Magenta"),
|
||||
_ => t!("White"),
|
||||
};
|
||||
f.write_str(label.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
/// The dialog's fields; numbers as typed.
|
||||
pub struct PcSectionState {
|
||||
pub perimeter: bool,
|
||||
pub max_points: String,
|
||||
/// "Use Current" first, then the drawing's layers.
|
||||
pub layers: Vec<String>,
|
||||
pub layer: String,
|
||||
pub color: LineColor,
|
||||
pub polylines: bool,
|
||||
pub width: String,
|
||||
pub min_length: String,
|
||||
pub connect: String,
|
||||
pub angle: String,
|
||||
pub preview: bool,
|
||||
}
|
||||
|
||||
pub fn view_pc_section<'a>(state: &'a PcSectionState, sizing: crate::ui::modal::ModalSizing) -> Element<'a, Message> {
|
||||
let extract = card(
|
||||
t!("Extract").into_owned(),
|
||||
segmented(
|
||||
vec![(false, t!("Entire cross section").into_owned()), (true, t!("Perimeter only").into_owned())],
|
||||
state.perimeter,
|
||||
PdfDialogMsg::SecPerimeter,
|
||||
),
|
||||
);
|
||||
let points = state.max_points.trim().parse::<f32>().unwrap_or(18_000.0).clamp(1_000.0, 200_000.0);
|
||||
// ponytail: the time shown scales with the points (18000 ≈ 1 minute, as
|
||||
// the reference shows it); the real rate depends on the machine.
|
||||
let minutes = (points / 18_000.0).ceil().max(1.0) as u32;
|
||||
let max_points = card(
|
||||
t!("Maximum points to process").into_owned(),
|
||||
column![
|
||||
row![
|
||||
iced::widget::slider(1_000.0..=200_000.0, points, |v| msg(PdfDialogMsg::SecMaxPoints(
|
||||
((v / 1_000.0).round() * 1_000.0).to_string()
|
||||
)))
|
||||
.step(1_000.0)
|
||||
.width(Fill),
|
||||
text_input("", &state.max_points)
|
||||
.on_input(|v| msg(PdfDialogMsg::SecMaxPoints(v)))
|
||||
.size(11)
|
||||
.padding([4, 8])
|
||||
.width(Length::Fixed(90.0))
|
||||
.style(field_style),
|
||||
]
|
||||
.spacing(8)
|
||||
.align_y(iced::Center),
|
||||
row![
|
||||
text(t!("Faster")).size(10).style(muted_style),
|
||||
Space::new().width(Fill),
|
||||
text(t!("More accurate")).size(10).style(muted_style),
|
||||
Space::new().width(Fill),
|
||||
text(crate::tf!("Estimated time: {count} min", count = minutes)).size(10).style(muted_style),
|
||||
],
|
||||
]
|
||||
.spacing(6),
|
||||
);
|
||||
let layer = pick_list(Some(state.layer.clone()), state.layers.clone(), |n: &String| n.clone())
|
||||
.on_select(|n| msg(PdfDialogMsg::SecLayer(n)))
|
||||
.text_size(12)
|
||||
.padding([4, 8])
|
||||
.width(Fill);
|
||||
let color = pick_list(Some(state.color), LineColor::ALL.to_vec(), |c: &LineColor| c.to_string())
|
||||
.on_select(|c| msg(PdfDialogMsg::SecColor(c)))
|
||||
.text_size(12)
|
||||
.padding([4, 8])
|
||||
.width(Fill);
|
||||
let labelled = |label: std::borrow::Cow<'static, str>, control: Element<'a, Message>| -> Element<'a, Message> {
|
||||
row![text(label).size(11).style(muted_style).width(Length::Fixed(70.0)), control]
|
||||
.spacing(6)
|
||||
.align_y(iced::Center)
|
||||
.into()
|
||||
};
|
||||
let output = card(
|
||||
t!("Output geometry").into_owned(),
|
||||
column![
|
||||
labelled(t!("Layer"), layer.into()),
|
||||
labelled(t!("Color"), color.into()),
|
||||
segmented(
|
||||
vec![(false, t!("Lines").into_owned()), (true, t!("2D Polylines").into_owned())],
|
||||
state.polylines,
|
||||
PdfDialogMsg::SecPolylines,
|
||||
),
|
||||
field(t!("Polyline width").into_owned(), &state.width, state.polylines, 150.0, |v| msg(PdfDialogMsg::SecWidth(v))),
|
||||
]
|
||||
.spacing(8),
|
||||
);
|
||||
let pick = |connect: bool| {
|
||||
button(text("⌖").size(12))
|
||||
.on_press(msg(PdfDialogMsg::SecPick(connect)))
|
||||
.style(button_style(false))
|
||||
.padding([4, 8])
|
||||
};
|
||||
let tolerances = card(
|
||||
t!("Extraction tolerances").into_owned(),
|
||||
column![
|
||||
row![field(t!("Minimum line length").into_owned(), &state.min_length, true, 170.0, |v| msg(PdfDialogMsg::SecMinLength(v))), pick(false)]
|
||||
.spacing(6)
|
||||
.align_y(iced::Center),
|
||||
row![field(t!("Connect lines tolerance").into_owned(), &state.connect, true, 170.0, |v| msg(PdfDialogMsg::SecConnect(v))), pick(true)]
|
||||
.spacing(6)
|
||||
.align_y(iced::Center),
|
||||
row![
|
||||
field(t!("Collinear angle tolerance").into_owned(), &state.angle, true, 170.0, |v| msg(PdfDialogMsg::SecAngle(v))),
|
||||
text("0–10°").size(10).style(muted_style)
|
||||
]
|
||||
.spacing(6)
|
||||
.align_y(iced::Center),
|
||||
]
|
||||
.spacing(8),
|
||||
);
|
||||
let body = column![
|
||||
row![extract, max_points].spacing(10),
|
||||
row![output, tolerances].spacing(10),
|
||||
]
|
||||
.spacing(10);
|
||||
let footer = row![
|
||||
button(text("?").size(12))
|
||||
.on_press(msg(PdfDialogMsg::Help("pcsection")))
|
||||
.style(button_style(false))
|
||||
.padding([5, 11]),
|
||||
chip(t!("Preview result").into_owned(), state.preview, msg(PdfDialogMsg::SecPreview(!state.preview))),
|
||||
Space::new().width(Fill),
|
||||
dialog_button(t!("Cancel"), Message::CloseModal, false),
|
||||
dialog_button(t!("Create"), msg(PdfDialogMsg::SecCreate), true),
|
||||
]
|
||||
.spacing(8)
|
||||
.align_y(iced::Center);
|
||||
column![body, footer].spacing(10).padding([10, 12]).width(sizing.width).into()
|
||||
}
|
||||
Reference in new issue
Block a user