Skip to content

Added .pyi files #156

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions pywavefront/__init__.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from _typeshed import Incomplete
from pywavefront.exceptions import PywavefrontException as PywavefrontException
from pywavefront.obj import ObjParser as ObjParser
from pywavefront.wavefront import Wavefront as Wavefront

__version__: str
logger: Incomplete
log_handler: Incomplete

def configure_logging(level, formatter: Incomplete | None = None) -> None: ...
59 changes: 59 additions & 0 deletions pywavefront/cache.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from _typeshed import Incomplete
from pywavefront.material import MaterialParser

logger: Incomplete

def cache_name(path):
"""Generate the name of the binary cache file"""
def meta_name(path):
"""Generate the name of the meta file"""

class CacheLoader:
material_parser_cls = MaterialParser
wavefront: Incomplete
file_name: Incomplete
path: Incomplete
encoding: Incomplete
strict: Incomplete
dir: Incomplete
meta: Incomplete
def __init__(self, file_name, wavefront, strict: bool = False, create_materials: bool = False, encoding: str = 'utf-8', parse: bool = True, **kwargs) -> None: ...
def parse(self): ...
def load_vertex_buffer(self, fd, material, length) -> None:
"""
Load vertex data from file. Can be overriden to reduce data copy
:param fd: file object
:param material: The material these vertices belong to
:param length: Byte length of the vertex data
"""

class CacheWriter:
file_name: Incomplete
wavefront: Incomplete
meta: Incomplete
def __init__(self, file_name, wavefront) -> None: ...
def write(self) -> None: ...

class Meta:
"""
Metadata for binary obj cache files
"""
format_version: str
def __init__(self, **kwargs) -> None: ...
def add_vertex_buffer(self, material, vertex_format, byte_offset, byte_length) -> None:
"""Add a vertex buffer"""
@classmethod
def from_file(cls, path): ...
def write(self, path) -> None:
"""Save the metadata as json"""
@property
def version(self): ...
@property
def created_at(self): ...
@property
def vertex_buffers(self): ...
@property
def mtllibs(self): ...
@mtllibs.setter
def mtllibs(self, value) -> None: ...
2 changes: 2 additions & 0 deletions pywavefront/exceptions.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class PywavefrontException(Exception):
"""Generic exception for this package to separate from common ones"""
102 changes: 102 additions & 0 deletions pywavefront/material.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
from _typeshed import Incomplete
from pathlib import Path as Path
from pywavefront.parser import Parser
from pywavefront.texture import Texture

logger: Incomplete

class Material:
texture_cls = Texture
name: Incomplete
diffuse: Incomplete
ambient: Incomplete
specular: Incomplete
emissive: Incomplete
transparency: float
shininess: float
optical_density: float
illumination_model: int
texture: Incomplete
texture_ambient: Incomplete
texture_specular_color: Incomplete
texture_specular_highlight: Incomplete
texture_alpha: Incomplete
texture_bump: Incomplete
is_default: Incomplete
vertex_format: str
vertices: Incomplete
gl_floats: Incomplete
def __init__(self, name, is_default: bool = False, has_faces: bool = False) -> None:
"""
Create a new material
:param name: Name of the material
:param is_default: Is this an auto created default material?
"""
@property
def has_normals(self): ...
@property
def has_uvs(self): ...
@property
def has_colors(self): ...
@property
def vertex_size(self):
"""How many float each vertex contains in the interleaved data"""
def pad_light(self, values):
"""Accept an array of up to 4 values, and return an array of 4 values.
If the input array is less than length 4, pad it with zeroes until it
is length 4. Also ensure each value is a float"""
def set_alpha(self, alpha) -> None:
"""Set alpha/last value on all four lighting attributes."""
def set_diffuse(self, values: Incomplete | None = None) -> None: ...
def set_ambient(self, values: Incomplete | None = None) -> None: ...
def set_specular(self, values: Incomplete | None = None) -> None: ...
def set_emissive(self, values: Incomplete | None = None) -> None: ...
def set_texture(self, name, search_path) -> None: ...
def set_texture_ambient(self, name, search_path) -> None: ...
def set_texture_specular_color(self, name, search_path) -> None: ...
def set_texture_specular_highlight(self, name, search_path) -> None: ...
def set_texture_alpha(self, name, search_path) -> None: ...
def set_texture_bump(self, name, search_path) -> None: ...
def unset_texture(self) -> None: ...

class MaterialParser(Parser):
"""Object to parse lines of a materials definition file."""
materials: Incomplete
this_material: Incomplete
collect_faces: Incomplete
def __init__(self, file_name, strict: bool = False, encoding: str = 'utf-8', parse: bool = True, collect_faces: bool = False) -> None:
"""
Create a new material parser
:param file_name: file name and path of obj file to read
:param strict: Enable strict mode
:param encoding: Encoding to read the text files
:param parse: Should parse be called immediately or manually called later?
"""
def parse_newmtl(self) -> None: ...
def parse_Kd(self) -> None: ...
def parse_Ka(self) -> None: ...
def parse_Ks(self) -> None: ...
def parse_Ke(self) -> None: ...
def parse_Ns(self) -> None: ...
def parse_d(self) -> None:
"""Transparency"""
def parse_Tr(self) -> None:
"""Transparency (alternative)"""
def parse_map_Kd(self) -> None:
"""Diffuse map"""
def parse_map_Ka(self) -> None:
"""Ambient map"""
def parse_map_Ks(self) -> None:
"""Specular color map"""
def parse_map_Ns(self) -> None:
"""Specular color map"""
def parse_map_d(self) -> None:
"""Alpha map"""
def parse_bump(self) -> None:
"""Bump map (from the spec)"""
def parse_map_bump(self) -> None:
"""Bump map (variant)"""
def parse_map_Bump(self) -> None:
"""Bump map (variant)"""
def parse_Ni(self) -> None: ...
def parse_illum(self) -> None: ...
14 changes: 14 additions & 0 deletions pywavefront/mesh.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from _typeshed import Incomplete

class Mesh:
"""This is a basic mesh for drawing using OpenGL. Interestingly, it does
not contain its own vertices. These are instead drawn via materials."""
name: Incomplete
materials: Incomplete
has_faces: Incomplete
faces: Incomplete
def __init__(self, name: Incomplete | None = None, has_faces: bool = False) -> None: ...
def has_material(self, new_material):
"""Determine whether we already have a material of this name."""
def add_material(self, material) -> None:
"""Add a material to the mesh, IF it's not already present."""
84 changes: 84 additions & 0 deletions pywavefront/obj.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from _typeshed import Incomplete
from collections.abc import Generator
from pywavefront.cache import CacheLoader, CacheWriter, Meta as Meta
from pywavefront.material import MaterialParser
from pywavefront.parser import Parser

logger: Incomplete

class ObjParser(Parser):
"""This parser parses lines from .obj files."""
material_parser_cls = MaterialParser
cache_loader_cls = CacheLoader
cache_writer_cls = CacheWriter
wavefront: Incomplete
mesh: Incomplete
material: Incomplete
create_materials: Incomplete
collect_faces: Incomplete
cache: Incomplete
cache_loaded: Incomplete
normals: Incomplete
tex_coords: Incomplete
def __init__(self, wavefront, file_name, strict: bool = False, encoding: str = 'utf-8', create_materials: bool = False, collect_faces: bool = False, parse: bool = True, cache: bool = False) -> None:
"""
Create a new obj parser
:param wavefront: The wavefront object
:param file_name: file name and path of obj file to read
:param strict: Enable strict mode
:param encoding: Encoding to read the text files
:param create_materials: Create materials if they don't exist
:param cache: Cache the loaded obj files in binary format
:param parse: Should parse be called immediately or manually called later?
"""
def parse(self) -> None:
"""Trigger cache load or call superclass parse()"""
def load_cache(self) -> None:
"""Loads the file using cached data"""
def post_parse(self) -> None:
"""Called after parsing is done"""
def parse_v(self) -> None: ...
line: Incomplete
values: Incomplete
def consume_vertices(self) -> Generator[Incomplete]:
"""
Consumes all consecutive vertices.
NOTE: There is no guarantee this will consume all vertices since other
statements can also occur in the vertex list
"""
def parse_vn(self) -> None: ...
def consume_normals(self) -> Generator[Incomplete]:
"""Consumes all consecutive texture coordinate lines"""
def parse_vt(self) -> None: ...
def consume_texture_coordinates(self) -> Generator[Incomplete]:
"""Consume all consecutive texture coordinates"""
def parse_mtllib(self) -> None: ...
def parse_usemtl(self) -> None: ...
def parse_usemat(self) -> None: ...
def parse_o(self) -> None: ...
def parse_f(self) -> None: ...
def consume_faces(self, collected_faces: Incomplete | None = None) -> Generator[Incomplete, Incomplete]:
"""
Consume all consecutive faces
If more than three vertices are specified, we triangulate by the following procedure:
Let the face have n vertices in the order v_1 v_2 v_3 ... v_n, n >= 3.
We emit the first face as usual: (v_1, v_2, v_3). For each remaining vertex v_j,
j > 3, we emit (v_j, v_1, v_{j - 1}), e.g. (v_4, v_1, v_3), (v_5, v_1, v_4).
In a perfect world we could consume all vertices straight forward and draw using
GL_TRIANGLE_FAN (which exactly matches the procedure above).
This is however rarely the case.
* If the face is co-planar but concave, then you need to triangulate the face.
* If the face is not-coplanar, you are screwed, because OBJ doesn't preserve enough information
to know what tessellation was intended.
We always triangulate to make it simple.
:param collected_faces: A list into which all (possibly triangulated) faces will be written in the form
of triples of the corresponding absolute vertex IDs. These IDs index the list
self.wavefront.vertices.
Specify None to prevent consuming faces (and thus saving memory usage).
"""
47 changes: 47 additions & 0 deletions pywavefront/parser.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from _typeshed import Incomplete
from collections.abc import Generator

logger: Incomplete

def auto_consume(func):
"""Decorator for auto consuming lines when leaving the function"""

class Parser:
"""This defines a generalized parse dispatcher; all parse functions
reside in subclasses."""
auto_post_parse: bool
file_name: Incomplete
strict: Incomplete
encoding: Incomplete
dir: Incomplete
dispatcher: Incomplete
lines: Incomplete
line: Incomplete
values: Incomplete
def __init__(self, file_name, strict: bool = False, encoding: str = 'utf-8') -> None:
"""
Initializer for the base parser
:param file_name: Name and path of the file to read
:param strict: Enable or disable strict mode
"""
def create_line_generator(self) -> Generator[Incomplete]:
"""
Creates a generator function yielding lines in the file
Should only yield non-empty lines
"""
def next_line(self) -> None:
"""Read the next line from the line generator and split it"""
def consume_line(self) -> None:
"""
Tell the parser we are done with this line.
This is simply by setting None values.
"""
def parse(self) -> None:
"""
Parse all the lines in the obj file
Determines what type of line we are and dispatch appropriately.
"""
def post_parse(self) -> None:
"""Override to trigger operations after parsing is complete"""
def parse_fallback(self) -> None:
"""Fallback method when parser doesn't know the statement"""
112 changes: 112 additions & 0 deletions pywavefront/texture.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
from _typeshed import Incomplete

class TextureOptions:
name: str
blendu: str
blendv: str
bm: float
boost: float
cc: str
clamp: str
imfchan: str
mm: Incomplete
o: Incomplete
s: Incomplete
t: Incomplete
texres: Incomplete
def __init__(self) -> None:
"""Set up options with sane defaults"""

class TextureOptionsParser:
def __init__(self, line) -> None: ...
def parse(self): ...
def parse_blendu(self) -> None:
"""The -blendu option turns texture blending in the horizontal direction
(u direction) on or off. The default is on.
"""
def parse_blendv(self) -> None:
"""The -blendv option turns texture blending in the vertical direction (v
direction) on or off. The default is on.
"""
def parse_bm(self) -> None:
"""The -bm option specifies a bump multiplier"""
def parse_boost(self) -> None:
"""The -boost option increases the sharpness, or clarity, of mip-mapped
texture files
"""
def parse_cc(self) -> None:
"""The -cc option turns on color correction for the texture"""
def parse_clamp(self) -> None:
"""The -clamp option turns clamping on or off."""
def parse_imfchan(self) -> None:
"""The -imfchan option specifies the channel used to create a scalar or
bump texture.
"""
def parse_mm(self) -> None:
"""The -mm option modifies the range over which scalar or color texture
values may vary
"""
def parse_o(self) -> None:
"""The -o option offsets the position of the texture map on the surface by
shifting the position of the map origin.
"""
def parse_s(self) -> None:
"""The -s option scales the size of the texture pattern on the textured
surface by expanding or shrinking the pattern
"""
def parse_t(self) -> None:
"""The -t option turns on turbulence for textures."""
def parse_texres(self) -> None:
"""The -texres option specifies the resolution of texture created when an
image is used.
"""

class Texture:
image: Incomplete
def __init__(self, name, search_path) -> None:
"""Create a texture.
Args:
name (str): The texture name possibly with path and options as it appear in the material
search_path (str): Absolute or relative path the texture might be located.
"""
@property
def name(self):
"""str: The texture path as it appears in the material"""
@name.setter
def name(self, value) -> None: ...
@property
def options(self) -> TextureOptions:
"""TextureOptions: Options for this texture"""
def find(self, path: Incomplete | None = None):
"""Find the texture in the configured search path
By default a search will be done in the same directory as
the obj file including all subdirectories if ``path`` does not exist.
Args:
path: Override the search path
Raises:
FileNotFoundError if not found
"""
@property
def file_name(self):
"""str: Obtains the file name of the texture.
Sometimes materials contains a relative or absolute path
to textures, something that often doesn't reflect the
textures real location.
"""
@property
def path(self):
"""str: search_path + name"""
@path.setter
def path(self, value) -> None: ...
@property
def image_name(self):
"""Wrap the old property name to not break compatibility.
The value will always be the texture path as it appears in the material.
"""
@image_name.setter
def image_name(self, value) -> None:
"""Wrap the old property name to not break compatibility"""
def exists(self):
"""bool: Does the texture exist"""
22 changes: 22 additions & 0 deletions pywavefront/visualization.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from pyglet.gl import *
from _typeshed import Incomplete
from pywavefront.mesh import Mesh as Mesh

def same(v): ...

VERTEX_FORMATS: Incomplete

def draw(instance, lighting_enabled: bool = True, textures_enabled: bool = True) -> None:
"""Generic draw function"""
def draw_materials(materials, lighting_enabled: bool = True, textures_enabled: bool = True) -> None:
"""Draw a dict of meshes"""
def draw_material(material, face=..., lighting_enabled: bool = True, textures_enabled: bool = True) -> None:
"""Draw a single material"""
def gl_light(lighting):
"""Return a GLfloat with length 4, containing the 4 lighting values."""
def bind_texture(texture) -> None:
"""Draw a single texture"""
def load_image(name):
"""Load an image"""
def verify_dimensions(image) -> None: ...
def verify(image, dimension) -> None: ...
26 changes: 26 additions & 0 deletions pywavefront/wavefront.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from _typeshed import Incomplete
from pywavefront import ObjParser

logger: Incomplete

class Wavefront:
parser_cls = ObjParser
file_name: Incomplete
mtllibs: Incomplete
materials: Incomplete
meshes: Incomplete
vertices: Incomplete
mesh_list: Incomplete
parser: Incomplete
def __init__(self, file_name, strict: bool = False, encoding: str = 'utf-8', create_materials: bool = False, collect_faces: bool = False, parse: bool = True, cache: bool = False) -> None:
"""
Create a Wavefront instance
:param file_name: file name and path of obj file to read
:param strict: Enable strict mode
:param encoding: What text encoding the parser should use
:param create_materials: Create materials if they don't exist
:param parse: Should parse be called immediately or manually called later?
"""
def parse(self) -> None:
"""Manually call the parser. This is used when parse=False"""
def add_mesh(self, the_mesh) -> None: ...