Skip to content

Commit

Permalink
Merge branch 'release/3.1.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
wolph committed Nov 8, 2023
2 parents bdaa099 + a1bce5d commit 60797a3
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 47 deletions.
20 changes: 0 additions & 20 deletions .github/stale.yml

This file was deleted.

17 changes: 17 additions & 0 deletions .github/workflows/stale.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Close stale issues and pull requests

on:
workflow_dispatch:
schedule:
- cron: '0 0 * * *' # Run every day at midnight

jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v8
with:
days-before-stale: 30
days-before-pr-stale: -1
exempt-issue-labels: in-progress,help-wanted,pinned,security,enhancement
stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days'
6 changes: 6 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Security contact information
------------------------------------------------------------------------------

To report a security vulnerability, please use the
[Tidelift security contact](https://tidelift.com/security>).
Tidelift will coordinate the fix and disclosure.
2 changes: 1 addition & 1 deletion stl/__about__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
__package_name__ = 'numpy-stl'
__import_name__ = 'stl'
__version__ = '3.0.1'
__version__ = '3.1.0'
__author__ = 'Rick van Hattem'
__author_email__ = '[email protected]'
__description__ = ' '.join('''
Expand Down
98 changes: 72 additions & 26 deletions stl/base.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import enum
import itertools
import logging
import math

import numpy
import logging

try: # pragma: no cover
from collections import abc
except ImportError: # pragma: no cover
import collections as abc

from python_utils import logger


#: When removing empty areas, remove areas that are smaller than this
AREA_SIZE_THRESHOLD = 0
#: Vectors in a point
Expand Down Expand Up @@ -167,9 +169,9 @@ class BaseMesh(logger.Logged, abc.Mapping):
#: - vectors: :func:`numpy.float32`, `(3, 3)`
#: - attr: :func:`numpy.uint16`, `(1, )`
dtype = numpy.dtype([
('normals', numpy.float32, (3, )),
('normals', numpy.float32, (3,)),
('vectors', numpy.float32, (3, 3)),
('attr', numpy.uint16, (1, )),
('attr', numpy.uint16, (1,)),
])
dtype = dtype.newbyteorder('<') # Even on big endian arches, use little e.

Expand Down Expand Up @@ -346,21 +348,66 @@ def update_areas(self, normals=None):
def update_centroids(self):
self.centroids = numpy.mean([self.v0, self.v1, self.v2], axis=0)

def check(self):
'''Check the mesh is valid or not'''
return self.is_closed()
def check(self, exact=False):
'''Check the mesh is valid or not
:param bool exact: Perform exact checks.
'''
return self.is_closed(exact=exact)

def is_closed(self, exact=False): # pragma: no cover
'''Check the mesh is closed or not
:param bool exact: Perform a exact check on edges.
'''

if exact:
reversed_triangles = (
numpy.cross(self.v1 - self.v0,
self.v2 - self.v0) * self.normals
).sum(axis=1) < 0
directed_edges = {
tuple(edge.ravel() if not rev else edge[::-1, :].ravel())
for rev, edge in zip(
itertools.cycle(reversed_triangles),
itertools.chain(
self.vectors[:, (0, 1), :],
self.vectors[:, (1, 2), :],
self.vectors[:, (2, 0), :],
),
)
}
if len(directed_edges) == 3 * self.data.size:
undirected_edges = {frozenset((edge[:3], edge[3:])) for edge in
directed_edges}
if len(directed_edges) == 2 * len(undirected_edges):
return True

def is_closed(self): # pragma: no cover
"""Check the mesh is closed or not"""
if numpy.isclose(self.normals.sum(axis=0), 0, atol=1e-4).all():
return True
else:
self.warning('''
Your mesh is not closed, the mass methods will not function
correctly on this mesh. For more info:
https://github.com/WoLpH/numpy-stl/issues/69
'''.strip())
return False
Use of not exact is_closed check. This check can lead to misleading
results. You could try to use `exact=True`.
See:
- false positive: https://github.com/wolph/numpy-stl/issues/198
- false negative: https://github.com/wolph/numpy-stl/pull/213
'''.strip()
)
normals = numpy.asarray(self.normals, dtype=numpy.float64)
allowed_max_errors = (
numpy.abs(normals).sum(axis=0) * numpy.finfo(
numpy.float32).eps
)
if (numpy.abs(normals.sum(axis=0)) <= allowed_max_errors).all():
return True

self.warning(
'''
Your mesh is not closed, the mass methods will not function
correctly on this mesh. For more info:
https://github.com/WoLpH/numpy-stl/issues/69
'''.strip()
)
return False

def get_mass_properties(self):
'''
Expand Down Expand Up @@ -538,7 +585,7 @@ def translate(self, translation):
:param numpy.array translation: Translation vector (x, y, z)
'''
assert len(translation) == 3, "Translation vector must be of length 3"
assert len(translation) == 3, 'Translation vector must be of length 3'
self.x += translation[0]
self.y += translation[1]
self.z += translation[2]
Expand All @@ -555,10 +602,10 @@ def transform(self, matrix):
part of the transformation
'''
is_a_4x4_matrix = matrix.shape == (4, 4)
assert is_a_4x4_matrix, "Transformation matrix must be of shape (4, 4)"
assert is_a_4x4_matrix, 'Transformation matrix must be of shape (4, 4)'
rotation = matrix[0:3, 0:3]
unit_det_rotation = numpy.allclose(numpy.linalg.det(rotation), 1.0)
assert unit_det_rotation, "Rotation matrix has not a unit determinant"
assert unit_det_rotation, 'Rotation matrix has not a unit determinant'
for i in range(3):
self.vectors[:, i] = numpy.dot(rotation, self.vectors[:, i].T).T
self.x += matrix[0, 3]
Expand Down Expand Up @@ -649,17 +696,16 @@ def subexpression(x):
inertia = numpy.zeros((3, 3))

inertia[0, 0] = (intg[5] + intg[6]) * density - vmass * (
cogsq[1] + cogsq[2])
cogsq[1] + cogsq[2])
inertia[1, 1] = (intg[4] + intg[6]) * density - vmass * (
cogsq[2] + cogsq[0])
cogsq[2] + cogsq[0])
inertia[2, 2] = (intg[4] + intg[5]) * density - vmass * (
cogsq[0] + cogsq[1])
cogsq[0] + cogsq[1])
inertia[0, 1] = inertia[1, 0] = -(
intg[7] * density - vmass * cog[0] * cog[1])
intg[7] * density - vmass * cog[0] * cog[1])
inertia[1, 2] = inertia[2, 1] = -(
intg[8] * density - vmass * cog[1] * cog[2])
intg[8] * density - vmass * cog[1] * cog[2])
inertia[0, 2] = inertia[2, 0] = -(
intg[9] * density - vmass * cog[2] * cog[0])
intg[9] * density - vmass * cog[2] * cog[0])

return volume, vmass, cog, inertia

0 comments on commit 60797a3

Please sign in to comment.