Geometry: Refacto and fix purge method.

scenarios
Pierre-Antoine 2025-09-08 11:26:42 +02:00
parent 76ce34c4ea
commit 7181122a3a
6 changed files with 55 additions and 47 deletions

View File

@ -58,7 +58,7 @@ class Point(SQLSubModel):
self._name = name self._name = name
self.modified() self.modified()
def point_is_named(self): def is_named(self):
""" """
Returns: Returns:
True if the point is named. True if the point is named.

View File

@ -368,5 +368,10 @@ class PointXYZ(Point):
a = PointXYZ.distance(p1, p2) a = PointXYZ.distance(p1, p2)
b = PointXYZ.distance(p2, p3) b = PointXYZ.distance(p2, p3)
c = PointXYZ.distance(p3, p1) c = PointXYZ.distance(p3, p1)
s = (a + b + c) / 2
return (s*(s-a) * (s-b)*(s-c)) ** 0.5 s = float((a + b + c) / 2)
res = (
s * abs(s - a) * abs(s - b) * abs(s - c)
) ** 0.5
return res

View File

@ -187,7 +187,7 @@ class Profile(object):
The list of named point The list of named point
""" """
return [point for point in self.points return [point for point in self.points
if point.point_is_named()] if point.is_named()]
def insert_point(self, index: int, point: Point): def insert_point(self, index: int, point: Point):
"""Insert point at index. """Insert point at index.

View File

@ -16,6 +16,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import queue
import random
import logging import logging
import numpy as np import numpy as np
from typing import List from typing import List
@ -929,13 +931,13 @@ class ProfileXYZ(Profile, SQLSubModel):
last_point_not_nan = self._last_point_not_nan(points) last_point_not_nan = self._last_point_not_nan(points)
for index, point in enumerate(points): for index, point in enumerate(points):
if point.point_is_named(): if point.is_named():
index_first_named_point = index index_first_named_point = index
first_named_point = point first_named_point = point
break break
for point in reversed(points): for point in reversed(points):
if point.point_is_named(): if point.is_named():
last_named_point = point last_named_point = point
break break
@ -1009,46 +1011,47 @@ class ProfileXYZ(Profile, SQLSubModel):
if (self.nb_points <= np_purge): if (self.nb_points <= np_purge):
return return
nb_named = 2 # we consider the first and last point as named q_area = queue.PriorityQueue()
area = [0.0] deleted = []
for i in range(1, self.nb_points-1): for ind, point in enumerate(self.points):
if self.point(i).point_is_named(): if (ind == 0) or (ind == self.nb_points - 1):
area.append(9999999.999) continue
nb_named += 1
else: if not point.is_named():
area.append( q_area.put((
PointXYZ.areatriangle3d(
self.point(ind - 1),
point,
self.point(ind + 1)
),
ind,
point
))
while self.nb_points > np_purge and not q_area.empty():
area, ind, point = q_area.get()
self.delete_points([point])
deleted.append(point)
# Recompute point neighbourhood
for i in [ind-1, ind]:
if (i <= 0) or (i >= self.nb_points - 1):
continue
point = self.point(i)
if not point.is_named():
q_area.put((
PointXYZ.areatriangle3d( PointXYZ.areatriangle3d(
self.point(i-1), self.point(i-1),
self.point(i), point,
self.point(i+1))
)
area.append(0.0)
while self.nb_points > max(np_purge, nb_named):
to_rm = np.argmin(area[1:self.nb_points - 1]) + 1
self.delete_i([to_rm])
area.pop(to_rm)
for i in [to_rm-1, to_rm]:
if (i == 0):
continue
if (i == self.nb_points - 1):
continue
if self.point(i).point_is_named():
area[i] = 9999999.999
else:
area[i] = PointXYZ.areatriangle3d(
self.point(i-1),
self.point(i),
self.point(i+1) self.point(i+1)
) ), i, point
))
self.modified() self.modified()
return deleted
def shift(self, x, y, z): def shift(self, x, y, z):
for p in self._points: for p in self._points:

View File

@ -202,16 +202,17 @@ class PurgeCommand(QUndoCommand):
def __init__(self, profile, np_purge): def __init__(self, profile, np_purge):
QUndoCommand.__init__(self) QUndoCommand.__init__(self)
self._deleted = []
self._profile = profile self._profile = profile
self._old = self._profile.points.copy()
self._np_purge = np_purge self._np_purge = np_purge
def undo(self): def undo(self):
self._profile._points = self._old.copy() for point in self._deleted:
point.set_as_not_deleted()
self._profile.modified() self._profile.modified()
def redo(self): def redo(self):
self._profile.purge(self._np_purge) self._deleted = self._profile.purge(self._np_purge)
self._profile.modified() self._profile.modified()

View File

@ -277,18 +277,17 @@ class PurgeCommand(QUndoCommand):
self._reach = reach self._reach = reach
self._np_purge = np_purge self._np_purge = np_purge
self._deleted = {}
self._old = []
for profile in self._reach.profiles:
self._old.append(profile.points.copy())
def undo(self): def undo(self):
for i in range(self._reach.number_profiles): for profile in self._deleted:
self._reach.profiles[i]._points = self._old[i].copy() for point in self._deleted[profile]:
point.set_as_not_deleted()
profile.modified()
def redo(self): def redo(self):
for profile in self._reach._profiles: for profile in self._reach._profiles:
profile.purge(self._np_purge) self._deleted[profile] = profile.purge(self._np_purge)
class ChangeReachCommand(QUndoCommand): class ChangeReachCommand(QUndoCommand):