-
-
Notifications
You must be signed in to change notification settings - Fork 405
Description
Minimal example
The minimal example starts from a list of (x, y, z) coordinates,. Then converts it to a list of gp_Pnt, via a Collection, and stores the list in self.pnts. When the list is recalled at a later stage in the code, some coordinates are incorrect.
py 3.11.10 | packaged by conda-forge [MSC v.1941 64 bit (AMD64)]
OCC.VERSION '7.9.0'
# -*- coding: utf-8 -*-
import numpy as np
from OCC.Core.gp import gp_Pnt
from OCC.Core.TColgp import TColgp_Array1OfPnt
#==============================================================================
class Minimal_Example():
#==============================================================================
def __init__(self):
self.pnts=None
self.inputs=dict()
self.inputs['variant']={'opt':0}
self.inputs['trim']={'skip':False,'by':2}
#------------------------------------------------------------------------------
def pack_list(self):
# Load point coordinates
np_array1 = np.array([
[26.0, 12.0, -1.0],
[2.0, 11.0, 1.0],
[0.0, 12.0, 3.0],
[6.0, 13.0, 6.0],
[2.0, 15.0, 7.0],
[9.0, 17.0, 10.0],
[16.0, 20.0, 12.0],
[14.0, 22.0, 15.0],
[7.0, -26.0, 19.0],
[12.0, 28.0, 22.0],
[2.0, 1.0, 25.0],
[5.0, 12.0, 33.0],
[3.0, 4.0, 5.0],
[-4.0, 9.0, -1.0],
[2.1, 3.0, 11.0]
],float)
nrows= np_array1.shape[0]
# Vary number of points for the purpose of debugging, can be ignored at this stage
if not self.inputs['trim']['skip']:
by=self.inputs['trim']['by']
np_array1 = np_array1[0:(nrows-by),:]
nrows= np_array1.shape[0]
opt=self.inputs['variant']['opt']
if opt==0:
# Original user code, this is the case of interest
# - convert np_arr to occ_arr
# - user code
# - convert occ_arr to list
#
# Please note that attention was paid to start the OCC array index
# to one and not zero like in Python.
occ_arr1 = TColgp_Array1OfPnt(1,nrows)
istart = occ_arr1.Lower()
iend = occ_arr1.Upper()
inpy=0
for iocc in range(istart,iend+1):
coord = np_array1[inpy,:].tolist()
occ_arr1.SetValue(iocc,gp_Pnt(*coord))
inpy=inpy+1
# [... User code here removed for the sake of minimal example...]
# Convert pyOCC array of gp_Pnt to Python list of gp_Pnt
self.pnts=list()
for iocc in range(istart,iend+1):
a_gp_pnt = occ_arr1.Value(iocc)
self.pnts.append(a_gp_pnt)
elif opt==1:
# If there would be no user code in the middle, the code could be simplified by going straightaway from
# np_arr to occ_arr. In that case, the problem seen at later stage would not appear.But it cannot be considered
# as a solution, as the user code removed for the sake of debugging is needed.
self.pnts=list()
for inpy in range(0,nrows):
coord = np_array1[inpy].tolist()
a_gp_pnt = gp_Pnt(*coord)
self.pnts.append(a_gp_pnt)
# Pack the points in the list and print the coordinates to check that eveything is correct up to that point.
print('\n===')
print('*Packed %s point(s), check coords:' % str(nrows))
print([x.Coord() for x in self.pnts])
#------------------------------------------------------------------------------
def unpack_list(self):
# Unpack the list here, and check coordinates. The problem is visible at this stage, some coordinates are wong
#
# What is wrong: the coordinates x and y of the first point, receive a tiny value '1e-311'.
# Only x,y are incorrect, but z is correct. And only first point is wrong, others are OK
print('\n*Unpacked, check coords:')
print([x.Coord() for x in self.pnts ])
#------------------------------------------------------------------------------
def run(self):
self.pack_list()
self.unpack_list()
#==============================================================================
print('\n===== Reproduce the issue')
debugger0 = Minimal_Example()
debugger0.inputs['variant']['opt']=0
debugger0.inputs['trim']['skip']=False
debugger0.inputs['trim']['by']=3
debugger0.run() The output is shown below.
*Packed 12 point(s), check coords:
[(26.0, 12.0, -1.0), (2.0, 11.0, 1.0), (0.0, 12.0, 3.0), (6.0, 13.0, 6.0), (2.0, 15.0, 7.0), (9.0, 17.0, 10.0), (16.0, 20.0, 12.0), (14.0, 22.0, 15.0), (7.0, -26.0, 19.0), (12.0, 28.0, 22.0), (2.0, 1.0, 25.0), (5.0, 12.0, 33.0)]
*Unpacked, check coords:
[(1.131783611129e-311, 1.1318068432973e-311, -1.0), (2.0, 11.0, 1.0), (0.0, 12.0, 3.0), (6.0, 13.0, 6.0), (2.0, 15.0, 7.0), (9.0, 17.0, 10.0), (16.0, 20.0, 12.0), (14.0, 22.0, 15.0), (7.0, -26.0, 19.0), (12.0, 28.0, 22.0), (2.0, 1.0, 25.0), (5.0, 12.0, 33.0)]
The formatting in bold points to the values which are wrong.
Additional tests
- Moving from
opt0 to 1. The problem disappears but as commented in the code it cannot be accepted as a solution
for opt in [0,1]:
debugger0 = Minimal_Example()
debugger0.inputs['variant']['opt']=opt
debugger0.inputs['trim']['skip']=False
debugger0.inputs['trim']['by']=3
debugger0.run() - Changing the number of points. This is the most surprising, the problem occurs when the inputs contains 12 points.
It just works fine with more or less points. To change the number of points, just set thebyparameters to the number of
elements to be removed from the original list.
for by in range(0,14):
debugger0 = Minimal_Example()
debugger0.inputs['variant']['opt']=0
debugger0.inputs['trim']['skip']=False
debugger0.inputs['trim']['by']=by
debugger0.run()