Это ошибка в NURBS-python при обновлении контрольных точек? - PullRequest
0 голосов
/ 16 мая 2019

Я использовал NURBS-python и обнаружил интересную проблему, и не уверен, что это сделано намеренно или это просто ошибка. Я хотел бы представить это с 2 кодами.

Первый должен выводить то же самое, что и второй, а это не так. Первый успешно обновил контрольные точки кривой NURBS и нарисовал новую кривую,

Способ изменения списка контрольных точек влияет на результаты.

import math
from geomdl import BSpline
from geomdl import NURBS
from geomdl import fitting
from geomdl import convert
from geomdl.visualization import VisMPL

P1=[[0, 0], [0, 1], [1, 1], [1, 0], [1, -1], [0, -1], [0, 0]]
Degree=3
CPN=5

P2=[[0, 0], [0, 1], [2, 1], [2, 0], [2, -1], [0, -1], [0, 0]]
CP=[[0, 0], [1, 2], [2, 0], [1, -2], [0, 0]]

c1=NURBS.Curve()
c1.degree=Degree
c1.ctrlpts=P1
c1.weights=[1, 1, 1, 1, 1, 1, 1]
c1.knotvector=[0, 0, 0, 0, 0.25, 0.5, 0.75, 1, 1, 1, 1]

c1.vis=VisMPL.VisCurve2D()
c1.render()

c1.ctrlpts=P2
c1.vis=VisMPL.VisCurve2D()
c1.render()


c2=convert.bspline_to_nurbs(fitting.approximate_curve(P1, Degree, ctrlpts_size=CPN))

c2.vis=VisMPL.VisCurve2D()
c2.render()

c2.ctrlpts=CP

c2.vis=VisMPL.VisCurve2D()
c2.render()

в то время как второй просто обновляет контрольные точки, сама кривая вообще не изменилась.

import math
from geomdl import BSpline
from geomdl import NURBS
from geomdl import fitting
from geomdl import convert
from geomdl.visualization import VisMPL

P1=[[0, 0], [0, 1], [1, 1], [1, 0], [1, -1], [0, -1], [0, 0]]
Degree=3
CPN=5

P2=[[0, 0], [0, 1], [2, 1], [2, 0], [2, -1], [0, -1], [0, 0]]
CP=[[0, 0], [1, 2], [2, 0], [1, -2], [0, 0]]

c1=NURBS.Curve()
c1.degree=Degree
c1.ctrlpts=P1
c1.weights=[1, 1, 1, 1, 1, 1, 1]
c1.knotvector=[0, 0, 0, 0, 0.25, 0.5, 0.75, 1, 1, 1, 1]

c1.vis=VisMPL.VisCurve2D()
c1.render()


for i in range(len(P2)):
    c1.ctrlpts[i]=P2[i]
c1.vis=VisMPL.VisCurve2D()
c1.render()

c2=convert.bspline_to_nurbs(fitting.approximate_curve(P1, Degree, ctrlpts_size=CPN))

c2.vis=VisMPL.VisCurve2D()
c2.render()

for i in range(len(CP)):
    c2.ctrlpts[i]=CP[i]

c2.vis=VisMPL.VisCurve2D()
c2.render()

Пожалуйста, помогите, спасибо.

1 Ответ

0 голосов
/ 16 мая 2019

Curve.ctrlpts является свойством .Когда вы получаете доступ к геттеру, он возвращает список контрольных точек.Доступ к установщику делает намного больше, в основном проверка согласованности и необходимые очистки.

Когда вызывается cpts = c1.ctrlpts, вызывается метод свойства __get__, ссылка на объект списка, который хранит контрольные точки внутриЭкземпляр Curve возвращается и присваивается переменной cpts:

>>> cpts = c1.ctrlpts
>>> type(cpts)
<class 'list'>

Когда вы просматриваете список cpts, вы фактически просматриваете его ссылку в экземпляре класса Curve.Поскольку вы напрямую взаимодействуете с объектом списка, вы не получаете доступ к установщику ctrlpts, который на самом деле выполняет очистку, вызывая метод Curve.reset().

К сожалению, невозможно переопределить методы объектавстроенные классы (классы, определенные на уровне API).

>>> list.__getitem__ = my_getter_method
TypeError: can't set attributes of built-in/extension type 'list'

В результате запуск метода Curve.reset() при изменении базового объекта list становится немного сложным (но не невозможным).).

Лучший и самый безопасный способ установить контрольные точки - использовать метод установки свойства:

my_ctrlpts = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
c1.ctrlpts = my_ctrlpts

Если вы хотите использовать цикл for, то вам нужновызовите метод сброса вручную:

for i in range(len(P2)):
    c1.ctrlpts[i]=P2[i]
c1.reset(evalpts=True)

Примечание: я являюсь автором NURBS-Python (geomdl)

...