From a272d74e704cf978c2137e20fe09727477186f2e Mon Sep 17 00:00:00 2001 From: guojianzhu Date: Thu, 4 Jul 2024 04:32:47 +0800 Subject: [PATCH] feat: launch LivePortrait --- .gitignore | 17 + .vscode/settings.json | 19 + app.py | 136 + assets/.gitattributes | 23 + assets/docs/inference.gif | 3 + assets/docs/showcase.gif | 3 + assets/docs/showcase2.gif | 3 + assets/examples/driving/d0.mp4 | 3 + assets/examples/driving/d1.mp4 | 3 + assets/examples/driving/d2.mp4 | 3 + assets/examples/driving/d3.mp4 | 3 + assets/examples/driving/d5.mp4 | 3 + assets/examples/driving/d6.mp4 | 3 + assets/examples/driving/d7.mp4 | 3 + assets/examples/driving/d8.mp4 | 3 + assets/examples/driving/d9.mp4 | 3 + assets/examples/source/s0.jpg | 3 + assets/examples/source/s1.jpg | 3 + assets/examples/source/s10.jpg | 3 + assets/examples/source/s2.jpg | 3 + assets/examples/source/s3.jpg | 3 + assets/examples/source/s4.jpg | 3 + assets/examples/source/s5.jpg | 3 + assets/examples/source/s6.jpg | 3 + assets/examples/source/s7.jpg | 3 + assets/examples/source/s8.jpg | 3 + assets/examples/source/s9.jpg | 3 + assets/gradio_description_animation.md | 7 + assets/gradio_description_retargeting.md | 7 + assets/gradio_description_upload.md | 4 + assets/gradio_title.md | 10 + inference.py | 33 + pretrained_weights/.gitkeep | 0 readme.md | 145 + speed.py | 192 + src/config/__init__.py | 0 src/config/argument_config.py | 44 + src/config/base_config.py | 29 + src/config/crop_config.py | 18 + src/config/inference_config.py | 49 + src/config/models.yaml | 43 + src/gradio_pipeline.py | 104 + src/live_portrait_pipeline.py | 195 + src/live_portrait_wrapper.py | 335 + src/modules/__init__.py | 0 src/modules/appearance_feature_extractor.py | 48 + src/modules/convnextv2.py | 149 + src/modules/dense_motion.py | 104 + src/modules/motion_extractor.py | 35 + src/modules/spade_generator.py | 59 + src/modules/stitching_retargeting_network.py | 38 + src/modules/util.py | 441 + src/modules/warping_network.py | 77 + src/template_maker.py | 65 + src/utils/__init__.py | 0 src/utils/camera.py | 75 + src/utils/crop.py | 393 + src/utils/cropper.py | 143 + .../dependencies/insightface/__init__.py | 21 + .../dependencies/insightface/app/__init__.py | 2 + .../dependencies/insightface/app/common.py | 49 + .../insightface/app/face_analysis.py | 108 + .../insightface/app/mask_renderer.py | 232 + .../insightface/commands/__init__.py | 13 + .../insightface/commands/insightface_cli.py | 29 + .../insightface/commands/model_download.py | 36 + .../commands/rec_add_mask_param.py | 94 + .../dependencies/insightface/data/__init__.py | 2 + .../dependencies/insightface/data/image.py | 27 + .../data/images/Tom_Hanks_54745.png | Bin 0 -> 12123 bytes .../insightface/data/images/mask_black.jpg | Bin 0 -> 21308 bytes .../insightface/data/images/mask_blue.jpg | Bin 0 -> 44728 bytes .../insightface/data/images/mask_green.jpg | Bin 0 -> 6116 bytes .../insightface/data/images/mask_white.jpg | Bin 0 -> 78905 bytes .../insightface/data/images/t1.jpg | Bin 0 -> 128824 bytes .../insightface/data/objects/meanshape_68.pkl | Bin 0 -> 974 bytes .../insightface/data/pickle_object.py | 17 + .../insightface/data/rec_builder.py | 71 + .../insightface/model_zoo/__init__.py | 6 + .../insightface/model_zoo/arcface_onnx.py | 92 + .../insightface/model_zoo/attribute.py | 94 + .../insightface/model_zoo/inswapper.py | 114 + .../insightface/model_zoo/landmark.py | 114 + .../insightface/model_zoo/model_store.py | 103 + .../insightface/model_zoo/model_zoo.py | 97 + .../insightface/model_zoo/retinaface.py | 301 + .../insightface/model_zoo/scrfd.py | 348 + .../insightface/thirdparty/__init__.py | 0 .../insightface/thirdparty/face3d/__init__.py | 4 + .../thirdparty/face3d/mesh/__init__.py | 15 + .../face3d/mesh/cython/mesh_core.cpp | 375 + .../thirdparty/face3d/mesh/cython/mesh_core.h | 83 + .../face3d/mesh/cython/mesh_core_cython.c | 9091 ++++++++++++ .../face3d/mesh/cython/mesh_core_cython.cpp | 11757 ++++++++++++++++ ...core_cython.cpython-39-x86_64-linux-gnu.so | Bin 0 -> 156864 bytes .../face3d/mesh/cython/mesh_core_cython.pyx | 109 + .../thirdparty/face3d/mesh/cython/setup.py | 20 + .../insightface/thirdparty/face3d/mesh/io.py | 142 + .../thirdparty/face3d/mesh/light.py | 213 + .../thirdparty/face3d/mesh/render.py | 135 + .../thirdparty/face3d/mesh/transform.py | 383 + .../insightface/thirdparty/face3d/mesh/vis.py | 24 + .../thirdparty/face3d/mesh_numpy/__init__.py | 10 + .../thirdparty/face3d/mesh_numpy/io.py | 170 + .../thirdparty/face3d/mesh_numpy/light.py | 215 + .../thirdparty/face3d/mesh_numpy/render.py | 287 + .../thirdparty/face3d/mesh_numpy/transform.py | 385 + .../thirdparty/face3d/mesh_numpy/vis.py | 24 + .../face3d/morphable_model/__init__.py | 7 + .../thirdparty/face3d/morphable_model/fit.py | 272 + .../thirdparty/face3d/morphable_model/load.py | 110 + .../face3d/morphable_model/morphabel_model.py | 143 + .../insightface/utils/__init__.py | 6 + .../insightface/utils/constant.py | 3 + .../insightface/utils/download.py | 95 + .../insightface/utils/face_align.py | 103 + .../insightface/utils/filesystem.py | 157 + .../dependencies/insightface/utils/storage.py | 52 + .../insightface/utils/transform.py | 116 + src/utils/face_analysis_diy.py | 79 + src/utils/helper.py | 175 + src/utils/io.py | 97 + src/utils/landmark_runner.py | 89 + src/utils/resources/.gitattributes | 1 + src/utils/resources/mask_template.png | 3 + src/utils/retargeting_utils.py | 76 + src/utils/rprint.py | 16 + src/utils/timer.py | 29 + src/utils/video.py | 139 + video2template.py | 37 + 130 files changed, 30323 insertions(+) create mode 100644 .gitignore create mode 100644 .vscode/settings.json create mode 100644 app.py create mode 100644 assets/.gitattributes create mode 100644 assets/docs/inference.gif create mode 100644 assets/docs/showcase.gif create mode 100644 assets/docs/showcase2.gif create mode 100644 assets/examples/driving/d0.mp4 create mode 100644 assets/examples/driving/d1.mp4 create mode 100644 assets/examples/driving/d2.mp4 create mode 100644 assets/examples/driving/d3.mp4 create mode 100644 assets/examples/driving/d5.mp4 create mode 100644 assets/examples/driving/d6.mp4 create mode 100644 assets/examples/driving/d7.mp4 create mode 100644 assets/examples/driving/d8.mp4 create mode 100644 assets/examples/driving/d9.mp4 create mode 100644 assets/examples/source/s0.jpg create mode 100644 assets/examples/source/s1.jpg create mode 100644 assets/examples/source/s10.jpg create mode 100644 assets/examples/source/s2.jpg create mode 100644 assets/examples/source/s3.jpg create mode 100644 assets/examples/source/s4.jpg create mode 100644 assets/examples/source/s5.jpg create mode 100644 assets/examples/source/s6.jpg create mode 100644 assets/examples/source/s7.jpg create mode 100644 assets/examples/source/s8.jpg create mode 100644 assets/examples/source/s9.jpg create mode 100644 assets/gradio_description_animation.md create mode 100644 assets/gradio_description_retargeting.md create mode 100644 assets/gradio_description_upload.md create mode 100644 assets/gradio_title.md create mode 100644 inference.py create mode 100644 pretrained_weights/.gitkeep create mode 100644 readme.md create mode 100644 speed.py create mode 100644 src/config/__init__.py create mode 100644 src/config/argument_config.py create mode 100644 src/config/base_config.py create mode 100644 src/config/crop_config.py create mode 100644 src/config/inference_config.py create mode 100644 src/config/models.yaml create mode 100644 src/gradio_pipeline.py create mode 100644 src/live_portrait_pipeline.py create mode 100644 src/live_portrait_wrapper.py create mode 100644 src/modules/__init__.py create mode 100644 src/modules/appearance_feature_extractor.py create mode 100644 src/modules/convnextv2.py create mode 100644 src/modules/dense_motion.py create mode 100644 src/modules/motion_extractor.py create mode 100644 src/modules/spade_generator.py create mode 100644 src/modules/stitching_retargeting_network.py create mode 100644 src/modules/util.py create mode 100644 src/modules/warping_network.py create mode 100644 src/template_maker.py create mode 100644 src/utils/__init__.py create mode 100644 src/utils/camera.py create mode 100644 src/utils/crop.py create mode 100644 src/utils/cropper.py create mode 100644 src/utils/dependencies/insightface/__init__.py create mode 100644 src/utils/dependencies/insightface/app/__init__.py create mode 100644 src/utils/dependencies/insightface/app/common.py create mode 100644 src/utils/dependencies/insightface/app/face_analysis.py create mode 100644 src/utils/dependencies/insightface/app/mask_renderer.py create mode 100644 src/utils/dependencies/insightface/commands/__init__.py create mode 100644 src/utils/dependencies/insightface/commands/insightface_cli.py create mode 100644 src/utils/dependencies/insightface/commands/model_download.py create mode 100644 src/utils/dependencies/insightface/commands/rec_add_mask_param.py create mode 100644 src/utils/dependencies/insightface/data/__init__.py create mode 100644 src/utils/dependencies/insightface/data/image.py create mode 100644 src/utils/dependencies/insightface/data/images/Tom_Hanks_54745.png create mode 100644 src/utils/dependencies/insightface/data/images/mask_black.jpg create mode 100644 src/utils/dependencies/insightface/data/images/mask_blue.jpg create mode 100644 src/utils/dependencies/insightface/data/images/mask_green.jpg create mode 100644 src/utils/dependencies/insightface/data/images/mask_white.jpg create mode 100644 src/utils/dependencies/insightface/data/images/t1.jpg create mode 100644 src/utils/dependencies/insightface/data/objects/meanshape_68.pkl create mode 100644 src/utils/dependencies/insightface/data/pickle_object.py create mode 100644 src/utils/dependencies/insightface/data/rec_builder.py create mode 100644 src/utils/dependencies/insightface/model_zoo/__init__.py create mode 100644 src/utils/dependencies/insightface/model_zoo/arcface_onnx.py create mode 100644 src/utils/dependencies/insightface/model_zoo/attribute.py create mode 100644 src/utils/dependencies/insightface/model_zoo/inswapper.py create mode 100644 src/utils/dependencies/insightface/model_zoo/landmark.py create mode 100644 src/utils/dependencies/insightface/model_zoo/model_store.py create mode 100644 src/utils/dependencies/insightface/model_zoo/model_zoo.py create mode 100644 src/utils/dependencies/insightface/model_zoo/retinaface.py create mode 100644 src/utils/dependencies/insightface/model_zoo/scrfd.py create mode 100644 src/utils/dependencies/insightface/thirdparty/__init__.py create mode 100644 src/utils/dependencies/insightface/thirdparty/face3d/__init__.py create mode 100644 src/utils/dependencies/insightface/thirdparty/face3d/mesh/__init__.py create mode 100644 src/utils/dependencies/insightface/thirdparty/face3d/mesh/cython/mesh_core.cpp create mode 100644 src/utils/dependencies/insightface/thirdparty/face3d/mesh/cython/mesh_core.h create mode 100644 src/utils/dependencies/insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.c create mode 100644 src/utils/dependencies/insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.cpp create mode 100644 src/utils/dependencies/insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.cpython-39-x86_64-linux-gnu.so create mode 100644 src/utils/dependencies/insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx create mode 100644 src/utils/dependencies/insightface/thirdparty/face3d/mesh/cython/setup.py create mode 100644 src/utils/dependencies/insightface/thirdparty/face3d/mesh/io.py create mode 100644 src/utils/dependencies/insightface/thirdparty/face3d/mesh/light.py create mode 100644 src/utils/dependencies/insightface/thirdparty/face3d/mesh/render.py create mode 100644 src/utils/dependencies/insightface/thirdparty/face3d/mesh/transform.py create mode 100644 src/utils/dependencies/insightface/thirdparty/face3d/mesh/vis.py create mode 100644 src/utils/dependencies/insightface/thirdparty/face3d/mesh_numpy/__init__.py create mode 100644 src/utils/dependencies/insightface/thirdparty/face3d/mesh_numpy/io.py create mode 100644 src/utils/dependencies/insightface/thirdparty/face3d/mesh_numpy/light.py create mode 100644 src/utils/dependencies/insightface/thirdparty/face3d/mesh_numpy/render.py create mode 100644 src/utils/dependencies/insightface/thirdparty/face3d/mesh_numpy/transform.py create mode 100644 src/utils/dependencies/insightface/thirdparty/face3d/mesh_numpy/vis.py create mode 100644 src/utils/dependencies/insightface/thirdparty/face3d/morphable_model/__init__.py create mode 100644 src/utils/dependencies/insightface/thirdparty/face3d/morphable_model/fit.py create mode 100644 src/utils/dependencies/insightface/thirdparty/face3d/morphable_model/load.py create mode 100644 src/utils/dependencies/insightface/thirdparty/face3d/morphable_model/morphabel_model.py create mode 100644 src/utils/dependencies/insightface/utils/__init__.py create mode 100644 src/utils/dependencies/insightface/utils/constant.py create mode 100644 src/utils/dependencies/insightface/utils/download.py create mode 100644 src/utils/dependencies/insightface/utils/face_align.py create mode 100644 src/utils/dependencies/insightface/utils/filesystem.py create mode 100644 src/utils/dependencies/insightface/utils/storage.py create mode 100644 src/utils/dependencies/insightface/utils/transform.py create mode 100644 src/utils/face_analysis_diy.py create mode 100644 src/utils/helper.py create mode 100644 src/utils/io.py create mode 100644 src/utils/landmark_runner.py create mode 100644 src/utils/resources/.gitattributes create mode 100644 src/utils/resources/mask_template.png create mode 100644 src/utils/retargeting_utils.py create mode 100644 src/utils/rprint.py create mode 100644 src/utils/timer.py create mode 100644 src/utils/video.py create mode 100644 video2template.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..07050fd --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +**/__pycache__/ +*.py[cod] +**/*.py[cod] +*$py.class + +# Model weights +**/*.pth +**/*.onnx + +# Ipython notebook +*.ipynb + +# Temporary files or benchmark resources +animations/* +tmp/* diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..1bca84c --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,19 @@ +{ + "[python]": { + "editor.tabSize": 4 + }, + "files.eol": "\n", + "files.insertFinalNewline": true, + "files.trimFinalNewlines": true, + "files.trimTrailingWhitespace": true, + "files.exclude": { + "**/.git": true, + "**/.svn": true, + "**/.hg": true, + "**/CVS": true, + "**/.DS_Store": true, + "**/Thumbs.db": true, + "**/*.crswap": true, + "**/__pycache__": true + } +} diff --git a/app.py b/app.py new file mode 100644 index 0000000..1998082 --- /dev/null +++ b/app.py @@ -0,0 +1,136 @@ +# coding: utf-8 + +""" +The entrance of the gradio +""" + +import os +import os.path as osp +import gradio as gr +import tyro +from src.utils.helper import load_description +from src.gradio_pipeline import GradioPipeline +from src.config.crop_config import CropConfig +from src.config.argument_config import ArgumentConfig +from src.config.inference_config import InferenceConfig + + +def partial_fields(target_class, kwargs): + return target_class(**{k: v for k, v in kwargs.items() if hasattr(target_class, k)}) + + +# set tyro theme +tyro.extras.set_accent_color("bright_cyan") +args = tyro.cli(ArgumentConfig) + +# specify configs for inference +inference_cfg = partial_fields(InferenceConfig, args.__dict__) # use attribute of args to initial InferenceConfig +crop_cfg = partial_fields(CropConfig, args.__dict__) # use attribute of args to initial CropConfig +gradio_pipeline = GradioPipeline( + inference_cfg=inference_cfg, + crop_cfg=crop_cfg, + args=args +) +# assets +title_md = "assets/gradio_title.md" +example_portrait_dir = "assets/examples/source" +example_video_dir = "assets/examples/driving" +data_examples = [ + [osp.join(example_portrait_dir, "s1.jpg"), osp.join(example_video_dir, "d1.mp4"), True, True, True], + [osp.join(example_portrait_dir, "s2.jpg"), osp.join(example_video_dir, "d2.mp4"), True, True, True], + [osp.join(example_portrait_dir, "s3.jpg"), osp.join(example_video_dir, "d5.mp4"), True, True, True], + [osp.join(example_portrait_dir, "s5.jpg"), osp.join(example_video_dir, "d6.mp4"), True, True, True], + [osp.join(example_portrait_dir, "s7.jpg"), osp.join(example_video_dir, "d7.mp4"), True, True, True], +] +#################### interface logic #################### +# Define components first +eye_retargeting_slider = gr.Slider(minimum=0, maximum=0.8, step=0.01, label="target eye-close ratio") +lip_retargeting_slider = gr.Slider(minimum=0, maximum=0.8, step=0.01, label="target lip-close ratio") +output_image = gr.Image(label="The animated image with the given eye-close and lip-close ratio.", type="numpy") +with gr.Blocks(theme=gr.themes.Soft()) as demo: + gr.HTML(load_description(title_md)) + gr.Markdown(load_description("assets/gradio_description_upload.md")) + with gr.Row(): + with gr.Accordion(open=True, label="Reference Portrait"): + image_input = gr.Image(label="Please upload the reference portrait here.", type="filepath") + with gr.Accordion(open=True, label="Driving Video"): + video_input = gr.Video(label="Please upload the driving video here.") + gr.Markdown(load_description("assets/gradio_description_animation.md")) + with gr.Row(): + with gr.Accordion(open=True, label="Animation Options"): + with gr.Row(): + flag_relative_input = gr.Checkbox(value=True, label="relative pose") + flag_remap_input = gr.Checkbox(value=True, label="paste-back") + flag_do_crop_input = gr.Checkbox(value=True, label="do crop") + with gr.Row(): + process_button_animation = gr.Button("๐Ÿš€ Animate", variant="primary") + with gr.Row(): + with gr.Column(): + with gr.Accordion(open=True, label="The animated video in the original image space"): + output_video = gr.Video(label="The animated video after pasted back.") + with gr.Column(): + with gr.Accordion(open=True, label="The animated video"): + output_video_concat = gr.Video(label="The animated video and driving video.") + with gr.Row(): + process_button_reset = gr.ClearButton([image_input, video_input, output_video, output_video_concat], value="๐Ÿงน Clear") + with gr.Row(): + # Examples + gr.Markdown("## You could choose the examples below โฌ‡๏ธ") + with gr.Row(): + gr.Examples( + examples=data_examples, + inputs=[ + image_input, + video_input, + flag_relative_input, + flag_do_crop_input, + flag_remap_input + ], + examples_per_page=5 + ) + gr.Markdown(load_description("assets/gradio_description_retargeting.md")) + with gr.Row(): + with gr.Column(): + process_button_close_ratio = gr.Button("๐Ÿค– Calculate the eye-close and lip-close ratio") + process_button_retargeting = gr.Button("๐Ÿš— Retargeting", variant="primary") + process_button_reset_retargeting = gr.ClearButton([output_image, eye_retargeting_slider, lip_retargeting_slider], value="๐Ÿงน Clear") + # with gr.Column(): + eye_retargeting_slider.render() + lip_retargeting_slider.render() + with gr.Column(): + with gr.Accordion(open=True, label="Eye and lip Retargeting Result"): + output_image.render() + # binding functions for buttons + process_button_close_ratio.click( + fn=gradio_pipeline.prepare_retargeting, + inputs=image_input, + outputs=[eye_retargeting_slider, lip_retargeting_slider], + show_progress=True + ) + process_button_retargeting.click( + fn=gradio_pipeline.execute_image, + inputs=[eye_retargeting_slider, lip_retargeting_slider], + outputs=output_image, + show_progress=True + ) + process_button_animation.click( + fn=gradio_pipeline.execute_video, + inputs=[ + image_input, + video_input, + flag_relative_input, + flag_do_crop_input, + flag_remap_input + ], + outputs=[output_video, output_video_concat], + show_progress=True + ) + process_button_reset.click() + process_button_reset_retargeting +########################################################## + +demo.launch( + server_name=args.server_name, + server_port=args.server_port, + share=args.share, +) diff --git a/assets/.gitattributes b/assets/.gitattributes new file mode 100644 index 0000000..3b11779 --- /dev/null +++ b/assets/.gitattributes @@ -0,0 +1,23 @@ +docs/inference.gif filter=lfs diff=lfs merge=lfs -text +docs/showcase2.gif filter=lfs diff=lfs merge=lfs -text +docs/showcase.gif filter=lfs diff=lfs merge=lfs -text +examples/driving/d5.mp4 filter=lfs diff=lfs merge=lfs -text +examples/driving/d7.mp4 filter=lfs diff=lfs merge=lfs -text +examples/driving/d9.mp4 filter=lfs diff=lfs merge=lfs -text +examples/driving/d6.mp4 filter=lfs diff=lfs merge=lfs -text +examples/driving/d8.mp4 filter=lfs diff=lfs merge=lfs -text +examples/driving/d0.mp4 filter=lfs diff=lfs merge=lfs -text +examples/driving/d1.mp4 filter=lfs diff=lfs merge=lfs -text +examples/driving/d2.mp4 filter=lfs diff=lfs merge=lfs -text +examples/driving/d3.mp4 filter=lfs diff=lfs merge=lfs -text +examples/source/s5.jpg filter=lfs diff=lfs merge=lfs -text +examples/source/s7.jpg filter=lfs diff=lfs merge=lfs -text +examples/source/s9.jpg filter=lfs diff=lfs merge=lfs -text +examples/source/s4.jpg filter=lfs diff=lfs merge=lfs -text +examples/source/s10.jpg filter=lfs diff=lfs merge=lfs -text +examples/source/s1.jpg filter=lfs diff=lfs merge=lfs -text +examples/source/s2.jpg filter=lfs diff=lfs merge=lfs -text +examples/source/s3.jpg filter=lfs diff=lfs merge=lfs -text +examples/source/s6.jpg filter=lfs diff=lfs merge=lfs -text +examples/source/s8.jpg filter=lfs diff=lfs merge=lfs -text +examples/source/s0.jpg filter=lfs diff=lfs merge=lfs -text diff --git a/assets/docs/inference.gif b/assets/docs/inference.gif new file mode 100644 index 0000000..d31040b --- /dev/null +++ b/assets/docs/inference.gif @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e1316eca5556ba5a8da7c53bcadbc1df26aa822bbde68fbad94813139803d0c6 +size 819961 diff --git a/assets/docs/showcase.gif b/assets/docs/showcase.gif new file mode 100644 index 0000000..fae84c2 --- /dev/null +++ b/assets/docs/showcase.gif @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7bca5f38bfd555bf7c013312d87883afdf39d97fba719ac171c60f897af49e21 +size 6623248 diff --git a/assets/docs/showcase2.gif b/assets/docs/showcase2.gif new file mode 100644 index 0000000..29175c0 --- /dev/null +++ b/assets/docs/showcase2.gif @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eb1fffb139681775780b2956e7d0289f55d199c1a3e14ab263887864d4b0d586 +size 2881351 diff --git a/assets/examples/driving/d0.mp4 b/assets/examples/driving/d0.mp4 new file mode 100644 index 0000000..92391dd --- /dev/null +++ b/assets/examples/driving/d0.mp4 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:63f6f9962e1fdf6e6722172e7a18155204858d5d5ce3b1e0646c150360c33bed +size 2958395 diff --git a/assets/examples/driving/d1.mp4 b/assets/examples/driving/d1.mp4 new file mode 100644 index 0000000..8f58096 --- /dev/null +++ b/assets/examples/driving/d1.mp4 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d8bdb2e3d18db28a7c81bc06070aefe2beebae2b489b976fa009eff5881bc7fe +size 48753 diff --git a/assets/examples/driving/d2.mp4 b/assets/examples/driving/d2.mp4 new file mode 100644 index 0000000..5372520 --- /dev/null +++ b/assets/examples/driving/d2.mp4 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5ce4a92e80e4d0b44c43af7afba471b3ebdf7dc83894ae98af6d4973f17af484 +size 47762 diff --git a/assets/examples/driving/d3.mp4 b/assets/examples/driving/d3.mp4 new file mode 100644 index 0000000..8b70b6a --- /dev/null +++ b/assets/examples/driving/d3.mp4 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef5c86e49b1b43dcb1449b499eb5a7f0cbae2f78aec08b5598193be1e4257099 +size 1430968 diff --git a/assets/examples/driving/d5.mp4 b/assets/examples/driving/d5.mp4 new file mode 100644 index 0000000..0d34edb --- /dev/null +++ b/assets/examples/driving/d5.mp4 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:021af59d9e1d89c967699efd374e7acc77fd14c30b052abd98665de401d9e511 +size 135015 diff --git a/assets/examples/driving/d6.mp4 b/assets/examples/driving/d6.mp4 new file mode 100644 index 0000000..44f3513 --- /dev/null +++ b/assets/examples/driving/d6.mp4 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:00e3ea79bbf28cbdc4fbb67ec655d9a0fe876e880ec45af55ae481348d0c0fff +size 1967790 diff --git a/assets/examples/driving/d7.mp4 b/assets/examples/driving/d7.mp4 new file mode 100644 index 0000000..d50ec4e --- /dev/null +++ b/assets/examples/driving/d7.mp4 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9e3ecc59a7285d52ca3666be6562e59ed45ad8afcef28d0f69a9be0e2850ed37 +size 185258 diff --git a/assets/examples/driving/d8.mp4 b/assets/examples/driving/d8.mp4 new file mode 100644 index 0000000..de9c9d1 --- /dev/null +++ b/assets/examples/driving/d8.mp4 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:912a02dcffef9b1a6d6641c9a48e170490080c3715dc9f55d91e168483d27e6e +size 312295 diff --git a/assets/examples/driving/d9.mp4 b/assets/examples/driving/d9.mp4 new file mode 100644 index 0000000..7803b3b --- /dev/null +++ b/assets/examples/driving/d9.mp4 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9a414aa1d547be35306d692065a2157434bf40a6025ba8e30ce12e5bb322cc33 +size 2257929 diff --git a/assets/examples/source/s0.jpg b/assets/examples/source/s0.jpg new file mode 100644 index 0000000..7cef081 --- /dev/null +++ b/assets/examples/source/s0.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ccd094951787cec391f3d444e056ee9a58d715f84152f49100c03bb3ce2962fc +size 116149 diff --git a/assets/examples/source/s1.jpg b/assets/examples/source/s1.jpg new file mode 100644 index 0000000..40f5043 --- /dev/null +++ b/assets/examples/source/s1.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:98931abeba483c27c699197e7c7bab58b7deb4324745b0f84e3c92e9ccef5901 +size 98411 diff --git a/assets/examples/source/s10.jpg b/assets/examples/source/s10.jpg new file mode 100644 index 0000000..1806f0d --- /dev/null +++ b/assets/examples/source/s10.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:49bdee735bed389d289c20d0bdff9bf0a485068e128cec8eb9e5bb11ae1f0422 +size 537372 diff --git a/assets/examples/source/s2.jpg b/assets/examples/source/s2.jpg new file mode 100644 index 0000000..d172b2c --- /dev/null +++ b/assets/examples/source/s2.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d950dc1c6560e0c7d0bcdca258079ba605d26f0979b7a602af75511a15e4c03 +size 760146 diff --git a/assets/examples/source/s3.jpg b/assets/examples/source/s3.jpg new file mode 100644 index 0000000..3b508a9 --- /dev/null +++ b/assets/examples/source/s3.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d93728ec60e1c0fceaf0f62b05d0b70283e9383a6eef0f31dc2078cb560f707a +size 63626 diff --git a/assets/examples/source/s4.jpg b/assets/examples/source/s4.jpg new file mode 100644 index 0000000..058e1f5 --- /dev/null +++ b/assets/examples/source/s4.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d62af6c554e211942f954237f7b898abb41d9d6166b5079564e76c25ff804c55 +size 143918 diff --git a/assets/examples/source/s5.jpg b/assets/examples/source/s5.jpg new file mode 100644 index 0000000..bd8dc95 --- /dev/null +++ b/assets/examples/source/s5.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9c368d9aa2eea0c5319b7d76e3b6c339819e49565ef064933a4511c11b581549 +size 133517 diff --git a/assets/examples/source/s6.jpg b/assets/examples/source/s6.jpg new file mode 100644 index 0000000..494b6bd --- /dev/null +++ b/assets/examples/source/s6.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fa226be24fc24c11c4bb276c2d7d789218eba88b8e49155855f5685d1b4d7809 +size 107520 diff --git a/assets/examples/source/s7.jpg b/assets/examples/source/s7.jpg new file mode 100644 index 0000000..d87d7b5 --- /dev/null +++ b/assets/examples/source/s7.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7a94b38bb66b58c3d44b98b86be3138cd3fb3ca40f89017294476b879353ebc4 +size 139855 diff --git a/assets/examples/source/s8.jpg b/assets/examples/source/s8.jpg new file mode 100644 index 0000000..398cd85 --- /dev/null +++ b/assets/examples/source/s8.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:01b6af295ebefcac1291cbe3b84fc6af37e40b168c528113662519aace4bbce5 +size 227378 diff --git a/assets/examples/source/s9.jpg b/assets/examples/source/s9.jpg new file mode 100644 index 0000000..83191d9 --- /dev/null +++ b/assets/examples/source/s9.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:84a6bfcb3346951cef85c0b0bb07856794e0b04d5b65322c18d77198fbf43f2a +size 442850 diff --git a/assets/gradio_description_animation.md b/assets/gradio_description_animation.md new file mode 100644 index 0000000..6cd6791 --- /dev/null +++ b/assets/gradio_description_animation.md @@ -0,0 +1,7 @@ +๐Ÿ”ฅ To animate the reference portrait with the driving video, please follow these steps: +
+ 1. Specify the options in the Animation Options section. We recommend checking the do crop option when facial areas occupy a relatively small portion of your image. +
+
+ 2. Press the ๐Ÿš€ Animate button and wait for a moment. Your animated video will appear in the result block. This may take a few moments. +
\ No newline at end of file diff --git a/assets/gradio_description_retargeting.md b/assets/gradio_description_retargeting.md new file mode 100644 index 0000000..0a5dcba --- /dev/null +++ b/assets/gradio_description_retargeting.md @@ -0,0 +1,7 @@ +๐Ÿ”ฅ To change the target eye-close and lip-close ratio of the reference portrait, please: +
+ 1. Please first press the ๐Ÿค– Calculate the eye-close and lip-close ratio button, and wait for the result shown in the sliders. +
+
+ 2. Please drag the sliders and then click the ๐Ÿš— Retargeting button. Then the result would be shown in the middle block. You can try running it multiple times! +
diff --git a/assets/gradio_description_upload.md b/assets/gradio_description_upload.md new file mode 100644 index 0000000..cba21ca --- /dev/null +++ b/assets/gradio_description_upload.md @@ -0,0 +1,4 @@ + ## ๐Ÿค— This is the official gradio demo for **Live Portrait**. +### Guidance for the gradio page: +
Please upload or use the webcam to get a reference portrait to the Reference Portrait field and a driving video to the Driving Video field.
+ diff --git a/assets/gradio_title.md b/assets/gradio_title.md new file mode 100644 index 0000000..bf4bf2b --- /dev/null +++ b/assets/gradio_title.md @@ -0,0 +1,10 @@ +
+
+

LivePortrait: Efficient Portrait Animation with Stitching and Retargeting Control

+
+ Project Page + +
+
+
diff --git a/inference.py b/inference.py new file mode 100644 index 0000000..8387e7f --- /dev/null +++ b/inference.py @@ -0,0 +1,33 @@ +# coding: utf-8 + +import tyro +from src.config.argument_config import ArgumentConfig +from src.config.inference_config import InferenceConfig +from src.config.crop_config import CropConfig +from src.live_portrait_pipeline import LivePortraitPipeline + + +def partial_fields(target_class, kwargs): + return target_class(**{k: v for k, v in kwargs.items() if hasattr(target_class, k)}) + + +def main(): + # set tyro theme + tyro.extras.set_accent_color("bright_cyan") + args = tyro.cli(ArgumentConfig) + + # specify configs for inference + inference_cfg = partial_fields(InferenceConfig, args.__dict__) # use attribute of args to initial InferenceConfig + crop_cfg = partial_fields(CropConfig, args.__dict__) # use attribute of args to initial CropConfig + + live_portrait_pipeline = LivePortraitPipeline( + inference_cfg=inference_cfg, + crop_cfg=crop_cfg + ) + + # run + live_portrait_pipeline.execute(args) + + +if __name__ == '__main__': + main() diff --git a/pretrained_weights/.gitkeep b/pretrained_weights/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..edb94db --- /dev/null +++ b/readme.md @@ -0,0 +1,145 @@ +

LivePortrait: Efficient Portrait Animation with Stitching and Retargeting Control

+ +
+ Jianzhu Guo1*  + Dingyun Zhang1,2  + Xiaoqiang Liu1  + Zhizhou Zhong1,3  + Yuan Zhang1  + Pengfei Wan1  + Di Zhang1  +
+ +
+ 1Kuaishou Technology  2University of Science and Technology of China  3Fudan University  +
+ +
+
+ + + +
+
+ +

+ showcase +

+ + + +## ๐Ÿ”ฅ Updates +- **`2024/07/04`**: ๐Ÿ”ฅ We released the initial version of the inference code and models. +- **`2024/07/04`**: ๐Ÿ˜Š We released the technique report on [arXiv](). + +## Introduction +This repo, named **LivePortrait**, contains the official PyTorch implementation of our paper [LivePortrait: Efficient Portrait Animation with Stitching and Retargeting Control](). +We are actively updating and improving this repository. If you find any bugs or have suggestions, welcome to raise issues or submit pull requests (PR) ๐Ÿ’–. + +## ๐Ÿ”ฅ Getting Started +### 1. Clone the code and prepare the environment +```bash +git clone https://github.com/KwaiVGI/LivePortrait +cd LivePortrait +# using lfs to pull the data +git lfs install +git lfs pull + +# create env using conda +conda create -n LivePortrait python==3.9.18 +conda activate LivePortrait +# install dependencies with pip +pip install -r requirements.txt +``` + +### 2. Download pretrained weights +Download our pretrained LivePortrait weights and face detection models of InsightFace from [Google Drive](https://drive.google.com/drive/folders/1UtKgzKjFAOmZkhNK-OYT0caJ_w2XAnib) or [Baidu Yun](https://pan.baidu.com/s/1MGctWmNla_vZxDbEp2Dtzw?pwd=z5cn). We have packed all weights in one directory ๐Ÿ˜Š. Unzip and place them in `./pretrained_weights` ensuring the directory structure is as follows: +```text +pretrained_weights +โ”œโ”€โ”€ insightface +โ”‚ โ””โ”€โ”€ models +โ”‚ โ””โ”€โ”€ buffalo_l +โ”‚ โ”œโ”€โ”€ 2d106det.onnx +โ”‚ โ””โ”€โ”€ det_10g.onnx +โ””โ”€โ”€ liveportrait + โ”œโ”€โ”€ base_models + โ”‚ โ”œโ”€โ”€ appearance_feature_extractor.pth + โ”‚ โ”œโ”€โ”€ motion_extractor.pth + โ”‚ โ”œโ”€โ”€ spade_generator.pth + โ”‚ โ””โ”€โ”€ warping_module.pth + โ”œโ”€โ”€ landmark.onnx + โ””โ”€โ”€ retargeting_models + โ””โ”€โ”€ stitching_retargeting_module.pth +``` + +### 3. Inference ๐Ÿš€ + +```bash +python inference.py +``` + +If the script runs successfully, you will see the following results: driving video, input image, and generated result. + +

+ image +

+ +Or, you can change the input by specifying the `-s` and `-d` arguments: + +```bash +python inference.py -s assets/examples/source/s9.jpg -d assets/examples/driving/d0.mp4 + +# or disable pasting back +python inference.py -s assets/examples/source/s9.jpg -d assets/examples/driving/d0.mp4 --no_flag_pasteback + +# more options to see +python inference.py -h +``` + +**More interesting results can be found in our [Homepage](https://liveportrait.github.io/)** ๐Ÿ˜Š + +### 4. Gradio interface (WIP) + +We also provide a Gradio interface for a better experience. Please install `gradio` and then run `app.py`: + +```bash +pip install gradio==4.36.1 +python app.py +``` + +***NOTE:*** *we are working on the Gradio interface and will be upgrading it soon.* + + +### 5. Inference speed evaluation ๐Ÿš€๐Ÿš€๐Ÿš€ +We have also provided a script to evaluate the inference speed of each module: + +```bash +python speed.py +``` + +Below are the results of inferring one frame on an RTX 4090 GPU using the native PyTorch framework with `torch.compile`: + +| Model | Parameters(M) | Model Size(MB) | Inference(ms) | +|-----------------------------------|:-------------:|:--------------:|:-------------:| +| Appearance Feature Extractor | 0.84 | 3.3 | 0.82 | +| Motion Extractor | 28.12 | 108 | 0.84 | +| Spade Generator | 55.37 | 212 | 7.59 | +| Warping Module | 45.53 | 174 | 5.21 | +| Stitching and Retargeting Modules| 0.23 | 2.3 | 0.31 | + +*Note: the listed values of Stitching and Retargeting Modules represent the combined parameter counts and the total sequential inference time of three MLP networks.* + + +## Acknowledgements +We would like to thank the contributors of [FOMM](https://github.com/AliaksandrSiarohin/first-order-model), [Open Facevid2vid](https://github.com/zhanglonghao1992/One-Shot_Free-View_Neural_Talking_Head_Synthesis), [SPADE](https://github.com/NVlabs/SPADE), [InsightFace](https://github.com/deepinsight/insightface) repositories, for their open research and contributions. + +## Citation ๐Ÿ’– +If you find LivePortrait useful for your research, welcome to ๐ŸŒŸ this repo and cite our work using the following BibTeX: +```bibtex +@article{guo2024live, + title = {LivePortrait: Efficient Portrait Animation with Stitching and Retargeting Control}, + author = {Jianzhu Guo and Dingyun Zhang and Xiaoqiang Liu and Zhizhou Zhong and Yuan Zhang and Pengfei Wan and Di Zhang}, + year = {2024}, + journal = {arXiv preprint:24xx.xxxx}, +} +``` diff --git a/speed.py b/speed.py new file mode 100644 index 0000000..02459d2 --- /dev/null +++ b/speed.py @@ -0,0 +1,192 @@ +# coding: utf-8 + +""" +Benchmark the inference speed of each module in LivePortrait. + +TODO: heavy GPT style, need to refactor +""" + +import yaml +import torch +import time +import numpy as np +from src.utils.helper import load_model, concat_feat +from src.config.inference_config import InferenceConfig + + +def initialize_inputs(batch_size=1): + """ + Generate random input tensors and move them to GPU + """ + feature_3d = torch.randn(batch_size, 32, 16, 64, 64).cuda().half() + kp_source = torch.randn(batch_size, 21, 3).cuda().half() + kp_driving = torch.randn(batch_size, 21, 3).cuda().half() + source_image = torch.randn(batch_size, 3, 256, 256).cuda().half() + generator_input = torch.randn(batch_size, 256, 64, 64).cuda().half() + eye_close_ratio = torch.randn(batch_size, 3).cuda().half() + lip_close_ratio = torch.randn(batch_size, 2).cuda().half() + feat_stitching = concat_feat(kp_source, kp_driving).half() + feat_eye = concat_feat(kp_source, eye_close_ratio).half() + feat_lip = concat_feat(kp_source, lip_close_ratio).half() + + inputs = { + 'feature_3d': feature_3d, + 'kp_source': kp_source, + 'kp_driving': kp_driving, + 'source_image': source_image, + 'generator_input': generator_input, + 'feat_stitching': feat_stitching, + 'feat_eye': feat_eye, + 'feat_lip': feat_lip + } + + return inputs + + +def load_and_compile_models(cfg, model_config): + """ + Load and compile models for inference + """ + appearance_feature_extractor = load_model(cfg.checkpoint_F, model_config, cfg.device_id, 'appearance_feature_extractor') + motion_extractor = load_model(cfg.checkpoint_M, model_config, cfg.device_id, 'motion_extractor') + warping_module = load_model(cfg.checkpoint_W, model_config, cfg.device_id, 'warping_module') + spade_generator = load_model(cfg.checkpoint_G, model_config, cfg.device_id, 'spade_generator') + stitching_retargeting_module = load_model(cfg.checkpoint_S, model_config, cfg.device_id, 'stitching_retargeting_module') + + models_with_params = [ + ('Appearance Feature Extractor', appearance_feature_extractor), + ('Motion Extractor', motion_extractor), + ('Warping Network', warping_module), + ('SPADE Decoder', spade_generator) + ] + + compiled_models = {} + for name, model in models_with_params: + model = model.half() + model = torch.compile(model, mode='max-autotune') # Optimize for inference + model.eval() # Switch to evaluation mode + compiled_models[name] = model + + retargeting_models = ['stitching', 'eye', 'lip'] + for retarget in retargeting_models: + module = stitching_retargeting_module[retarget].half() + module = torch.compile(module, mode='max-autotune') # Optimize for inference + module.eval() # Switch to evaluation mode + stitching_retargeting_module[retarget] = module + + return compiled_models, stitching_retargeting_module + + +def warm_up_models(compiled_models, stitching_retargeting_module, inputs): + """ + Warm up models to prepare them for benchmarking + """ + print("Warm up start!") + with torch.no_grad(): + for _ in range(10): + compiled_models['Appearance Feature Extractor'](inputs['source_image']) + compiled_models['Motion Extractor'](inputs['source_image']) + compiled_models['Warping Network'](inputs['feature_3d'], inputs['kp_driving'], inputs['kp_source']) + compiled_models['SPADE Decoder'](inputs['generator_input']) # Adjust input as required + stitching_retargeting_module['stitching'](inputs['feat_stitching']) + stitching_retargeting_module['eye'](inputs['feat_eye']) + stitching_retargeting_module['lip'](inputs['feat_lip']) + print("Warm up end!") + + +def measure_inference_times(compiled_models, stitching_retargeting_module, inputs): + """ + Measure inference times for each model + """ + times = {name: [] for name in compiled_models.keys()} + times['Retargeting Models'] = [] + + overall_times = [] + + with torch.no_grad(): + for _ in range(100): + torch.cuda.synchronize() + overall_start = time.time() + + start = time.time() + compiled_models['Appearance Feature Extractor'](inputs['source_image']) + torch.cuda.synchronize() + times['Appearance Feature Extractor'].append(time.time() - start) + + start = time.time() + compiled_models['Motion Extractor'](inputs['source_image']) + torch.cuda.synchronize() + times['Motion Extractor'].append(time.time() - start) + + start = time.time() + compiled_models['Warping Network'](inputs['feature_3d'], inputs['kp_driving'], inputs['kp_source']) + torch.cuda.synchronize() + times['Warping Network'].append(time.time() - start) + + start = time.time() + compiled_models['SPADE Decoder'](inputs['generator_input']) # Adjust input as required + torch.cuda.synchronize() + times['SPADE Decoder'].append(time.time() - start) + + start = time.time() + stitching_retargeting_module['stitching'](inputs['feat_stitching']) + stitching_retargeting_module['eye'](inputs['feat_eye']) + stitching_retargeting_module['lip'](inputs['feat_lip']) + torch.cuda.synchronize() + times['Retargeting Models'].append(time.time() - start) + + overall_times.append(time.time() - overall_start) + + return times, overall_times + + +def print_benchmark_results(compiled_models, stitching_retargeting_module, retargeting_models, times, overall_times): + """ + Print benchmark results with average and standard deviation of inference times + """ + average_times = {name: np.mean(times[name]) * 1000 for name in times.keys()} + std_times = {name: np.std(times[name]) * 1000 for name in times.keys()} + + for name, model in compiled_models.items(): + num_params = sum(p.numel() for p in model.parameters()) + num_params_in_millions = num_params / 1e6 + print(f"Number of parameters for {name}: {num_params_in_millions:.2f} M") + + for index, retarget in enumerate(retargeting_models): + num_params = sum(p.numel() for p in stitching_retargeting_module[retarget].parameters()) + num_params_in_millions = num_params / 1e6 + print(f"Number of parameters for part_{index} in Stitching and Retargeting Modules: {num_params_in_millions:.2f} M") + + for name, avg_time in average_times.items(): + std_time = std_times[name] + print(f"Average inference time for {name} over 100 runs: {avg_time:.2f} ms (std: {std_time:.2f} ms)") + + +def main(): + """ + Main function to benchmark speed and model parameters + """ + # Sample input tensors + inputs = initialize_inputs() + + # Load configuration + cfg = InferenceConfig(device_id=0) + model_config_path = cfg.models_config + with open(model_config_path, 'r') as file: + model_config = yaml.safe_load(file) + + # Load and compile models + compiled_models, stitching_retargeting_module = load_and_compile_models(cfg, model_config) + + # Warm up models + warm_up_models(compiled_models, stitching_retargeting_module, inputs) + + # Measure inference times + times, overall_times = measure_inference_times(compiled_models, stitching_retargeting_module, inputs) + + # Print benchmark results + print_benchmark_results(compiled_models, stitching_retargeting_module, ['stitching', 'eye', 'lip'], times, overall_times) + + +if __name__ == "__main__": + main() diff --git a/src/config/__init__.py b/src/config/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/config/argument_config.py b/src/config/argument_config.py new file mode 100644 index 0000000..340c177 --- /dev/null +++ b/src/config/argument_config.py @@ -0,0 +1,44 @@ +# coding: utf-8 + +""" +config for user +""" + +import os.path as osp +from dataclasses import dataclass +import tyro +from typing_extensions import Annotated +from .base_config import PrintableConfig, make_abs_path + + +@dataclass(repr=False) # use repr from PrintableConfig +class ArgumentConfig(PrintableConfig): + ########## input arguments ########## + source_image: Annotated[str, tyro.conf.arg(aliases=["-s"])] = make_abs_path('../../assets/examples/source/s6.jpg') # path to the reference portrait + driving_info: Annotated[str, tyro.conf.arg(aliases=["-d"])] = make_abs_path('../../assets/examples/driving/d0.mp4') # path to driving video or template (.pkl format) + output_dir: Annotated[str, tyro.conf.arg(aliases=["-o"])] = 'animations/' # directory to save output video + ##################################### + + ########## inference arguments ########## + device_id: int = 0 + flag_lip_zero : bool = True # whether let the lip to close state before animation, only take effect when flag_eye_retargeting and flag_lip_retargeting is False + flag_eye_retargeting: bool = False + flag_lip_retargeting: bool = False + flag_stitching: bool = True # we recommend setting it to True! + flag_relative: bool = True # whether to use relative pose + flag_pasteback: bool = True # whether to paste-back/stitch the animated face cropping from the face-cropping space to the original image space + flag_do_crop: bool = True # whether to crop the reference portrait to the face-cropping space + flag_do_rot: bool = True # whether to conduct the rotation when flag_do_crop is True + ######################################### + + ########## crop arguments ########## + dsize: int = 512 + scale: float = 2.3 + vx_ratio: float = 0 # vx ratio + vy_ratio: float = -0.125 # vy ratio +up, -down + #################################### + + ########## gradio arguments ########## + server_port: Annotated[int, tyro.conf.arg(aliases=["-p"])] = 8890 + share: bool = False + server_name: str = "0.0.0.0" diff --git a/src/config/base_config.py b/src/config/base_config.py new file mode 100644 index 0000000..216b8be --- /dev/null +++ b/src/config/base_config.py @@ -0,0 +1,29 @@ +# coding: utf-8 + +""" +pretty printing class +""" + +from __future__ import annotations +import os.path as osp +from typing import Tuple + + +def make_abs_path(fn): + return osp.join(osp.dirname(osp.realpath(__file__)), fn) + + +class PrintableConfig: # pylint: disable=too-few-public-methods + """Printable Config defining str function""" + + def __repr__(self): + lines = [self.__class__.__name__ + ":"] + for key, val in vars(self).items(): + if isinstance(val, Tuple): + flattened_val = "[" + for item in val: + flattened_val += str(item) + "\n" + flattened_val = flattened_val.rstrip("\n") + val = flattened_val + "]" + lines += f"{key}: {str(val)}".split("\n") + return "\n ".join(lines) diff --git a/src/config/crop_config.py b/src/config/crop_config.py new file mode 100644 index 0000000..d3c79be --- /dev/null +++ b/src/config/crop_config.py @@ -0,0 +1,18 @@ +# coding: utf-8 + +""" +parameters used for crop faces +""" + +import os.path as osp +from dataclasses import dataclass +from typing import Union, List +from .base_config import PrintableConfig + + +@dataclass(repr=False) # use repr from PrintableConfig +class CropConfig(PrintableConfig): + dsize: int = 512 # crop size + scale: float = 2.3 # scale factor + vx_ratio: float = 0 # vx ratio + vy_ratio: float = -0.125 # vy ratio +up, -down diff --git a/src/config/inference_config.py b/src/config/inference_config.py new file mode 100644 index 0000000..0da3e3c --- /dev/null +++ b/src/config/inference_config.py @@ -0,0 +1,49 @@ +# coding: utf-8 + +""" +config dataclass used for inference +""" + +import os.path as osp +from dataclasses import dataclass +from typing import Literal, Tuple +from .base_config import PrintableConfig, make_abs_path + + +@dataclass(repr=False) # use repr from PrintableConfig +class InferenceConfig(PrintableConfig): + models_config: str = make_abs_path('./models.yaml') # portrait animation config + checkpoint_F: str = make_abs_path('../../pretrained_weights/liveportrait/base_models/appearance_feature_extractor.pth') # path to checkpoint + checkpoint_M: str = make_abs_path('../../pretrained_weights/liveportrait/base_models/motion_extractor.pth') # path to checkpoint + checkpoint_G: str = make_abs_path('../../pretrained_weights/liveportrait/base_models/spade_generator.pth') # path to checkpoint + checkpoint_W: str = make_abs_path('../../pretrained_weights/liveportrait/base_models/warping_module.pth') # path to checkpoint + + checkpoint_S: str = make_abs_path('../../pretrained_weights/liveportrait/retargeting_models/stitching_retargeting_module.pth') # path to checkpoint + flag_use_half_precision: bool = True # whether to use half precision + + flag_lip_zero: bool = True # whether let the lip to close state before animation, only take effect when flag_eye_retargeting and flag_lip_retargeting is False + lip_zero_threshold: float = 0.03 + + flag_eye_retargeting: bool = False + flag_lip_retargeting: bool = False + flag_stitching: bool = True # we recommend setting it to True! + + flag_relative: bool = True # whether to use relative pose + anchor_frame: int = 0 # set this value if find_best_frame is True + + input_shape: Tuple[int, int] = (256, 256) # input shape + output_format: Literal['mp4', 'gif'] = 'mp4' # output video format + output_fps: int = 30 # fps for output video + crf: int = 15 # crf for output video + + flag_write_result: bool = True # whether to write output video + flag_pasteback: bool = True # whether to paste-back/stitch the animated face cropping from the face-cropping space to the original image space + mask_crop = None + flag_write_gif: bool = False + size_gif: int = 256 + ref_max_shape: int = 1280 + ref_shape_n: int = 2 + + device_id: int = 0 + flag_do_crop: bool = False # whether to crop the reference portrait to the face-cropping space + flag_do_rot: bool = True # whether to conduct the rotation when flag_do_crop is True diff --git a/src/config/models.yaml b/src/config/models.yaml new file mode 100644 index 0000000..131d1c6 --- /dev/null +++ b/src/config/models.yaml @@ -0,0 +1,43 @@ +model_params: + appearance_feature_extractor_params: # the F in the paper + image_channel: 3 + block_expansion: 64 + num_down_blocks: 2 + max_features: 512 + reshape_channel: 32 + reshape_depth: 16 + num_resblocks: 6 + motion_extractor_params: # the M in the paper + num_kp: 21 + backbone: convnextv2_tiny + warping_module_params: # the W in the paper + num_kp: 21 + block_expansion: 64 + max_features: 512 + num_down_blocks: 2 + reshape_channel: 32 + estimate_occlusion_map: True + dense_motion_params: + block_expansion: 32 + max_features: 1024 + num_blocks: 5 + reshape_depth: 16 + compress: 4 + spade_generator_params: # the G in the paper + upscale: 2 # represents upsample factor 256x256 -> 512x512 + block_expansion: 64 + max_features: 512 + num_down_blocks: 2 + stitching_retargeting_module_params: # the S in the paper + stitching: + input_size: 126 # (21*3)*2 + hidden_sizes: [128, 128, 64] + output_size: 65 # (21*3)+2(tx,ty) + lip: + input_size: 65 # (21*3)+2 + hidden_sizes: [128, 128, 64] + output_size: 63 # (21*3) + eye: + input_size: 66 # (21*3)+3 + hidden_sizes: [256, 256, 128, 128, 64] + output_size: 63 # (21*3) diff --git a/src/gradio_pipeline.py b/src/gradio_pipeline.py new file mode 100644 index 0000000..45d661b --- /dev/null +++ b/src/gradio_pipeline.py @@ -0,0 +1,104 @@ +# coding: utf-8 + +""" +Pipeline for gradio +""" + +from .config.argument_config import ArgumentConfig +from .live_portrait_pipeline import LivePortraitPipeline +from .utils.io import load_img_online +from .utils.camera import get_rotation_matrix +from .utils.retargeting_utils import calc_eye_close_ratio, calc_lip_close_ratio +from .utils.rprint import rlog as log + +def update_args(args, user_args): + """update the args according to user inputs + """ + for k, v in user_args.items(): + if hasattr(args, k): + setattr(args, k, v) + return args + +class GradioPipeline(LivePortraitPipeline): + + def __init__(self, inference_cfg, crop_cfg, args: ArgumentConfig): + super().__init__(inference_cfg, crop_cfg) + # self.live_portrait_wrapper = self.live_portrait_wrapper + self.args = args + # for single image retargeting + self.f_s_user = None + self.x_c_s_info_user = None + self.x_s_user = None + self.source_lmk_user = None + + def execute_video( + self, + input_image_path, + input_video_path, + flag_relative_input, + flag_do_crop_input, + flag_remap_input + ): + """ for video driven potrait animation + """ + args_user = { + 'source_image': input_image_path, + 'driving_info': input_video_path, + 'flag_relative': flag_relative_input, + 'flag_do_crop': flag_do_crop_input, + 'flag_pasteback': flag_remap_input + } + # update config from user input + self.args = update_args(self.args, args_user) + self.live_portrait_wrapper.update_config(self.args.__dict__) + self.cropper.update_config(self.args.__dict__) + # video driven animation + video_path, video_path_concat = self.execute(self.args) + return video_path, video_path_concat + + def execute_image(self, input_eye_ratio: float, input_lip_ratio: float): + """ for single image retargeting + """ + # โˆ†_eyes,i = R_eyes(x_s; c_s,eyes, c_d,eyes,i) + combined_eye_ratio_tensor = self.live_portrait_wrapper.calc_combined_eye_ratio([[input_eye_ratio]], self.source_lmk_user) + eyes_delta = self.live_portrait_wrapper.retarget_eye(self.x_s_user, combined_eye_ratio_tensor) + # โˆ†_lip,i = R_lip(x_s; c_s,lip, c_d,lip,i) + combined_lip_ratio_tensor = self.live_portrait_wrapper.calc_combined_lip_ratio([[input_lip_ratio]], self.source_lmk_user) + lip_delta = self.live_portrait_wrapper.retarget_lip(self.x_s_user, combined_lip_ratio_tensor) + num_kp = self.x_s_user.shape[1] + # default: use x_s + x_d_new = self.x_s_user + eyes_delta.reshape(-1, num_kp, 3) + lip_delta.reshape(-1, num_kp, 3) + # D(W(f_s; x_s, xโ€ฒ_d)) + out = self.live_portrait_wrapper.warp_decode(self.f_s_user, self.x_s_user, x_d_new) + out = self.live_portrait_wrapper.parse_output(out['out'])[0] + return out + + def prepare_retargeting(self, input_image_path, flag_do_crop = True): + """ for single image retargeting + """ + inference_cfg = self.live_portrait_wrapper.cfg + ######## process reference portrait ######## + img_rgb = load_img_online(input_image_path, mode='rgb', max_dim=1280, n=16) + log(f"Load source image from {input_image_path}.") + crop_info = self.cropper.crop_single_image(img_rgb) + if flag_do_crop: + I_s = self.live_portrait_wrapper.prepare_source(crop_info['img_crop_256x256']) + else: + I_s = self.live_portrait_wrapper.prepare_source(img_rgb) + x_s_info = self.live_portrait_wrapper.get_kp_info(I_s) + R_s = get_rotation_matrix(x_s_info['pitch'], x_s_info['yaw'], x_s_info['roll']) + ############################################ + + # record global info for next time use + self.f_s_user = self.live_portrait_wrapper.extract_feature_3d(I_s) + self.x_s_user = self.live_portrait_wrapper.transform_keypoint(x_s_info) + self.x_s_info_user = x_s_info + self.source_lmk_user = crop_info['lmk_crop'] + + # update slider + eye_close_ratio = calc_eye_close_ratio(self.source_lmk_user[None]) + eye_close_ratio = float(eye_close_ratio.squeeze(0).mean()) + lip_close_ratio = calc_lip_close_ratio(self.source_lmk_user[None]) + lip_close_ratio = float(lip_close_ratio.squeeze(0).mean()) + + return eye_close_ratio, lip_close_ratio diff --git a/src/live_portrait_pipeline.py b/src/live_portrait_pipeline.py new file mode 100644 index 0000000..668e3a3 --- /dev/null +++ b/src/live_portrait_pipeline.py @@ -0,0 +1,195 @@ +# coding: utf-8 + +""" +Pipeline of LivePortrait +""" + +# TODO: +# 1. ๅฝ“ๅ‰ๅ‡ๅฎšๆ‰€ๆœ‰็š„ๆจกๆฟ้ƒฝๆ˜ฏๅทฒ็ป่ฃๅฅฝ็š„๏ผŒ้œ€่ฆไฟฎๆ”นไธ‹ +# 2. pickๆ ทไพ‹ๅ›พ source + driving + +import cv2 +import numpy as np +import pickle +import os.path as osp +from rich.progress import track + +from .config.argument_config import ArgumentConfig +from .config.inference_config import InferenceConfig +from .config.crop_config import CropConfig +from .utils.cropper import Cropper +from .utils.camera import get_rotation_matrix +from .utils.video import images2video, concat_frames +from .utils.crop import _transform_img +from .utils.retargeting_utils import calc_lip_close_ratio +from .utils.io import load_image_rgb, load_driving_info +from .utils.helper import mkdir, basename, dct2cuda, is_video, is_template, resize_to_limit +from .utils.rprint import rlog as log +from .live_portrait_wrapper import LivePortraitWrapper + + +def make_abs_path(fn): + return osp.join(osp.dirname(osp.realpath(__file__)), fn) + + +class LivePortraitPipeline(object): + + def __init__(self, inference_cfg: InferenceConfig, crop_cfg: CropConfig): + self.live_portrait_wrapper: LivePortraitWrapper = LivePortraitWrapper(cfg=inference_cfg) + self.cropper = Cropper(crop_cfg=crop_cfg) + + def execute(self, args: ArgumentConfig): + inference_cfg = self.live_portrait_wrapper.cfg # for convenience + ######## process reference portrait ######## + img_rgb = load_image_rgb(args.source_image) + img_rgb = resize_to_limit(img_rgb, inference_cfg.ref_max_shape, inference_cfg.ref_shape_n) + log(f"Load source image from {args.source_image}") + crop_info = self.cropper.crop_single_image(img_rgb) + source_lmk = crop_info['lmk_crop'] + img_crop, img_crop_256x256 = crop_info['img_crop'], crop_info['img_crop_256x256'] + if inference_cfg.flag_do_crop: + I_s = self.live_portrait_wrapper.prepare_source(img_crop_256x256) + else: + I_s = self.live_portrait_wrapper.prepare_source(img_rgb) + x_s_info = self.live_portrait_wrapper.get_kp_info(I_s) + x_c_s = x_s_info['kp'] + R_s = get_rotation_matrix(x_s_info['pitch'], x_s_info['yaw'], x_s_info['roll']) + f_s = self.live_portrait_wrapper.extract_feature_3d(I_s) + x_s = self.live_portrait_wrapper.transform_keypoint(x_s_info) + + if inference_cfg.flag_lip_zero: + # let lip-open scalar to be 0 at first + c_d_lip_before_animation = [0.] + combined_lip_ratio_tensor_before_animation = self.live_portrait_wrapper.calc_combined_lip_ratio(c_d_lip_before_animation, source_lmk) + if combined_lip_ratio_tensor_before_animation[0][0] < inference_cfg.lip_zero_threshold: + inference_cfg.flag_lip_zero = False + else: + lip_delta_before_animation = self.live_portrait_wrapper.retarget_lip(x_s, combined_lip_ratio_tensor_before_animation) + ############################################ + + ######## process driving info ######## + if is_video(args.driving_info): + log(f"Load from video file (mp4 mov avi etc...): {args.driving_info}") + # TODO: ่ฟ™้‡Œtrackไธ€ไธ‹้ฉฑๅŠจ่ง†้ข‘ -> ๆž„ๅปบๆจกๆฟ + driving_rgb_lst = load_driving_info(args.driving_info) + driving_rgb_lst_256 = [cv2.resize(_, (256, 256)) for _ in driving_rgb_lst] + I_d_lst = self.live_portrait_wrapper.prepare_driving_videos(driving_rgb_lst_256) + n_frames = I_d_lst.shape[0] + if inference_cfg.flag_eye_retargeting or inference_cfg.flag_lip_retargeting: + driving_lmk_lst = self.cropper.get_retargeting_lmk_info(driving_rgb_lst) + input_eye_ratio_lst, input_lip_ratio_lst = self.live_portrait_wrapper.calc_retargeting_ratio(source_lmk, driving_lmk_lst) + elif is_template(args.driving_info): + log(f"Load from video templates {args.driving_info}") + with open(args.driving_info, 'rb') as f: + template_lst, driving_lmk_lst = pickle.load(f) + n_frames = template_lst[0]['n_frames'] + input_eye_ratio_lst, input_lip_ratio_lst = self.live_portrait_wrapper.calc_retargeting_ratio(source_lmk, driving_lmk_lst) + else: + raise Exception("Unsupported driving types!") + ######################################### + + ######## prepare for pasteback ######## + if inference_cfg.flag_pasteback: + if inference_cfg.mask_crop is None: + inference_cfg.mask_crop = cv2.imread(make_abs_path('./utils/resources/mask_template.png'), cv2.IMREAD_COLOR) + mask_ori = _transform_img(inference_cfg.mask_crop, crop_info['M_c2o'], dsize=(img_rgb.shape[1], img_rgb.shape[0])) + mask_ori = mask_ori.astype(np.float32) / 255. + I_p_paste_lst = [] + ######################################### + + I_p_lst = [] + R_d_0, x_d_0_info = None, None + for i in track(range(n_frames), description='Animating...', total=n_frames): + if is_video(args.driving_info): + # extract kp info by M + I_d_i = I_d_lst[i] + x_d_i_info = self.live_portrait_wrapper.get_kp_info(I_d_i) + R_d_i = get_rotation_matrix(x_d_i_info['pitch'], x_d_i_info['yaw'], x_d_i_info['roll']) + else: + # from template + x_d_i_info = template_lst[i] + x_d_i_info = dct2cuda(x_d_i_info, inference_cfg.device_id) + R_d_i = x_d_i_info['R_d'] + + if i == 0: + R_d_0 = R_d_i + x_d_0_info = x_d_i_info + + if inference_cfg.flag_relative: + R_new = (R_d_i @ R_d_0.permute(0, 2, 1)) @ R_s + delta_new = x_s_info['exp'] + (x_d_i_info['exp'] - x_d_0_info['exp']) + scale_new = x_s_info['scale'] * (x_d_i_info['scale'] / x_d_0_info['scale']) + t_new = x_s_info['t'] + (x_d_i_info['t'] - x_d_0_info['t']) + else: + R_new = R_d_i + delta_new = x_d_i_info['exp'] + scale_new = x_s_info['scale'] + t_new = x_d_i_info['t'] + + t_new[..., 2].fill_(0) # zero tz + x_d_i_new = scale_new * (x_c_s @ R_new + delta_new) + t_new + + # Algorithm 1: + if not inference_cfg.flag_stitching and not inference_cfg.flag_eye_retargeting and not inference_cfg.flag_lip_retargeting: + # without stitching or retargeting + if inference_cfg.flag_lip_zero: + x_d_i_new += lip_delta_before_animation.reshape(-1, x_s.shape[1], 3) + else: + pass + elif inference_cfg.flag_stitching and not inference_cfg.flag_eye_retargeting and not inference_cfg.flag_lip_retargeting: + # with stitching and without retargeting + if inference_cfg.flag_lip_zero: + x_d_i_new = self.live_portrait_wrapper.stitching(x_s, x_d_i_new) + lip_delta_before_animation.reshape(-1, x_s.shape[1], 3) + else: + x_d_i_new = self.live_portrait_wrapper.stitching(x_s, x_d_i_new) + else: + eyes_delta, lip_delta = None, None + if inference_cfg.flag_eye_retargeting: + c_d_eyes_i = input_eye_ratio_lst[i] + combined_eye_ratio_tensor = self.live_portrait_wrapper.calc_combined_eye_ratio(c_d_eyes_i, source_lmk) + # โˆ†_eyes,i = R_eyes(x_s; c_s,eyes, c_d,eyes,i) + eyes_delta = self.live_portrait_wrapper.retarget_eye(x_s, combined_eye_ratio_tensor) + if inference_cfg.flag_lip_retargeting: + c_d_lip_i = input_lip_ratio_lst[i] + combined_lip_ratio_tensor = self.live_portrait_wrapper.calc_combined_lip_ratio(c_d_lip_i, source_lmk) + # โˆ†_lip,i = R_lip(x_s; c_s,lip, c_d,lip,i) + lip_delta = self.live_portrait_wrapper.retarget_lip(x_s, combined_lip_ratio_tensor) + + if inference_cfg.flag_relative: # use x_s + x_d_i_new = x_s + \ + (eyes_delta.reshape(-1, x_s.shape[1], 3) if eyes_delta is not None else 0) + \ + (lip_delta.reshape(-1, x_s.shape[1], 3) if lip_delta is not None else 0) + else: # use x_d,i + x_d_i_new = x_d_i_new + \ + (eyes_delta.reshape(-1, x_s.shape[1], 3) if eyes_delta is not None else 0) + \ + (lip_delta.reshape(-1, x_s.shape[1], 3) if lip_delta is not None else 0) + + if inference_cfg.flag_stitching: + x_d_i_new = self.live_portrait_wrapper.stitching(x_s, x_d_i_new) + + out = self.live_portrait_wrapper.warp_decode(f_s, x_s, x_d_i_new) + I_p_i = self.live_portrait_wrapper.parse_output(out['out'])[0] + I_p_lst.append(I_p_i) + + if inference_cfg.flag_pasteback: + I_p_i_to_ori = _transform_img(I_p_i, crop_info['M_c2o'], dsize=(img_rgb.shape[1], img_rgb.shape[0])) + I_p_i_to_ori_blend = np.clip(mask_ori * I_p_i_to_ori + (1 - mask_ori) * img_rgb, 0, 255).astype(np.uint8) + out = np.hstack([I_p_i_to_ori, I_p_i_to_ori_blend]) + I_p_paste_lst.append(I_p_i_to_ori_blend) + + mkdir(args.output_dir) + wfp_concat = None + if is_video(args.driving_info): + frames_concatenated = concat_frames(I_p_lst, driving_rgb_lst, img_crop_256x256) + # save (driving frames, source image, drived frames) result + wfp_concat = osp.join(args.output_dir, f'{basename(args.source_image)}--{basename(args.driving_info)}_concat.mp4') + images2video(frames_concatenated, wfp=wfp_concat) + + # save drived result + wfp = osp.join(args.output_dir, f'{basename(args.source_image)}--{basename(args.driving_info)}.mp4') + if inference_cfg.flag_pasteback: + images2video(I_p_paste_lst, wfp=wfp) + else: + images2video(I_p_lst, wfp=wfp) + + return wfp, wfp_concat diff --git a/src/live_portrait_wrapper.py b/src/live_portrait_wrapper.py new file mode 100644 index 0000000..2cb2eab --- /dev/null +++ b/src/live_portrait_wrapper.py @@ -0,0 +1,335 @@ +# coding: utf-8 + +""" +Wrapper for LivePortrait core functions +""" + +import os.path as osp +import numpy as np +import cv2 +import torch +import yaml + +from src.utils.timer import Timer +from src.utils.helper import load_model, concat_feat +from src.utils.retargeting_utils import compute_eye_delta, compute_lip_delta +from src.utils.camera import headpose_pred_to_degree, get_rotation_matrix +from .utils.retargeting_utils import calc_eye_close_ratio, calc_lip_close_ratio +from src.config.inference_config import InferenceConfig +from src.utils.rprint import rlog as log + + +class LivePortraitWrapper(object): + + def __init__(self, cfg: InferenceConfig): + + model_config = yaml.load(open(cfg.models_config, 'r'), Loader=yaml.SafeLoader) + + # init F + self.appearance_feature_extractor = load_model(cfg.checkpoint_F, model_config, cfg.device_id, 'appearance_feature_extractor') + log(f'Load appearance_feature_extractor done.') + # init M + self.motion_extractor = load_model(cfg.checkpoint_M, model_config, cfg.device_id, 'motion_extractor') + log(f'Load motion_extractor done.') + # init W + self.warping_module = load_model(cfg.checkpoint_W, model_config, cfg.device_id, 'warping_module') + log(f'Load warping_module done.') + # init G + self.spade_generator = load_model(cfg.checkpoint_G, model_config, cfg.device_id, 'spade_generator') + log(f'Load spade_generator done.') + # init S and R + if cfg.checkpoint_S is not None and osp.exists(cfg.checkpoint_S): + self.stitching_retargeting_module = load_model(cfg.checkpoint_S, model_config, cfg.device_id, 'stitching_retargeting_module') + log(f'Load stitching_retargeting_module done.') + else: + self.stitching_retargeting_module = None + + self.cfg = cfg + self.device_id = cfg.device_id + self.timer = Timer() + + def update_config(self, user_args): + for k, v in user_args.items(): + if hasattr(self.cfg, k): + setattr(self.cfg, k, v) + + def prepare_source(self, img: np.ndarray) -> torch.Tensor: + """ construct the input as standard + img: HxWx3, uint8, 256x256 + """ + h, w = img.shape[:2] + if h != self.cfg.input_shape[0] or w != self.cfg.input_shape[1]: + x = cv2.resize(img, (self.cfg.input_shape[0], self.cfg.input_shape[1])) + else: + x = img.copy() + + if x.ndim == 3: + x = x[np.newaxis].astype(np.float32) / 255. # HxWx3 -> 1xHxWx3, normalized to 0~1 + elif x.ndim == 4: + x = x.astype(np.float32) / 255. # BxHxWx3, normalized to 0~1 + else: + raise ValueError(f'img ndim should be 3 or 4: {x.ndim}') + x = np.clip(x, 0, 1) # clip to 0~1 + x = torch.from_numpy(x).permute(0, 3, 1, 2) # 1xHxWx3 -> 1x3xHxW + x = x.cuda(self.device_id) + return x + + def prepare_driving_videos(self, imgs) -> torch.Tensor: + """ construct the input as standard + imgs: NxBxHxWx3, uint8 + """ + if isinstance(imgs, list): + _imgs = np.array(imgs)[..., np.newaxis] # TxHxWx3x1 + elif isinstance(imgs, np.ndarray): + _imgs = imgs + else: + raise ValueError(f'imgs type error: {type(imgs)}') + + y = _imgs.astype(np.float32) / 255. + y = np.clip(y, 0, 1) # clip to 0~1 + y = torch.from_numpy(y).permute(0, 4, 3, 1, 2) # TxHxWx3x1 -> Tx1x3xHxW + y = y.cuda(self.device_id) + + return y + + def extract_feature_3d(self, x: torch.Tensor) -> torch.Tensor: + """ get the appearance feature of the image by F + x: Bx3xHxW, normalized to 0~1 + """ + with torch.no_grad(): + with torch.autocast(device_type='cuda', dtype=torch.float16, enabled=self.cfg.flag_use_half_precision): + feature_3d = self.appearance_feature_extractor(x) + + return feature_3d.float() + + def get_kp_info(self, x: torch.Tensor, **kwargs) -> dict: + """ get the implicit keypoint information + x: Bx3xHxW, normalized to 0~1 + flag_refine_info: whether to trandform the pose to degrees and the dimention of the reshape + return: A dict contains keys: 'pitch', 'yaw', 'roll', 't', 'exp', 'scale', 'kp' + """ + with torch.no_grad(): + with torch.autocast(device_type='cuda', dtype=torch.float16, enabled=self.cfg.flag_use_half_precision): + kp_info = self.motion_extractor(x) + + if self.cfg.flag_use_half_precision: + # float the dict + for k, v in kp_info.items(): + if isinstance(v, torch.Tensor): + kp_info[k] = v.float() + + flag_refine_info: bool = kwargs.get('flag_refine_info', True) + if flag_refine_info: + bs = kp_info['kp'].shape[0] + kp_info['pitch'] = headpose_pred_to_degree(kp_info['pitch'])[:, None] # Bx1 + kp_info['yaw'] = headpose_pred_to_degree(kp_info['yaw'])[:, None] # Bx1 + kp_info['roll'] = headpose_pred_to_degree(kp_info['roll'])[:, None] # Bx1 + kp_info['kp'] = kp_info['kp'].reshape(bs, -1, 3) # BxNx3 + kp_info['exp'] = kp_info['exp'].reshape(bs, -1, 3) # BxNx3 + + return kp_info + + def get_pose_dct(self, kp_info: dict) -> dict: + pose_dct = dict( + pitch=headpose_pred_to_degree(kp_info['pitch']).item(), + yaw=headpose_pred_to_degree(kp_info['yaw']).item(), + roll=headpose_pred_to_degree(kp_info['roll']).item(), + ) + return pose_dct + + def get_fs_and_kp_info(self, source_prepared, driving_first_frame): + + # get the canonical keypoints of source image by M + source_kp_info = self.get_kp_info(source_prepared, flag_refine_info=True) + source_rotation = get_rotation_matrix(source_kp_info['pitch'], source_kp_info['yaw'], source_kp_info['roll']) + + # get the canonical keypoints of first driving frame by M + driving_first_frame_kp_info = self.get_kp_info(driving_first_frame, flag_refine_info=True) + driving_first_frame_rotation = get_rotation_matrix( + driving_first_frame_kp_info['pitch'], + driving_first_frame_kp_info['yaw'], + driving_first_frame_kp_info['roll'] + ) + + # get feature volume by F + source_feature_3d = self.extract_feature_3d(source_prepared) + + return source_kp_info, source_rotation, source_feature_3d, driving_first_frame_kp_info, driving_first_frame_rotation + + def transform_keypoint(self, kp_info: dict): + """ + transform the implicit keypoints with the pose, shift, and expression deformation + kp: BxNx3 + """ + kp = kp_info['kp'] # (bs, k, 3) + pitch, yaw, roll = kp_info['pitch'], kp_info['yaw'], kp_info['roll'] + + t, exp = kp_info['t'], kp_info['exp'] + scale = kp_info['scale'] + + pitch = headpose_pred_to_degree(pitch) + yaw = headpose_pred_to_degree(yaw) + roll = headpose_pred_to_degree(roll) + + bs = kp.shape[0] + if kp.ndim == 2: + num_kp = kp.shape[1] // 3 # Bx(num_kpx3) + else: + num_kp = kp.shape[1] # Bxnum_kpx3 + + rot_mat = get_rotation_matrix(pitch, yaw, roll) # (bs, 3, 3) + + # Eqn.2: s * (R * x_c,s + exp) + t + kp_transformed = kp.view(bs, num_kp, 3) @ rot_mat + exp.view(bs, num_kp, 3) + kp_transformed *= scale[..., None] # (bs, k, 3) * (bs, 1, 1) = (bs, k, 3) + kp_transformed[:, :, 0:2] += t[:, None, 0:2] # remove z, only apply tx ty + + return kp_transformed + + def retarget_eye(self, kp_source: torch.Tensor, eye_close_ratio: torch.Tensor) -> torch.Tensor: + """ + kp_source: BxNx3 + eye_close_ratio: Bx3 + Return: Bx(3*num_kp+2) + """ + feat_eye = concat_feat(kp_source, eye_close_ratio) + + with torch.no_grad(): + delta = self.stitching_retargeting_module['eye'](feat_eye) + + return delta + + def retarget_lip(self, kp_source: torch.Tensor, lip_close_ratio: torch.Tensor) -> torch.Tensor: + """ + kp_source: BxNx3 + lip_close_ratio: Bx2 + """ + feat_lip = concat_feat(kp_source, lip_close_ratio) + + with torch.no_grad(): + delta = self.stitching_retargeting_module['lip'](feat_lip) + + return delta + + def retarget_keypoints(self, frame_idx, num_keypoints, input_eye_ratios, input_lip_ratios, source_landmarks, portrait_wrapper, kp_source, driving_transformed_kp): + # TODO: GPT style, refactor it... + if self.cfg.flag_eye_retargeting: + # โˆ†_eyes,i = R_eyes(x_s; c_s,eyes, c_d,eyes,i) + eye_delta = compute_eye_delta(frame_idx, input_eye_ratios, source_landmarks, portrait_wrapper, kp_source) + else: + # ฮฑ_eyes = 0 + eye_delta = None + + if self.cfg.flag_lip_retargeting: + # โˆ†_lip,i = R_lip(x_s; c_s,lip, c_d,lip,i) + lip_delta = compute_lip_delta(frame_idx, input_lip_ratios, source_landmarks, portrait_wrapper, kp_source) + else: + # ฮฑ_lip = 0 + lip_delta = None + + if self.cfg.flag_relative: # use x_s + new_driving_kp = kp_source + \ + (eye_delta.reshape(-1, num_keypoints, 3) if eye_delta is not None else 0) + \ + (lip_delta.reshape(-1, num_keypoints, 3) if lip_delta is not None else 0) + else: # use x_d,i + new_driving_kp = driving_transformed_kp + \ + (eye_delta.reshape(-1, num_keypoints, 3) if eye_delta is not None else 0) + \ + (lip_delta.reshape(-1, num_keypoints, 3) if lip_delta is not None else 0) + + return new_driving_kp + + def stitch(self, kp_source: torch.Tensor, kp_driving: torch.Tensor) -> torch.Tensor: + """ + kp_source: BxNx3 + kp_driving: BxNx3 + Return: Bx(3*num_kp+2) + """ + feat_stiching = concat_feat(kp_source, kp_driving) + + with torch.no_grad(): + delta = self.stitching_retargeting_module['stitching'](feat_stiching) + + return delta + + def stitching(self, kp_source: torch.Tensor, kp_driving: torch.Tensor) -> torch.Tensor: + """ conduct the stitching + kp_source: Bxnum_kpx3 + kp_driving: Bxnum_kpx3 + """ + + if self.stitching_retargeting_module is not None: + + bs, num_kp = kp_source.shape[:2] + + kp_driving_new = kp_driving.clone() + delta = self.stitch(kp_source, kp_driving_new) + + delta_exp = delta[..., :3*num_kp].reshape(bs, num_kp, 3) # 1x20x3 + delta_tx_ty = delta[..., 3*num_kp:3*num_kp+2].reshape(bs, 1, 2) # 1x1x2 + + kp_driving_new += delta_exp + kp_driving_new[..., :2] += delta_tx_ty + + return kp_driving_new + + return kp_driving + + def warp_decode(self, feature_3d: torch.Tensor, kp_source: torch.Tensor, kp_driving: torch.Tensor) -> torch.Tensor: + """ get the image after the warping of the implicit keypoints + feature_3d: Bx32x16x64x64, feature volume + kp_source: BxNx3 + kp_driving: BxNx3 + """ + # The line 18 in Algorithm 1: D(W(f_s; x_s, xโ€ฒ_d,i)๏ผ‰ + with torch.no_grad(): + with torch.autocast(device_type='cuda', dtype=torch.float16, enabled=self.cfg.flag_use_half_precision): + # get decoder input + ret_dct = self.warping_module(feature_3d, kp_source=kp_source, kp_driving=kp_driving) + # decode + ret_dct['out'] = self.spade_generator(feature=ret_dct['out']) + + # float the dict + if self.cfg.flag_use_half_precision: + for k, v in ret_dct.items(): + if isinstance(v, torch.Tensor): + ret_dct[k] = v.float() + + return ret_dct + + def parse_output(self, out: torch.Tensor) -> np.ndarray: + """ construct the output as standard + return: 1xHxWx3, uint8 + """ + out = np.transpose(out.data.cpu().numpy(), [0, 2, 3, 1]) # 1x3xHxW -> 1xHxWx3 + out = np.clip(out, 0, 1) # clip to 0~1 + out = np.clip(out * 255, 0, 255).astype(np.uint8) # 0~1 -> 0~255 + + return out + + def calc_retargeting_ratio(self, source_lmk, driving_lmk_lst): + input_eye_ratio_lst = [] + input_lip_ratio_lst = [] + for lmk in driving_lmk_lst: + # for eyes retargeting + input_eye_ratio_lst.append(calc_eye_close_ratio(lmk[None])) + # for lip retargeting + input_lip_ratio_lst.append(calc_lip_close_ratio(lmk[None])) + return input_eye_ratio_lst, input_lip_ratio_lst + + def calc_combined_eye_ratio(self, input_eye_ratio, source_lmk): + eye_close_ratio = calc_eye_close_ratio(source_lmk[None]) + eye_close_ratio_tensor = torch.from_numpy(eye_close_ratio).float().cuda(self.device_id) + input_eye_ratio_tensor = torch.Tensor([input_eye_ratio[0][0]]).reshape(1, 1).cuda(self.device_id) + # [c_s,eyes, c_d,eyes,i] + combined_eye_ratio_tensor = torch.cat([eye_close_ratio_tensor, input_eye_ratio_tensor], dim=1) + return combined_eye_ratio_tensor + + def calc_combined_lip_ratio(self, input_lip_ratio, source_lmk): + lip_close_ratio = calc_lip_close_ratio(source_lmk[None]) + lip_close_ratio_tensor = torch.from_numpy(lip_close_ratio).float().cuda(self.device_id) + # [c_s,lip, c_d,lip,i] + input_lip_ratio_tensor = torch.Tensor([input_lip_ratio[0]]).cuda(self.device_id) + if input_lip_ratio_tensor.shape != [1, 1]: + input_lip_ratio_tensor = input_lip_ratio_tensor.reshape(1, 1) + combined_lip_ratio_tensor = torch.cat([lip_close_ratio_tensor, input_lip_ratio_tensor], dim=1) + return combined_lip_ratio_tensor diff --git a/src/modules/__init__.py b/src/modules/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/modules/appearance_feature_extractor.py b/src/modules/appearance_feature_extractor.py new file mode 100644 index 0000000..8d89e4f --- /dev/null +++ b/src/modules/appearance_feature_extractor.py @@ -0,0 +1,48 @@ +# coding: utf-8 + +""" +Appearance extractor(F) defined in paper, which maps the source image s to a 3D appearance feature volume. +""" + +import torch +from torch import nn +from .util import SameBlock2d, DownBlock2d, ResBlock3d + + +class AppearanceFeatureExtractor(nn.Module): + + def __init__(self, image_channel, block_expansion, num_down_blocks, max_features, reshape_channel, reshape_depth, num_resblocks): + super(AppearanceFeatureExtractor, self).__init__() + self.image_channel = image_channel + self.block_expansion = block_expansion + self.num_down_blocks = num_down_blocks + self.max_features = max_features + self.reshape_channel = reshape_channel + self.reshape_depth = reshape_depth + + self.first = SameBlock2d(image_channel, block_expansion, kernel_size=(3, 3), padding=(1, 1)) + + down_blocks = [] + for i in range(num_down_blocks): + in_features = min(max_features, block_expansion * (2 ** i)) + out_features = min(max_features, block_expansion * (2 ** (i + 1))) + down_blocks.append(DownBlock2d(in_features, out_features, kernel_size=(3, 3), padding=(1, 1))) + self.down_blocks = nn.ModuleList(down_blocks) + + self.second = nn.Conv2d(in_channels=out_features, out_channels=max_features, kernel_size=1, stride=1) + + self.resblocks_3d = torch.nn.Sequential() + for i in range(num_resblocks): + self.resblocks_3d.add_module('3dr' + str(i), ResBlock3d(reshape_channel, kernel_size=3, padding=1)) + + def forward(self, source_image): + out = self.first(source_image) # Bx3x256x256 -> Bx64x256x256 + + for i in range(len(self.down_blocks)): + out = self.down_blocks[i](out) + out = self.second(out) + bs, c, h, w = out.shape # ->Bx512x64x64 + + f_s = out.view(bs, self.reshape_channel, self.reshape_depth, h, w) # ->Bx32x16x64x64 + f_s = self.resblocks_3d(f_s) # ->Bx32x16x64x64 + return f_s diff --git a/src/modules/convnextv2.py b/src/modules/convnextv2.py new file mode 100644 index 0000000..83ea126 --- /dev/null +++ b/src/modules/convnextv2.py @@ -0,0 +1,149 @@ +# coding: utf-8 + +""" +This moudle is adapted to the ConvNeXtV2 version for the extraction of implicit keypoints, poses, and expression deformation. +""" + +import torch +import torch.nn as nn +# from timm.models.layers import trunc_normal_, DropPath +from .util import LayerNorm, DropPath, trunc_normal_, GRN + +__all__ = ['convnextv2_tiny'] + + +class Block(nn.Module): + """ ConvNeXtV2 Block. + + Args: + dim (int): Number of input channels. + drop_path (float): Stochastic depth rate. Default: 0.0 + """ + + def __init__(self, dim, drop_path=0.): + super().__init__() + self.dwconv = nn.Conv2d(dim, dim, kernel_size=7, padding=3, groups=dim) # depthwise conv + self.norm = LayerNorm(dim, eps=1e-6) + self.pwconv1 = nn.Linear(dim, 4 * dim) # pointwise/1x1 convs, implemented with linear layers + self.act = nn.GELU() + self.grn = GRN(4 * dim) + self.pwconv2 = nn.Linear(4 * dim, dim) + self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity() + + def forward(self, x): + input = x + x = self.dwconv(x) + x = x.permute(0, 2, 3, 1) # (N, C, H, W) -> (N, H, W, C) + x = self.norm(x) + x = self.pwconv1(x) + x = self.act(x) + x = self.grn(x) + x = self.pwconv2(x) + x = x.permute(0, 3, 1, 2) # (N, H, W, C) -> (N, C, H, W) + + x = input + self.drop_path(x) + return x + + +class ConvNeXtV2(nn.Module): + """ ConvNeXt V2 + + Args: + in_chans (int): Number of input image channels. Default: 3 + num_classes (int): Number of classes for classification head. Default: 1000 + depths (tuple(int)): Number of blocks at each stage. Default: [3, 3, 9, 3] + dims (int): Feature dimension at each stage. Default: [96, 192, 384, 768] + drop_path_rate (float): Stochastic depth rate. Default: 0. + head_init_scale (float): Init scaling value for classifier weights and biases. Default: 1. + """ + + def __init__( + self, + in_chans=3, + depths=[3, 3, 9, 3], + dims=[96, 192, 384, 768], + drop_path_rate=0., + **kwargs + ): + super().__init__() + self.depths = depths + self.downsample_layers = nn.ModuleList() # stem and 3 intermediate downsampling conv layers + stem = nn.Sequential( + nn.Conv2d(in_chans, dims[0], kernel_size=4, stride=4), + LayerNorm(dims[0], eps=1e-6, data_format="channels_first") + ) + self.downsample_layers.append(stem) + for i in range(3): + downsample_layer = nn.Sequential( + LayerNorm(dims[i], eps=1e-6, data_format="channels_first"), + nn.Conv2d(dims[i], dims[i+1], kernel_size=2, stride=2), + ) + self.downsample_layers.append(downsample_layer) + + self.stages = nn.ModuleList() # 4 feature resolution stages, each consisting of multiple residual blocks + dp_rates = [x.item() for x in torch.linspace(0, drop_path_rate, sum(depths))] + cur = 0 + for i in range(4): + stage = nn.Sequential( + *[Block(dim=dims[i], drop_path=dp_rates[cur + j]) for j in range(depths[i])] + ) + self.stages.append(stage) + cur += depths[i] + + self.norm = nn.LayerNorm(dims[-1], eps=1e-6) # final norm layer + + # NOTE: the output semantic items + num_bins = kwargs.get('num_bins', 66) + num_kp = kwargs.get('num_kp', 24) # the number of implicit keypoints + self.fc_kp = nn.Linear(dims[-1], 3 * num_kp) # implicit keypoints + + # print('dims[-1]: ', dims[-1]) + self.fc_scale = nn.Linear(dims[-1], 1) # scale + self.fc_pitch = nn.Linear(dims[-1], num_bins) # pitch bins + self.fc_yaw = nn.Linear(dims[-1], num_bins) # yaw bins + self.fc_roll = nn.Linear(dims[-1], num_bins) # roll bins + self.fc_t = nn.Linear(dims[-1], 3) # translation + self.fc_exp = nn.Linear(dims[-1], 3 * num_kp) # expression / delta + + def _init_weights(self, m): + if isinstance(m, (nn.Conv2d, nn.Linear)): + trunc_normal_(m.weight, std=.02) + nn.init.constant_(m.bias, 0) + + def forward_features(self, x): + for i in range(4): + x = self.downsample_layers[i](x) + x = self.stages[i](x) + return self.norm(x.mean([-2, -1])) # global average pooling, (N, C, H, W) -> (N, C) + + def forward(self, x): + x = self.forward_features(x) + + # implicit keypoints + kp = self.fc_kp(x) + + # pose and expression deformation + pitch = self.fc_pitch(x) + yaw = self.fc_yaw(x) + roll = self.fc_roll(x) + t = self.fc_t(x) + exp = self.fc_exp(x) + scale = self.fc_scale(x) + + ret_dct = { + 'pitch': pitch, + 'yaw': yaw, + 'roll': roll, + 't': t, + 'exp': exp, + 'scale': scale, + + 'kp': kp, # canonical keypoint + } + + return ret_dct + + +def convnextv2_tiny(**kwargs): + model = ConvNeXtV2(depths=[3, 3, 9, 3], dims=[96, 192, 384, 768], **kwargs) + return model diff --git a/src/modules/dense_motion.py b/src/modules/dense_motion.py new file mode 100644 index 0000000..0eec0c4 --- /dev/null +++ b/src/modules/dense_motion.py @@ -0,0 +1,104 @@ +# coding: utf-8 + +""" +The module that predicting a dense motion from sparse motion representation given by kp_source and kp_driving +""" + +from torch import nn +import torch.nn.functional as F +import torch +from .util import Hourglass, make_coordinate_grid, kp2gaussian + + +class DenseMotionNetwork(nn.Module): + def __init__(self, block_expansion, num_blocks, max_features, num_kp, feature_channel, reshape_depth, compress, estimate_occlusion_map=True): + super(DenseMotionNetwork, self).__init__() + self.hourglass = Hourglass(block_expansion=block_expansion, in_features=(num_kp+1)*(compress+1), max_features=max_features, num_blocks=num_blocks) # ~60+G + + self.mask = nn.Conv3d(self.hourglass.out_filters, num_kp + 1, kernel_size=7, padding=3) # 65G! NOTE: computation cost is large + self.compress = nn.Conv3d(feature_channel, compress, kernel_size=1) # 0.8G + self.norm = nn.BatchNorm3d(compress, affine=True) + self.num_kp = num_kp + self.flag_estimate_occlusion_map = estimate_occlusion_map + + if self.flag_estimate_occlusion_map: + self.occlusion = nn.Conv2d(self.hourglass.out_filters*reshape_depth, 1, kernel_size=7, padding=3) + else: + self.occlusion = None + + def create_sparse_motions(self, feature, kp_driving, kp_source): + bs, _, d, h, w = feature.shape # (bs, 4, 16, 64, 64) + identity_grid = make_coordinate_grid((d, h, w), ref=kp_source) # (16, 64, 64, 3) + identity_grid = identity_grid.view(1, 1, d, h, w, 3) # (1, 1, d=16, h=64, w=64, 3) + coordinate_grid = identity_grid - kp_driving.view(bs, self.num_kp, 1, 1, 1, 3) + + k = coordinate_grid.shape[1] + + # NOTE: there lacks an one-order flow + driving_to_source = coordinate_grid + kp_source.view(bs, self.num_kp, 1, 1, 1, 3) # (bs, num_kp, d, h, w, 3) + + # adding background feature + identity_grid = identity_grid.repeat(bs, 1, 1, 1, 1, 1) + sparse_motions = torch.cat([identity_grid, driving_to_source], dim=1) # (bs, 1+num_kp, d, h, w, 3) + return sparse_motions + + def create_deformed_feature(self, feature, sparse_motions): + bs, _, d, h, w = feature.shape + feature_repeat = feature.unsqueeze(1).unsqueeze(1).repeat(1, self.num_kp+1, 1, 1, 1, 1, 1) # (bs, num_kp+1, 1, c, d, h, w) + feature_repeat = feature_repeat.view(bs * (self.num_kp+1), -1, d, h, w) # (bs*(num_kp+1), c, d, h, w) + sparse_motions = sparse_motions.view((bs * (self.num_kp+1), d, h, w, -1)) # (bs*(num_kp+1), d, h, w, 3) + sparse_deformed = F.grid_sample(feature_repeat, sparse_motions, align_corners=False) + sparse_deformed = sparse_deformed.view((bs, self.num_kp+1, -1, d, h, w)) # (bs, num_kp+1, c, d, h, w) + + return sparse_deformed + + def create_heatmap_representations(self, feature, kp_driving, kp_source): + spatial_size = feature.shape[3:] # (d=16, h=64, w=64) + gaussian_driving = kp2gaussian(kp_driving, spatial_size=spatial_size, kp_variance=0.01) # (bs, num_kp, d, h, w) + gaussian_source = kp2gaussian(kp_source, spatial_size=spatial_size, kp_variance=0.01) # (bs, num_kp, d, h, w) + heatmap = gaussian_driving - gaussian_source # (bs, num_kp, d, h, w) + + # adding background feature + zeros = torch.zeros(heatmap.shape[0], 1, spatial_size[0], spatial_size[1], spatial_size[2]).type(heatmap.type()).to(heatmap.device) + heatmap = torch.cat([zeros, heatmap], dim=1) + heatmap = heatmap.unsqueeze(2) # (bs, 1+num_kp, 1, d, h, w) + return heatmap + + def forward(self, feature, kp_driving, kp_source): + bs, _, d, h, w = feature.shape # (bs, 32, 16, 64, 64) + + feature = self.compress(feature) # (bs, 4, 16, 64, 64) + feature = self.norm(feature) # (bs, 4, 16, 64, 64) + feature = F.relu(feature) # (bs, 4, 16, 64, 64) + + out_dict = dict() + + # 1. deform 3d feature + sparse_motion = self.create_sparse_motions(feature, kp_driving, kp_source) # (bs, 1+num_kp, d, h, w, 3) + deformed_feature = self.create_deformed_feature(feature, sparse_motion) # (bs, 1+num_kp, c=4, d=16, h=64, w=64) + + # 2. (bs, 1+num_kp, d, h, w) + heatmap = self.create_heatmap_representations(deformed_feature, kp_driving, kp_source) # (bs, 1+num_kp, 1, d, h, w) + + input = torch.cat([heatmap, deformed_feature], dim=2) # (bs, 1+num_kp, c=5, d=16, h=64, w=64) + input = input.view(bs, -1, d, h, w) # (bs, (1+num_kp)*c=105, d=16, h=64, w=64) + + prediction = self.hourglass(input) + + mask = self.mask(prediction) + mask = F.softmax(mask, dim=1) # (bs, 1+num_kp, d=16, h=64, w=64) + out_dict['mask'] = mask + mask = mask.unsqueeze(2) # (bs, num_kp+1, 1, d, h, w) + sparse_motion = sparse_motion.permute(0, 1, 5, 2, 3, 4) # (bs, num_kp+1, 3, d, h, w) + deformation = (sparse_motion * mask).sum(dim=1) # (bs, 3, d, h, w) mask take effect in this place + deformation = deformation.permute(0, 2, 3, 4, 1) # (bs, d, h, w, 3) + + out_dict['deformation'] = deformation + + if self.flag_estimate_occlusion_map: + bs, _, d, h, w = prediction.shape + prediction_reshape = prediction.view(bs, -1, h, w) + occlusion_map = torch.sigmoid(self.occlusion(prediction_reshape)) # Bx1x64x64 + out_dict['occlusion_map'] = occlusion_map + + return out_dict diff --git a/src/modules/motion_extractor.py b/src/modules/motion_extractor.py new file mode 100644 index 0000000..b2982e5 --- /dev/null +++ b/src/modules/motion_extractor.py @@ -0,0 +1,35 @@ +# coding: utf-8 + +""" +Motion extractor(M), which directly predicts the canonical keypoints, head pose and expression deformation of the input image +""" + +from torch import nn +import torch + +from .convnextv2 import convnextv2_tiny +from .util import filter_state_dict + +model_dict = { + 'convnextv2_tiny': convnextv2_tiny, +} + + +class MotionExtractor(nn.Module): + def __init__(self, **kwargs): + super(MotionExtractor, self).__init__() + + # default is convnextv2_base + backbone = kwargs.get('backbone', 'convnextv2_tiny') + self.detector = model_dict.get(backbone)(**kwargs) + + def load_pretrained(self, init_path: str): + if init_path not in (None, ''): + state_dict = torch.load(init_path, map_location=lambda storage, loc: storage)['model'] + state_dict = filter_state_dict(state_dict, remove_name='head') + ret = self.detector.load_state_dict(state_dict, strict=False) + print(f'Load pretrained model from {init_path}, ret: {ret}') + + def forward(self, x): + out = self.detector(x) + return out diff --git a/src/modules/spade_generator.py b/src/modules/spade_generator.py new file mode 100644 index 0000000..147a9ae --- /dev/null +++ b/src/modules/spade_generator.py @@ -0,0 +1,59 @@ +# coding: utf-8 + +""" +Spade decoder(G) defined in the paper, which input the warped feature to generate the animated image. +""" + +import torch +from torch import nn +import torch.nn.functional as F +from .util import SPADEResnetBlock + + +class SPADEDecoder(nn.Module): + def __init__(self, upscale=1, max_features=256, block_expansion=64, out_channels=64, num_down_blocks=2): + for i in range(num_down_blocks): + input_channels = min(max_features, block_expansion * (2 ** (i + 1))) + self.upscale = upscale + super().__init__() + norm_G = 'spadespectralinstance' + label_num_channels = input_channels # 256 + + self.fc = nn.Conv2d(input_channels, 2 * input_channels, 3, padding=1) + self.G_middle_0 = SPADEResnetBlock(2 * input_channels, 2 * input_channels, norm_G, label_num_channels) + self.G_middle_1 = SPADEResnetBlock(2 * input_channels, 2 * input_channels, norm_G, label_num_channels) + self.G_middle_2 = SPADEResnetBlock(2 * input_channels, 2 * input_channels, norm_G, label_num_channels) + self.G_middle_3 = SPADEResnetBlock(2 * input_channels, 2 * input_channels, norm_G, label_num_channels) + self.G_middle_4 = SPADEResnetBlock(2 * input_channels, 2 * input_channels, norm_G, label_num_channels) + self.G_middle_5 = SPADEResnetBlock(2 * input_channels, 2 * input_channels, norm_G, label_num_channels) + self.up_0 = SPADEResnetBlock(2 * input_channels, input_channels, norm_G, label_num_channels) + self.up_1 = SPADEResnetBlock(input_channels, out_channels, norm_G, label_num_channels) + self.up = nn.Upsample(scale_factor=2) + + if self.upscale is None or self.upscale <= 1: + self.conv_img = nn.Conv2d(out_channels, 3, 3, padding=1) + else: + self.conv_img = nn.Sequential( + nn.Conv2d(out_channels, 3 * (2 * 2), kernel_size=3, padding=1), + nn.PixelShuffle(upscale_factor=2) + ) + + def forward(self, feature): + seg = feature # Bx256x64x64 + x = self.fc(feature) # Bx512x64x64 + x = self.G_middle_0(x, seg) + x = self.G_middle_1(x, seg) + x = self.G_middle_2(x, seg) + x = self.G_middle_3(x, seg) + x = self.G_middle_4(x, seg) + x = self.G_middle_5(x, seg) + + x = self.up(x) # Bx512x64x64 -> Bx512x128x128 + x = self.up_0(x, seg) # Bx512x128x128 -> Bx256x128x128 + x = self.up(x) # Bx256x128x128 -> Bx256x256x256 + x = self.up_1(x, seg) # Bx256x256x256 -> Bx64x256x256 + + x = self.conv_img(F.leaky_relu(x, 2e-1)) # Bx64x256x256 -> Bx3xHxW + x = torch.sigmoid(x) # Bx3xHxW + + return x \ No newline at end of file diff --git a/src/modules/stitching_retargeting_network.py b/src/modules/stitching_retargeting_network.py new file mode 100644 index 0000000..5f50b7c --- /dev/null +++ b/src/modules/stitching_retargeting_network.py @@ -0,0 +1,38 @@ +# coding: utf-8 + +""" +Stitching module(S) and two retargeting modules(R) defined in the paper. + +- The stitching module pastes the animated portrait back into the original image space without pixel misalignment, such as in +the stitching region. + +- The eyes retargeting module is designed to address the issue of incomplete eye closure during cross-id reenactment, especially +when a person with small eyes drives a person with larger eyes. + +- The lip retargeting module is designed similarly to the eye retargeting module, and can also normalize the input by ensuring that +the lips are in a closed state, which facilitates better animation driving. +""" +from torch import nn + + +class StitchingRetargetingNetwork(nn.Module): + def __init__(self, input_size, hidden_sizes, output_size): + super(StitchingRetargetingNetwork, self).__init__() + layers = [] + for i in range(len(hidden_sizes)): + if i == 0: + layers.append(nn.Linear(input_size, hidden_sizes[i])) + else: + layers.append(nn.Linear(hidden_sizes[i - 1], hidden_sizes[i])) + layers.append(nn.ReLU(inplace=True)) + layers.append(nn.Linear(hidden_sizes[-1], output_size)) + self.mlp = nn.Sequential(*layers) + + def initialize_weights_to_zero(self): + for m in self.modules(): + if isinstance(m, nn.Linear): + nn.init.zeros_(m.weight) + nn.init.zeros_(m.bias) + + def forward(self, x): + return self.mlp(x) diff --git a/src/modules/util.py b/src/modules/util.py new file mode 100644 index 0000000..f83980b --- /dev/null +++ b/src/modules/util.py @@ -0,0 +1,441 @@ +# coding: utf-8 + +""" +This file defines various neural network modules and utility functions, including convolutional and residual blocks, +normalizations, and functions for spatial transformation and tensor manipulation. +""" + +from torch import nn +import torch.nn.functional as F +import torch +import torch.nn.utils.spectral_norm as spectral_norm +import math +import warnings + + +def kp2gaussian(kp, spatial_size, kp_variance): + """ + Transform a keypoint into gaussian like representation + """ + mean = kp + + coordinate_grid = make_coordinate_grid(spatial_size, mean) + number_of_leading_dimensions = len(mean.shape) - 1 + shape = (1,) * number_of_leading_dimensions + coordinate_grid.shape + coordinate_grid = coordinate_grid.view(*shape) + repeats = mean.shape[:number_of_leading_dimensions] + (1, 1, 1, 1) + coordinate_grid = coordinate_grid.repeat(*repeats) + + # Preprocess kp shape + shape = mean.shape[:number_of_leading_dimensions] + (1, 1, 1, 3) + mean = mean.view(*shape) + + mean_sub = (coordinate_grid - mean) + + out = torch.exp(-0.5 * (mean_sub ** 2).sum(-1) / kp_variance) + + return out + + +def make_coordinate_grid(spatial_size, ref, **kwargs): + d, h, w = spatial_size + x = torch.arange(w).type(ref.dtype).to(ref.device) + y = torch.arange(h).type(ref.dtype).to(ref.device) + z = torch.arange(d).type(ref.dtype).to(ref.device) + + # NOTE: must be right-down-in + x = (2 * (x / (w - 1)) - 1) # the x axis faces to the right + y = (2 * (y / (h - 1)) - 1) # the y axis faces to the bottom + z = (2 * (z / (d - 1)) - 1) # the z axis faces to the inner + + yy = y.view(1, -1, 1).repeat(d, 1, w) + xx = x.view(1, 1, -1).repeat(d, h, 1) + zz = z.view(-1, 1, 1).repeat(1, h, w) + + meshed = torch.cat([xx.unsqueeze_(3), yy.unsqueeze_(3), zz.unsqueeze_(3)], 3) + + return meshed + + +class ConvT2d(nn.Module): + """ + Upsampling block for use in decoder. + """ + + def __init__(self, in_features, out_features, kernel_size=3, stride=2, padding=1, output_padding=1): + super(ConvT2d, self).__init__() + + self.convT = nn.ConvTranspose2d(in_features, out_features, kernel_size=kernel_size, stride=stride, + padding=padding, output_padding=output_padding) + self.norm = nn.InstanceNorm2d(out_features) + + def forward(self, x): + out = self.convT(x) + out = self.norm(out) + out = F.leaky_relu(out) + return out + + +class ResBlock3d(nn.Module): + """ + Res block, preserve spatial resolution. + """ + + def __init__(self, in_features, kernel_size, padding): + super(ResBlock3d, self).__init__() + self.conv1 = nn.Conv3d(in_channels=in_features, out_channels=in_features, kernel_size=kernel_size, padding=padding) + self.conv2 = nn.Conv3d(in_channels=in_features, out_channels=in_features, kernel_size=kernel_size, padding=padding) + self.norm1 = nn.BatchNorm3d(in_features, affine=True) + self.norm2 = nn.BatchNorm3d(in_features, affine=True) + + def forward(self, x): + out = self.norm1(x) + out = F.relu(out) + out = self.conv1(out) + out = self.norm2(out) + out = F.relu(out) + out = self.conv2(out) + out += x + return out + + +class UpBlock3d(nn.Module): + """ + Upsampling block for use in decoder. + """ + + def __init__(self, in_features, out_features, kernel_size=3, padding=1, groups=1): + super(UpBlock3d, self).__init__() + + self.conv = nn.Conv3d(in_channels=in_features, out_channels=out_features, kernel_size=kernel_size, + padding=padding, groups=groups) + self.norm = nn.BatchNorm3d(out_features, affine=True) + + def forward(self, x): + out = F.interpolate(x, scale_factor=(1, 2, 2)) + out = self.conv(out) + out = self.norm(out) + out = F.relu(out) + return out + + +class DownBlock2d(nn.Module): + """ + Downsampling block for use in encoder. + """ + + def __init__(self, in_features, out_features, kernel_size=3, padding=1, groups=1): + super(DownBlock2d, self).__init__() + self.conv = nn.Conv2d(in_channels=in_features, out_channels=out_features, kernel_size=kernel_size, padding=padding, groups=groups) + self.norm = nn.BatchNorm2d(out_features, affine=True) + self.pool = nn.AvgPool2d(kernel_size=(2, 2)) + + def forward(self, x): + out = self.conv(x) + out = self.norm(out) + out = F.relu(out) + out = self.pool(out) + return out + + +class DownBlock3d(nn.Module): + """ + Downsampling block for use in encoder. + """ + + def __init__(self, in_features, out_features, kernel_size=3, padding=1, groups=1): + super(DownBlock3d, self).__init__() + ''' + self.conv = nn.Conv3d(in_channels=in_features, out_channels=out_features, kernel_size=kernel_size, + padding=padding, groups=groups, stride=(1, 2, 2)) + ''' + self.conv = nn.Conv3d(in_channels=in_features, out_channels=out_features, kernel_size=kernel_size, + padding=padding, groups=groups) + self.norm = nn.BatchNorm3d(out_features, affine=True) + self.pool = nn.AvgPool3d(kernel_size=(1, 2, 2)) + + def forward(self, x): + out = self.conv(x) + out = self.norm(out) + out = F.relu(out) + out = self.pool(out) + return out + + +class SameBlock2d(nn.Module): + """ + Simple block, preserve spatial resolution. + """ + + def __init__(self, in_features, out_features, groups=1, kernel_size=3, padding=1, lrelu=False): + super(SameBlock2d, self).__init__() + self.conv = nn.Conv2d(in_channels=in_features, out_channels=out_features, kernel_size=kernel_size, padding=padding, groups=groups) + self.norm = nn.BatchNorm2d(out_features, affine=True) + if lrelu: + self.ac = nn.LeakyReLU() + else: + self.ac = nn.ReLU() + + def forward(self, x): + out = self.conv(x) + out = self.norm(out) + out = self.ac(out) + return out + + +class Encoder(nn.Module): + """ + Hourglass Encoder + """ + + def __init__(self, block_expansion, in_features, num_blocks=3, max_features=256): + super(Encoder, self).__init__() + + down_blocks = [] + for i in range(num_blocks): + down_blocks.append(DownBlock3d(in_features if i == 0 else min(max_features, block_expansion * (2 ** i)), min(max_features, block_expansion * (2 ** (i + 1))), kernel_size=3, padding=1)) + self.down_blocks = nn.ModuleList(down_blocks) + + def forward(self, x): + outs = [x] + for down_block in self.down_blocks: + outs.append(down_block(outs[-1])) + return outs + + +class Decoder(nn.Module): + """ + Hourglass Decoder + """ + + def __init__(self, block_expansion, in_features, num_blocks=3, max_features=256): + super(Decoder, self).__init__() + + up_blocks = [] + + for i in range(num_blocks)[::-1]: + in_filters = (1 if i == num_blocks - 1 else 2) * min(max_features, block_expansion * (2 ** (i + 1))) + out_filters = min(max_features, block_expansion * (2 ** i)) + up_blocks.append(UpBlock3d(in_filters, out_filters, kernel_size=3, padding=1)) + + self.up_blocks = nn.ModuleList(up_blocks) + self.out_filters = block_expansion + in_features + + self.conv = nn.Conv3d(in_channels=self.out_filters, out_channels=self.out_filters, kernel_size=3, padding=1) + self.norm = nn.BatchNorm3d(self.out_filters, affine=True) + + def forward(self, x): + out = x.pop() + for up_block in self.up_blocks: + out = up_block(out) + skip = x.pop() + out = torch.cat([out, skip], dim=1) + out = self.conv(out) + out = self.norm(out) + out = F.relu(out) + return out + + +class Hourglass(nn.Module): + """ + Hourglass architecture. + """ + + def __init__(self, block_expansion, in_features, num_blocks=3, max_features=256): + super(Hourglass, self).__init__() + self.encoder = Encoder(block_expansion, in_features, num_blocks, max_features) + self.decoder = Decoder(block_expansion, in_features, num_blocks, max_features) + self.out_filters = self.decoder.out_filters + + def forward(self, x): + return self.decoder(self.encoder(x)) + + +class SPADE(nn.Module): + def __init__(self, norm_nc, label_nc): + super().__init__() + + self.param_free_norm = nn.InstanceNorm2d(norm_nc, affine=False) + nhidden = 128 + + self.mlp_shared = nn.Sequential( + nn.Conv2d(label_nc, nhidden, kernel_size=3, padding=1), + nn.ReLU()) + self.mlp_gamma = nn.Conv2d(nhidden, norm_nc, kernel_size=3, padding=1) + self.mlp_beta = nn.Conv2d(nhidden, norm_nc, kernel_size=3, padding=1) + + def forward(self, x, segmap): + normalized = self.param_free_norm(x) + segmap = F.interpolate(segmap, size=x.size()[2:], mode='nearest') + actv = self.mlp_shared(segmap) + gamma = self.mlp_gamma(actv) + beta = self.mlp_beta(actv) + out = normalized * (1 + gamma) + beta + return out + + +class SPADEResnetBlock(nn.Module): + def __init__(self, fin, fout, norm_G, label_nc, use_se=False, dilation=1): + super().__init__() + # Attributes + self.learned_shortcut = (fin != fout) + fmiddle = min(fin, fout) + self.use_se = use_se + # create conv layers + self.conv_0 = nn.Conv2d(fin, fmiddle, kernel_size=3, padding=dilation, dilation=dilation) + self.conv_1 = nn.Conv2d(fmiddle, fout, kernel_size=3, padding=dilation, dilation=dilation) + if self.learned_shortcut: + self.conv_s = nn.Conv2d(fin, fout, kernel_size=1, bias=False) + # apply spectral norm if specified + if 'spectral' in norm_G: + self.conv_0 = spectral_norm(self.conv_0) + self.conv_1 = spectral_norm(self.conv_1) + if self.learned_shortcut: + self.conv_s = spectral_norm(self.conv_s) + # define normalization layers + self.norm_0 = SPADE(fin, label_nc) + self.norm_1 = SPADE(fmiddle, label_nc) + if self.learned_shortcut: + self.norm_s = SPADE(fin, label_nc) + + def forward(self, x, seg1): + x_s = self.shortcut(x, seg1) + dx = self.conv_0(self.actvn(self.norm_0(x, seg1))) + dx = self.conv_1(self.actvn(self.norm_1(dx, seg1))) + out = x_s + dx + return out + + def shortcut(self, x, seg1): + if self.learned_shortcut: + x_s = self.conv_s(self.norm_s(x, seg1)) + else: + x_s = x + return x_s + + def actvn(self, x): + return F.leaky_relu(x, 2e-1) + + +def filter_state_dict(state_dict, remove_name='fc'): + new_state_dict = {} + for key in state_dict: + if remove_name in key: + continue + new_state_dict[key] = state_dict[key] + return new_state_dict + + +class GRN(nn.Module): + """ GRN (Global Response Normalization) layer + """ + + def __init__(self, dim): + super().__init__() + self.gamma = nn.Parameter(torch.zeros(1, 1, 1, dim)) + self.beta = nn.Parameter(torch.zeros(1, 1, 1, dim)) + + def forward(self, x): + Gx = torch.norm(x, p=2, dim=(1, 2), keepdim=True) + Nx = Gx / (Gx.mean(dim=-1, keepdim=True) + 1e-6) + return self.gamma * (x * Nx) + self.beta + x + + +class LayerNorm(nn.Module): + r""" LayerNorm that supports two data formats: channels_last (default) or channels_first. + The ordering of the dimensions in the inputs. channels_last corresponds to inputs with + shape (batch_size, height, width, channels) while channels_first corresponds to inputs + with shape (batch_size, channels, height, width). + """ + + def __init__(self, normalized_shape, eps=1e-6, data_format="channels_last"): + super().__init__() + self.weight = nn.Parameter(torch.ones(normalized_shape)) + self.bias = nn.Parameter(torch.zeros(normalized_shape)) + self.eps = eps + self.data_format = data_format + if self.data_format not in ["channels_last", "channels_first"]: + raise NotImplementedError + self.normalized_shape = (normalized_shape, ) + + def forward(self, x): + if self.data_format == "channels_last": + return F.layer_norm(x, self.normalized_shape, self.weight, self.bias, self.eps) + elif self.data_format == "channels_first": + u = x.mean(1, keepdim=True) + s = (x - u).pow(2).mean(1, keepdim=True) + x = (x - u) / torch.sqrt(s + self.eps) + x = self.weight[:, None, None] * x + self.bias[:, None, None] + return x + + +def _no_grad_trunc_normal_(tensor, mean, std, a, b): + # Cut & paste from PyTorch official master until it's in a few official releases - RW + # Method based on https://people.sc.fsu.edu/~jburkardt/presentations/truncated_normal.pdf + def norm_cdf(x): + # Computes standard normal cumulative distribution function + return (1. + math.erf(x / math.sqrt(2.))) / 2. + + if (mean < a - 2 * std) or (mean > b + 2 * std): + warnings.warn("mean is more than 2 std from [a, b] in nn.init.trunc_normal_. " + "The distribution of values may be incorrect.", + stacklevel=2) + + with torch.no_grad(): + # Values are generated by using a truncated uniform distribution and + # then using the inverse CDF for the normal distribution. + # Get upper and lower cdf values + l = norm_cdf((a - mean) / std) + u = norm_cdf((b - mean) / std) + + # Uniformly fill tensor with values from [l, u], then translate to + # [2l-1, 2u-1]. + tensor.uniform_(2 * l - 1, 2 * u - 1) + + # Use inverse cdf transform for normal distribution to get truncated + # standard normal + tensor.erfinv_() + + # Transform to proper mean, std + tensor.mul_(std * math.sqrt(2.)) + tensor.add_(mean) + + # Clamp to ensure it's in the proper range + tensor.clamp_(min=a, max=b) + return tensor + + +def drop_path(x, drop_prob=0., training=False, scale_by_keep=True): + """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). + + This is the same as the DropConnect impl I created for EfficientNet, etc networks, however, + the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... + See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for + changing the layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use + 'survival rate' as the argument. + + """ + if drop_prob == 0. or not training: + return x + keep_prob = 1 - drop_prob + shape = (x.shape[0],) + (1,) * (x.ndim - 1) # work with diff dim tensors, not just 2D ConvNets + random_tensor = x.new_empty(shape).bernoulli_(keep_prob) + if keep_prob > 0.0 and scale_by_keep: + random_tensor.div_(keep_prob) + return x * random_tensor + + +class DropPath(nn.Module): + """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). + """ + + def __init__(self, drop_prob=None, scale_by_keep=True): + super(DropPath, self).__init__() + self.drop_prob = drop_prob + self.scale_by_keep = scale_by_keep + + def forward(self, x): + return drop_path(x, self.drop_prob, self.training, self.scale_by_keep) + + +def trunc_normal_(tensor, mean=0., std=1., a=-2., b=2.): + return _no_grad_trunc_normal_(tensor, mean, std, a, b) diff --git a/src/modules/warping_network.py b/src/modules/warping_network.py new file mode 100644 index 0000000..9191a19 --- /dev/null +++ b/src/modules/warping_network.py @@ -0,0 +1,77 @@ +# coding: utf-8 + +""" +Warping field estimator(W) defined in the paper, which generates a warping field using the implicit +keypoint representations x_s and x_d, and employs this flow field to warp the source feature volume f_s. +""" + +from torch import nn +import torch.nn.functional as F +from .util import SameBlock2d +from .dense_motion import DenseMotionNetwork + + +class WarpingNetwork(nn.Module): + def __init__( + self, + num_kp, + block_expansion, + max_features, + num_down_blocks, + reshape_channel, + estimate_occlusion_map=False, + dense_motion_params=None, + **kwargs + ): + super(WarpingNetwork, self).__init__() + + self.upscale = kwargs.get('upscale', 1) + self.flag_use_occlusion_map = kwargs.get('flag_use_occlusion_map', True) + + if dense_motion_params is not None: + self.dense_motion_network = DenseMotionNetwork( + num_kp=num_kp, + feature_channel=reshape_channel, + estimate_occlusion_map=estimate_occlusion_map, + **dense_motion_params + ) + else: + self.dense_motion_network = None + + self.third = SameBlock2d(max_features, block_expansion * (2 ** num_down_blocks), kernel_size=(3, 3), padding=(1, 1), lrelu=True) + self.fourth = nn.Conv2d(in_channels=block_expansion * (2 ** num_down_blocks), out_channels=block_expansion * (2 ** num_down_blocks), kernel_size=1, stride=1) + + self.estimate_occlusion_map = estimate_occlusion_map + + def deform_input(self, inp, deformation): + return F.grid_sample(inp, deformation, align_corners=False) + + def forward(self, feature_3d, kp_driving, kp_source): + if self.dense_motion_network is not None: + # Feature warper, Transforming feature representation according to deformation and occlusion + dense_motion = self.dense_motion_network( + feature=feature_3d, kp_driving=kp_driving, kp_source=kp_source + ) + if 'occlusion_map' in dense_motion: + occlusion_map = dense_motion['occlusion_map'] # Bx1x64x64 + else: + occlusion_map = None + + deformation = dense_motion['deformation'] # Bx16x64x64x3 + out = self.deform_input(feature_3d, deformation) # Bx32x16x64x64 + + bs, c, d, h, w = out.shape # Bx32x16x64x64 + out = out.view(bs, c * d, h, w) # -> Bx512x64x64 + out = self.third(out) # -> Bx256x64x64 + out = self.fourth(out) # -> Bx256x64x64 + + if self.flag_use_occlusion_map and (occlusion_map is not None): + out = out * occlusion_map + + ret_dct = { + 'occlusion_map': occlusion_map, + 'deformation': deformation, + 'out': out, + } + + return ret_dct diff --git a/src/template_maker.py b/src/template_maker.py new file mode 100644 index 0000000..7f3ce06 --- /dev/null +++ b/src/template_maker.py @@ -0,0 +1,65 @@ +# coding: utf-8 + +""" +Make video template +""" + +import os +import cv2 +import numpy as np +import pickle +from rich.progress import track +from .utils.cropper import Cropper + +from .utils.io import load_driving_info +from .utils.camera import get_rotation_matrix +from .utils.helper import mkdir, basename +from .utils.rprint import rlog as log +from .config.crop_config import CropConfig +from .config.inference_config import InferenceConfig +from .live_portrait_wrapper import LivePortraitWrapper + +class TemplateMaker: + + def __init__(self, inference_cfg: InferenceConfig, crop_cfg: CropConfig): + self.live_portrait_wrapper: LivePortraitWrapper = LivePortraitWrapper(cfg=inference_cfg) + self.cropper = Cropper(crop_cfg=crop_cfg) + + def make_motion_template(self, video_fp: str, output_path: str, **kwargs): + """ make video template (.pkl format) + video_fp: driving video file path + output_path: where to save the pickle file + """ + + driving_rgb_lst = load_driving_info(video_fp) + driving_rgb_lst = [cv2.resize(_, (256, 256)) for _ in driving_rgb_lst] + driving_lmk_lst = self.cropper.get_retargeting_lmk_info(driving_rgb_lst) + I_d_lst = self.live_portrait_wrapper.prepare_driving_videos(driving_rgb_lst) + + n_frames = I_d_lst.shape[0] + + templates = [] + + + for i in track(range(n_frames), description='Making templates...', total=n_frames): + I_d_i = I_d_lst[i] + x_d_i_info = self.live_portrait_wrapper.get_kp_info(I_d_i) + R_d_i = get_rotation_matrix(x_d_i_info['pitch'], x_d_i_info['yaw'], x_d_i_info['roll']) + # collect s_d, R_d, ฮด_d and t_d for inference + template_dct = { + 'n_frames': n_frames, + 'frames_index': i, + } + template_dct['scale'] = x_d_i_info['scale'].cpu().numpy().astype(np.float32) + template_dct['R_d'] = R_d_i.cpu().numpy().astype(np.float32) + template_dct['exp'] = x_d_i_info['exp'].cpu().numpy().astype(np.float32) + template_dct['t'] = x_d_i_info['t'].cpu().numpy().astype(np.float32) + + templates.append(template_dct) + + mkdir(output_path) + # Save the dictionary as a pickle file + pickle_fp = os.path.join(output_path, f'{basename(video_fp)}.pkl') + with open(pickle_fp, 'wb') as f: + pickle.dump([templates, driving_lmk_lst], f) + log(f"Template saved at {pickle_fp}") diff --git a/src/utils/__init__.py b/src/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/utils/camera.py b/src/utils/camera.py new file mode 100644 index 0000000..8bbfc90 --- /dev/null +++ b/src/utils/camera.py @@ -0,0 +1,75 @@ +# coding: utf-8 + +""" +functions for processing and transforming 3D facial keypoints +""" + +import numpy as np +import torch +import torch.nn.functional as F + +PI = np.pi + + +def headpose_pred_to_degree(pred): + """ + pred: (bs, 66) or (bs, 1) or others + """ + if pred.ndim > 1 and pred.shape[1] == 66: + # NOTE: note that the average is modified to 97.5 + device = pred.device + idx_tensor = [idx for idx in range(0, 66)] + idx_tensor = torch.FloatTensor(idx_tensor).to(device) + pred = F.softmax(pred, dim=1) + degree = torch.sum(pred*idx_tensor, axis=1) * 3 - 97.5 + + return degree + + return pred + + +def get_rotation_matrix(pitch_, yaw_, roll_): + """ the input is in degree + """ + # calculate the rotation matrix: vps @ rot + + # transform to radian + pitch = pitch_ / 180 * PI + yaw = yaw_ / 180 * PI + roll = roll_ / 180 * PI + + device = pitch.device + + if pitch.ndim == 1: + pitch = pitch.unsqueeze(1) + if yaw.ndim == 1: + yaw = yaw.unsqueeze(1) + if roll.ndim == 1: + roll = roll.unsqueeze(1) + + # calculate the euler matrix + bs = pitch.shape[0] + ones = torch.ones([bs, 1]).to(device) + zeros = torch.zeros([bs, 1]).to(device) + x, y, z = pitch, yaw, roll + + rot_x = torch.cat([ + ones, zeros, zeros, + zeros, torch.cos(x), -torch.sin(x), + zeros, torch.sin(x), torch.cos(x) + ], dim=1).reshape([bs, 3, 3]) + + rot_y = torch.cat([ + torch.cos(y), zeros, torch.sin(y), + zeros, ones, zeros, + -torch.sin(y), zeros, torch.cos(y) + ], dim=1).reshape([bs, 3, 3]) + + rot_z = torch.cat([ + torch.cos(z), -torch.sin(z), zeros, + torch.sin(z), torch.cos(z), zeros, + zeros, zeros, ones + ], dim=1).reshape([bs, 3, 3]) + + rot = rot_z @ rot_y @ rot_x + return rot.permute(0, 2, 1) # transpose diff --git a/src/utils/crop.py b/src/utils/crop.py new file mode 100644 index 0000000..c061ef4 --- /dev/null +++ b/src/utils/crop.py @@ -0,0 +1,393 @@ +# coding: utf-8 + +""" +cropping function and the related preprocess functions for cropping +""" + +import cv2; cv2.setNumThreads(0); cv2.ocl.setUseOpenCL(False) # NOTE: enforce single thread +import numpy as np +from .rprint import rprint as print +from math import sin, cos, acos, degrees + +DTYPE = np.float32 +CV2_INTERP = cv2.INTER_LINEAR + + +def _transform_img(img, M, dsize, flags=CV2_INTERP, borderMode=None): + """ conduct similarity or affine transformation to the image, do not do border operation! + img: + M: 2x3 matrix or 3x3 matrix + dsize: target shape (width, height) + """ + if isinstance(dsize, tuple) or isinstance(dsize, list): + _dsize = tuple(dsize) + else: + _dsize = (dsize, dsize) + + if borderMode is not None: + return cv2.warpAffine(img, M[:2, :], dsize=_dsize, flags=flags, borderMode=borderMode, borderValue=(0, 0, 0)) + else: + return cv2.warpAffine(img, M[:2, :], dsize=_dsize, flags=flags) + + +def _transform_pts(pts, M): + """ conduct similarity or affine transformation to the pts + pts: Nx2 ndarray + M: 2x3 matrix or 3x3 matrix + return: Nx2 + """ + return pts @ M[:2, :2].T + M[:2, 2] + + +def parse_pt2_from_pt101(pt101, use_lip=True): + """ + parsing the 2 points according to the 101 points, which cancels the roll + """ + # the former version use the eye center, but it is not robust, now use interpolation + pt_left_eye = np.mean(pt101[[39, 42, 45, 48]], axis=0) # left eye center + pt_right_eye = np.mean(pt101[[51, 54, 57, 60]], axis=0) # right eye center + + if use_lip: + # use lip + pt_center_eye = (pt_left_eye + pt_right_eye) / 2 + pt_center_lip = (pt101[75] + pt101[81]) / 2 + pt2 = np.stack([pt_center_eye, pt_center_lip], axis=0) + else: + pt2 = np.stack([pt_left_eye, pt_right_eye], axis=0) + return pt2 + + +def parse_pt2_from_pt106(pt106, use_lip=True): + """ + parsing the 2 points according to the 106 points, which cancels the roll + """ + pt_left_eye = np.mean(pt106[[33, 35, 40, 39]], axis=0) # left eye center + pt_right_eye = np.mean(pt106[[87, 89, 94, 93]], axis=0) # right eye center + + if use_lip: + # use lip + pt_center_eye = (pt_left_eye + pt_right_eye) / 2 + pt_center_lip = (pt106[52] + pt106[61]) / 2 + pt2 = np.stack([pt_center_eye, pt_center_lip], axis=0) + else: + pt2 = np.stack([pt_left_eye, pt_right_eye], axis=0) + return pt2 + + +def parse_pt2_from_pt203(pt203, use_lip=True): + """ + parsing the 2 points according to the 203 points, which cancels the roll + """ + pt_left_eye = np.mean(pt203[[0, 6, 12, 18]], axis=0) # left eye center + pt_right_eye = np.mean(pt203[[24, 30, 36, 42]], axis=0) # right eye center + if use_lip: + # use lip + pt_center_eye = (pt_left_eye + pt_right_eye) / 2 + pt_center_lip = (pt203[48] + pt203[66]) / 2 + pt2 = np.stack([pt_center_eye, pt_center_lip], axis=0) + else: + pt2 = np.stack([pt_left_eye, pt_right_eye], axis=0) + return pt2 + + +def parse_pt2_from_pt68(pt68, use_lip=True): + """ + parsing the 2 points according to the 68 points, which cancels the roll + """ + lm_idx = np.array([31, 37, 40, 43, 46, 49, 55], dtype=np.int32) - 1 + if use_lip: + pt5 = np.stack([ + np.mean(pt68[lm_idx[[1, 2]], :], 0), # left eye + np.mean(pt68[lm_idx[[3, 4]], :], 0), # right eye + pt68[lm_idx[0], :], # nose + pt68[lm_idx[5], :], # lip + pt68[lm_idx[6], :] # lip + ], axis=0) + + pt2 = np.stack([ + (pt5[0] + pt5[1]) / 2, + (pt5[3] + pt5[4]) / 2 + ], axis=0) + else: + pt2 = np.stack([ + np.mean(pt68[lm_idx[[1, 2]], :], 0), # left eye + np.mean(pt68[lm_idx[[3, 4]], :], 0), # right eye + ], axis=0) + + return pt2 + + +def parse_pt2_from_pt5(pt5, use_lip=True): + """ + parsing the 2 points according to the 5 points, which cancels the roll + """ + if use_lip: + pt2 = np.stack([ + (pt5[0] + pt5[1]) / 2, + (pt5[3] + pt5[4]) / 2 + ], axis=0) + else: + pt2 = np.stack([ + pt5[0], + pt5[1] + ], axis=0) + return pt2 + + +def parse_pt2_from_pt_x(pts, use_lip=True): + if pts.shape[0] == 101: + pt2 = parse_pt2_from_pt101(pts, use_lip=use_lip) + elif pts.shape[0] == 106: + pt2 = parse_pt2_from_pt106(pts, use_lip=use_lip) + elif pts.shape[0] == 68: + pt2 = parse_pt2_from_pt68(pts, use_lip=use_lip) + elif pts.shape[0] == 5: + pt2 = parse_pt2_from_pt5(pts, use_lip=use_lip) + elif pts.shape[0] == 203: + pt2 = parse_pt2_from_pt203(pts, use_lip=use_lip) + elif pts.shape[0] > 101: + # take the first 101 points + pt2 = parse_pt2_from_pt101(pts[:101], use_lip=use_lip) + else: + raise Exception(f'Unknow shape: {pts.shape}') + + if not use_lip: + # NOTE: to compile with the latter code, need to rotate the pt2 90 degrees clockwise manually + v = pt2[1] - pt2[0] + pt2[1, 0] = pt2[0, 0] - v[1] + pt2[1, 1] = pt2[0, 1] + v[0] + + return pt2 + + +def parse_rect_from_landmark( + pts, + scale=1.5, + need_square=True, + vx_ratio=0, + vy_ratio=0, + use_deg_flag=False, + **kwargs +): + """parsing center, size, angle from 101/68/5/x landmarks + vx_ratio: the offset ratio along the pupil axis x-axis, multiplied by size + vy_ratio: the offset ratio along the pupil axis y-axis, multiplied by size, which is used to contain more forehead area + + judge with pts.shape + """ + pt2 = parse_pt2_from_pt_x(pts, use_lip=kwargs.get('use_lip', True)) + + uy = pt2[1] - pt2[0] + l = np.linalg.norm(uy) + if l <= 1e-3: + uy = np.array([0, 1], dtype=DTYPE) + else: + uy /= l + ux = np.array((uy[1], -uy[0]), dtype=DTYPE) + + # the rotation degree of the x-axis, the clockwise is positive, the counterclockwise is negative (image coordinate system) + # print(uy) + # print(ux) + angle = acos(ux[0]) + if ux[1] < 0: + angle = -angle + + # rotation matrix + M = np.array([ux, uy]) + + # calculate the size which contains the angle degree of the bbox, and the center + center0 = np.mean(pts, axis=0) + rpts = (pts - center0) @ M.T # (M @ P.T).T = P @ M.T + lt_pt = np.min(rpts, axis=0) + rb_pt = np.max(rpts, axis=0) + center1 = (lt_pt + rb_pt) / 2 + + size = rb_pt - lt_pt + if need_square: + m = max(size[0], size[1]) + size[0] = m + size[1] = m + + size *= scale # scale size + center = center0 + ux * center1[0] + uy * center1[1] # counterclockwise rotation, equivalent to M.T @ center1.T + center = center + ux * (vx_ratio * size) + uy * \ + (vy_ratio * size) # considering the offset in vx and vy direction + + if use_deg_flag: + angle = degrees(angle) + + return center, size, angle + + +def parse_bbox_from_landmark(pts, **kwargs): + center, size, angle = parse_rect_from_landmark(pts, **kwargs) + cx, cy = center + w, h = size + + # calculate the vertex positions before rotation + bbox = np.array([ + [cx-w/2, cy-h/2], # left, top + [cx+w/2, cy-h/2], + [cx+w/2, cy+h/2], # right, bottom + [cx-w/2, cy+h/2] + ], dtype=DTYPE) + + # construct rotation matrix + bbox_rot = bbox.copy() + R = np.array([ + [np.cos(angle), -np.sin(angle)], + [np.sin(angle), np.cos(angle)] + ], dtype=DTYPE) + + # calculate the relative position of each vertex from the rotation center, then rotate these positions, and finally add the coordinates of the rotation center + bbox_rot = (bbox_rot - center) @ R.T + center + + return { + 'center': center, # 2x1 + 'size': size, # scalar + 'angle': angle, # rad, counterclockwise + 'bbox': bbox, # 4x2 + 'bbox_rot': bbox_rot, # 4x2 + } + + +def crop_image_by_bbox(img, bbox, lmk=None, dsize=512, angle=None, flag_rot=False, **kwargs): + left, top, right, bot = bbox + if int(right - left) != int(bot - top): + print(f'right-left {right-left} != bot-top {bot-top}') + size = right - left + + src_center = np.array([(left + right) / 2, (top + bot) / 2], dtype=DTYPE) + tgt_center = np.array([dsize / 2, dsize / 2], dtype=DTYPE) + + s = dsize / size # scale + if flag_rot and angle is not None: + costheta, sintheta = cos(angle), sin(angle) + cx, cy = src_center[0], src_center[1] # ori center + tcx, tcy = tgt_center[0], tgt_center[1] # target center + # need to infer + M_o2c = np.array( + [[s * costheta, s * sintheta, tcx - s * (costheta * cx + sintheta * cy)], + [-s * sintheta, s * costheta, tcy - s * (-sintheta * cx + costheta * cy)]], + dtype=DTYPE + ) + else: + M_o2c = np.array( + [[s, 0, tgt_center[0] - s * src_center[0]], + [0, s, tgt_center[1] - s * src_center[1]]], + dtype=DTYPE + ) + + if flag_rot and angle is None: + print('angle is None, but flag_rotate is True', style="bold yellow") + + img_crop = _transform_img(img, M_o2c, dsize=dsize, borderMode=kwargs.get('borderMode', None)) + + lmk_crop = _transform_pts(lmk, M_o2c) if lmk is not None else None + + M_o2c = np.vstack([M_o2c, np.array([0, 0, 1], dtype=DTYPE)]) + M_c2o = np.linalg.inv(M_o2c) + + # cv2.imwrite('crop.jpg', img_crop) + + return { + 'img_crop': img_crop, + 'lmk_crop': lmk_crop, + 'M_o2c': M_o2c, + 'M_c2o': M_c2o, + } + + +def _estimate_similar_transform_from_pts( + pts, + dsize, + scale=1.5, + vx_ratio=0, + vy_ratio=-0.1, + flag_do_rot=True, + **kwargs +): + """ calculate the affine matrix of the cropped image from sparse points, the original image to the cropped image, the inverse is the cropped image to the original image + pts: landmark, 101 or 68 points or other points, Nx2 + scale: the larger scale factor, the smaller face ratio + vx_ratio: x shift + vy_ratio: y shift, the smaller the y shift, the lower the face region + rot_flag: if it is true, conduct correction + """ + center, size, angle = parse_rect_from_landmark( + pts, scale=scale, vx_ratio=vx_ratio, vy_ratio=vy_ratio, + use_lip=kwargs.get('use_lip', True) + ) + + s = dsize / size[0] # scale + tgt_center = np.array([dsize / 2, dsize / 2], dtype=DTYPE) # center of dsize + + if flag_do_rot: + costheta, sintheta = cos(angle), sin(angle) + cx, cy = center[0], center[1] # ori center + tcx, tcy = tgt_center[0], tgt_center[1] # target center + # need to infer + M_INV = np.array( + [[s * costheta, s * sintheta, tcx - s * (costheta * cx + sintheta * cy)], + [-s * sintheta, s * costheta, tcy - s * (-sintheta * cx + costheta * cy)]], + dtype=DTYPE + ) + else: + M_INV = np.array( + [[s, 0, tgt_center[0] - s * center[0]], + [0, s, tgt_center[1] - s * center[1]]], + dtype=DTYPE + ) + + M_INV_H = np.vstack([M_INV, np.array([0, 0, 1])]) + M = np.linalg.inv(M_INV_H) + + # M_INV is from the original image to the cropped image, M is from the cropped image to the original image + return M_INV, M[:2, ...] + + +def crop_image(img, pts: np.ndarray, **kwargs): + dsize = kwargs.get('dsize', 224) + scale = kwargs.get('scale', 1.5) # 1.5 | 1.6 + vy_ratio = kwargs.get('vy_ratio', -0.1) # -0.0625 | -0.1 + + M_INV, _ = _estimate_similar_transform_from_pts( + pts, + dsize=dsize, + scale=scale, + vy_ratio=vy_ratio, + flag_do_rot=kwargs.get('flag_do_rot', True), + ) + + if img is None: + M_INV_H = np.vstack([M_INV, np.array([0, 0, 1], dtype=DTYPE)]) + M = np.linalg.inv(M_INV_H) + ret_dct = { + 'M': M[:2, ...], # from the original image to the cropped image + 'M_o2c': M[:2, ...], # from the cropped image to the original image + 'img_crop': None, + 'pt_crop': None, + } + return ret_dct + + img_crop = _transform_img(img, M_INV, dsize) # origin to crop + pt_crop = _transform_pts(pts, M_INV) + + M_o2c = np.vstack([M_INV, np.array([0, 0, 1], dtype=DTYPE)]) + M_c2o = np.linalg.inv(M_o2c) + + ret_dct = { + 'M_o2c': M_o2c, # from the original image to the cropped image 3x3 + 'M_c2o': M_c2o, # from the cropped image to the original image 3x3 + 'img_crop': img_crop, # the cropped image + 'pt_crop': pt_crop, # the landmarks of the cropped image + } + + return ret_dct + +def average_bbox_lst(bbox_lst): + if len(bbox_lst) == 0: + return None + bbox_arr = np.array(bbox_lst) + return np.mean(bbox_arr, axis=0).tolist() + diff --git a/src/utils/cropper.py b/src/utils/cropper.py new file mode 100644 index 0000000..e8ee194 --- /dev/null +++ b/src/utils/cropper.py @@ -0,0 +1,143 @@ +# coding: utf-8 + +import numpy as np +import os.path as osp +from typing import List, Union, Tuple +from dataclasses import dataclass, field +import cv2; cv2.setNumThreads(0); cv2.ocl.setUseOpenCL(False) + +from .landmark_runner import LandmarkRunner +from .face_analysis_diy import FaceAnalysisDIY +from .helper import prefix +from .crop import crop_image, crop_image_by_bbox, parse_bbox_from_landmark, average_bbox_lst +from .timer import Timer +from .rprint import rlog as log +from .io import load_image_rgb +from .video import VideoWriter, get_fps, change_video_fps + + +def make_abs_path(fn): + return osp.join(osp.dirname(osp.realpath(__file__)), fn) + + +@dataclass +class Trajectory: + start: int = -1 # ่ตทๅง‹ๅธง ้—ญๅŒบ้—ด + end: int = -1 # ็ป“ๆŸๅธง ้—ญๅŒบ้—ด + lmk_lst: Union[Tuple, List, np.ndarray] = field(default_factory=list) # lmk list + bbox_lst: Union[Tuple, List, np.ndarray] = field(default_factory=list) # bbox list + frame_rgb_lst: Union[Tuple, List, np.ndarray] = field(default_factory=list) # frame list + frame_rgb_crop_lst: Union[Tuple, List, np.ndarray] = field(default_factory=list) # frame crop list + + +class Cropper(object): + def __init__(self, **kwargs) -> None: + device_id = kwargs.get('device_id', 0) + self.landmark_runner = LandmarkRunner( + ckpt_path=make_abs_path('../../pretrained_weights/liveportrait/landmark.onnx'), + onnx_provider='cuda', + device_id=device_id + ) + self.landmark_runner.warmup() + + self.face_analysis_wrapper = FaceAnalysisDIY( + name='buffalo_l', + root=make_abs_path('../../pretrained_weights/insightface'), + providers=["CUDAExecutionProvider"] + ) + self.face_analysis_wrapper.prepare(ctx_id=device_id, det_size=(512, 512)) + self.face_analysis_wrapper.warmup() + + self.crop_cfg = kwargs.get('crop_cfg', None) + + def update_config(self, user_args): + for k, v in user_args.items(): + if hasattr(self.crop_cfg, k): + setattr(self.crop_cfg, k, v) + + def crop_single_image(self, obj, **kwargs): + direction = kwargs.get('direction', 'large-small') + + # crop and align a single image + if isinstance(obj, str): + img_rgb = load_image_rgb(obj) + elif isinstance(obj, np.ndarray): + img_rgb = obj + + src_face = self.face_analysis_wrapper.get( + img_rgb, + flag_do_landmark_2d_106=True, + direction=direction + ) + + if len(src_face) == 0: + log('No face detected in the source image.') + raise Exception("No face detected in the source image!") + elif len(src_face) > 1: + log(f'More than one face detected in the image, only pick one face by rule {direction}.') + + src_face = src_face[0] + pts = src_face.landmark_2d_106 + + # crop the face + ret_dct = crop_image( + img_rgb, # ndarray + pts, # 106x2 or Nx2 + dsize=kwargs.get('dsize', 512), + scale=kwargs.get('scale', 2.3), + vy_ratio=kwargs.get('vy_ratio', -0.15), + ) + # update a 256x256 version for network input or else + ret_dct['img_crop_256x256'] = cv2.resize(ret_dct['img_crop'], (256, 256), interpolation=cv2.INTER_AREA) + ret_dct['pt_crop_256x256'] = ret_dct['pt_crop'] * 256 / kwargs.get('dsize', 512) + + recon_ret = self.landmark_runner.run(img_rgb, pts) + lmk = recon_ret['pts'] + ret_dct['lmk_crop'] = lmk + + return ret_dct + + def get_retargeting_lmk_info(self, driving_rgb_lst): + # TODO: implement a tracking-based version + driving_lmk_lst = [] + for driving_image in driving_rgb_lst: + ret_dct = self.crop_single_image(driving_image) + driving_lmk_lst.append(ret_dct['lmk_crop']) + return driving_lmk_lst + + def make_video_clip(self, driving_rgb_lst, output_path, output_fps=30, **kwargs): + trajectory = Trajectory() + direction = kwargs.get('direction', 'large-small') + for idx, driving_image in enumerate(driving_rgb_lst): + if idx == 0 or trajectory.start == -1: + src_face = self.face_analysis_wrapper.get( + driving_image, + flag_do_landmark_2d_106=True, + direction=direction + ) + if len(src_face) == 0: + # No face detected in the driving_image + continue + elif len(src_face) > 1: + log(f'More than one face detected in the driving frame_{idx}, only pick one face by rule {direction}.') + src_face = src_face[0] + pts = src_face.landmark_2d_106 + lmk_203 = self.landmark_runner(driving_image, pts)['pts'] + trajectory.start, trajectory.end = idx, idx + else: + lmk_203 = self.face_recon_wrapper(driving_image, trajectory.lmk_lst[-1])['pts'] + trajectory.end = idx + + trajectory.lmk_lst.append(lmk_203) + ret_bbox = parse_bbox_from_landmark(lmk_203, scale=self.crop_cfg.globalscale, vy_ratio=elf.crop_cfg.vy_ratio)['bbox'] + bbox = [ret_bbox[0, 0], ret_bbox[0, 1], ret_bbox[2, 0], ret_bbox[2, 1]] # 4, + trajectory.bbox_lst.append(bbox) # bbox + trajectory.frame_rgb_lst.append(driving_image) + + global_bbox = average_bbox_lst(trajectory.bbox_lst) + for idx, (frame_rgb, lmk) in enumerate(zip(trajectory.frame_rgb_lst, trajectory.lmk_lst)): + ret_dct = crop_image_by_bbox( + frame_rgb, global_bbox, lmk=lmk, + dsize=self.video_crop_cfg.dsize, flag_rot=self.video_crop_cfg.flag_rot, borderValue=self.video_crop_cfg.borderValue + ) + frame_rgb_crop = ret_dct['img_crop'] diff --git a/src/utils/dependencies/insightface/__init__.py b/src/utils/dependencies/insightface/__init__.py new file mode 100644 index 0000000..7ddc9e0 --- /dev/null +++ b/src/utils/dependencies/insightface/__init__.py @@ -0,0 +1,21 @@ +# coding: utf-8 +# pylint: disable=wrong-import-position +"""InsightFace: A Face Analysis Toolkit.""" +from __future__ import absolute_import + +try: + #import mxnet as mx + import onnxruntime +except ImportError: + raise ImportError( + "Unable to import dependency onnxruntime. " + ) + +__version__ = '0.7.3' + +from . import model_zoo +from . import utils +from . import app +from . import data +from . import thirdparty + diff --git a/src/utils/dependencies/insightface/app/__init__.py b/src/utils/dependencies/insightface/app/__init__.py new file mode 100644 index 0000000..2a0e492 --- /dev/null +++ b/src/utils/dependencies/insightface/app/__init__.py @@ -0,0 +1,2 @@ +from .face_analysis import * +from .mask_renderer import * diff --git a/src/utils/dependencies/insightface/app/common.py b/src/utils/dependencies/insightface/app/common.py new file mode 100644 index 0000000..82ca987 --- /dev/null +++ b/src/utils/dependencies/insightface/app/common.py @@ -0,0 +1,49 @@ +import numpy as np +from numpy.linalg import norm as l2norm +#from easydict import EasyDict + +class Face(dict): + + def __init__(self, d=None, **kwargs): + if d is None: + d = {} + if kwargs: + d.update(**kwargs) + for k, v in d.items(): + setattr(self, k, v) + # Class attributes + #for k in self.__class__.__dict__.keys(): + # if not (k.startswith('__') and k.endswith('__')) and not k in ('update', 'pop'): + # setattr(self, k, getattr(self, k)) + + def __setattr__(self, name, value): + if isinstance(value, (list, tuple)): + value = [self.__class__(x) + if isinstance(x, dict) else x for x in value] + elif isinstance(value, dict) and not isinstance(value, self.__class__): + value = self.__class__(value) + super(Face, self).__setattr__(name, value) + super(Face, self).__setitem__(name, value) + + __setitem__ = __setattr__ + + def __getattr__(self, name): + return None + + @property + def embedding_norm(self): + if self.embedding is None: + return None + return l2norm(self.embedding) + + @property + def normed_embedding(self): + if self.embedding is None: + return None + return self.embedding / self.embedding_norm + + @property + def sex(self): + if self.gender is None: + return None + return 'M' if self.gender==1 else 'F' diff --git a/src/utils/dependencies/insightface/app/face_analysis.py b/src/utils/dependencies/insightface/app/face_analysis.py new file mode 100644 index 0000000..8ff366f --- /dev/null +++ b/src/utils/dependencies/insightface/app/face_analysis.py @@ -0,0 +1,108 @@ +# -*- coding: utf-8 -*- +# @Organization : insightface.ai +# @Author : Jia Guo +# @Time : 2021-05-04 +# @Function : + + +from __future__ import division + +import glob +import os.path as osp + +import numpy as np +import onnxruntime +from numpy.linalg import norm + +from ..model_zoo import model_zoo +from ..utils import DEFAULT_MP_NAME, ensure_available +from .common import Face + +__all__ = ['FaceAnalysis'] + +class FaceAnalysis: + def __init__(self, name=DEFAULT_MP_NAME, root='~/.insightface', allowed_modules=None, **kwargs): + onnxruntime.set_default_logger_severity(3) + self.models = {} + self.model_dir = ensure_available('models', name, root=root) + onnx_files = glob.glob(osp.join(self.model_dir, '*.onnx')) + onnx_files = sorted(onnx_files) + for onnx_file in onnx_files: + model = model_zoo.get_model(onnx_file, **kwargs) + if model is None: + print('model not recognized:', onnx_file) + elif allowed_modules is not None and model.taskname not in allowed_modules: + print('model ignore:', onnx_file, model.taskname) + del model + elif model.taskname not in self.models and (allowed_modules is None or model.taskname in allowed_modules): + # print('find model:', onnx_file, model.taskname, model.input_shape, model.input_mean, model.input_std) + self.models[model.taskname] = model + else: + print('duplicated model task type, ignore:', onnx_file, model.taskname) + del model + assert 'detection' in self.models + self.det_model = self.models['detection'] + + + def prepare(self, ctx_id, det_thresh=0.5, det_size=(640, 640)): + self.det_thresh = det_thresh + assert det_size is not None + # print('set det-size:', det_size) + self.det_size = det_size + for taskname, model in self.models.items(): + if taskname=='detection': + model.prepare(ctx_id, input_size=det_size, det_thresh=det_thresh) + else: + model.prepare(ctx_id) + + def get(self, img, max_num=0): + bboxes, kpss = self.det_model.detect(img, + max_num=max_num, + metric='default') + if bboxes.shape[0] == 0: + return [] + ret = [] + for i in range(bboxes.shape[0]): + bbox = bboxes[i, 0:4] + det_score = bboxes[i, 4] + kps = None + if kpss is not None: + kps = kpss[i] + face = Face(bbox=bbox, kps=kps, det_score=det_score) + for taskname, model in self.models.items(): + if taskname=='detection': + continue + model.get(img, face) + ret.append(face) + return ret + + def draw_on(self, img, faces): + import cv2 + dimg = img.copy() + for i in range(len(faces)): + face = faces[i] + box = face.bbox.astype(np.int) + color = (0, 0, 255) + cv2.rectangle(dimg, (box[0], box[1]), (box[2], box[3]), color, 2) + if face.kps is not None: + kps = face.kps.astype(np.int) + #print(landmark.shape) + for l in range(kps.shape[0]): + color = (0, 0, 255) + if l == 0 or l == 3: + color = (0, 255, 0) + cv2.circle(dimg, (kps[l][0], kps[l][1]), 1, color, + 2) + if face.gender is not None and face.age is not None: + cv2.putText(dimg,'%s,%d'%(face.sex,face.age), (box[0]-1, box[1]-4),cv2.FONT_HERSHEY_COMPLEX,0.7,(0,255,0),1) + + #for key, value in face.items(): + # if key.startswith('landmark_3d'): + # print(key, value.shape) + # print(value[0:10,:]) + # lmk = np.round(value).astype(np.int) + # for l in range(lmk.shape[0]): + # color = (255, 0, 0) + # cv2.circle(dimg, (lmk[l][0], lmk[l][1]), 1, color, + # 2) + return dimg diff --git a/src/utils/dependencies/insightface/app/mask_renderer.py b/src/utils/dependencies/insightface/app/mask_renderer.py new file mode 100644 index 0000000..2815f50 --- /dev/null +++ b/src/utils/dependencies/insightface/app/mask_renderer.py @@ -0,0 +1,232 @@ +import os, sys, datetime +import numpy as np +import os.path as osp +import albumentations as A +from albumentations.core.transforms_interface import ImageOnlyTransform +from .face_analysis import FaceAnalysis +from ..utils import get_model_dir +from ..thirdparty import face3d +from ..data import get_image as ins_get_image +from ..utils import DEFAULT_MP_NAME +import cv2 + +class MaskRenderer: + def __init__(self, name=DEFAULT_MP_NAME, root='~/.insightface', insfa=None): + #if insfa is None, enter render_only mode + self.mp_name = name + self.root = root + self.insfa = insfa + model_dir = get_model_dir(name, root) + bfm_file = osp.join(model_dir, 'BFM.mat') + assert osp.exists(bfm_file), 'should contains BFM.mat in your model directory' + self.bfm = face3d.morphable_model.MorphabelModel(bfm_file) + self.index_ind = self.bfm.kpt_ind + bfm_uv_file = osp.join(model_dir, 'BFM_UV.mat') + assert osp.exists(bfm_uv_file), 'should contains BFM_UV.mat in your model directory' + uv_coords = face3d.morphable_model.load.load_uv_coords(bfm_uv_file) + self.uv_size = (224,224) + self.mask_stxr = 0.1 + self.mask_styr = 0.33 + self.mask_etxr = 0.9 + self.mask_etyr = 0.7 + self.tex_h , self.tex_w, self.tex_c = self.uv_size[1] , self.uv_size[0],3 + texcoord = np.zeros_like(uv_coords) + texcoord[:, 0] = uv_coords[:, 0] * (self.tex_h - 1) + texcoord[:, 1] = uv_coords[:, 1] * (self.tex_w - 1) + texcoord[:, 1] = self.tex_w - texcoord[:, 1] - 1 + self.texcoord = np.hstack((texcoord, np.zeros((texcoord.shape[0], 1)))) + self.X_ind = self.bfm.kpt_ind + self.mask_image_names = ['mask_white', 'mask_blue', 'mask_black', 'mask_green'] + self.mask_aug_probs = [0.4, 0.4, 0.1, 0.1] + #self.mask_images = [] + #self.mask_images_rgb = [] + #for image_name in mask_image_names: + # mask_image = ins_get_image(image_name) + # self.mask_images.append(mask_image) + # mask_image_rgb = mask_image[:,:,::-1] + # self.mask_images_rgb.append(mask_image_rgb) + + + def prepare(self, ctx_id=0, det_thresh=0.5, det_size=(128, 128)): + self.pre_ctx_id = ctx_id + self.pre_det_thresh = det_thresh + self.pre_det_size = det_size + + def transform(self, shape3D, R): + s = 1.0 + shape3D[:2, :] = shape3D[:2, :] + shape3D = s * np.dot(R, shape3D) + return shape3D + + def preprocess(self, vertices, w, h): + R1 = face3d.mesh.transform.angle2matrix([0, 180, 180]) + t = np.array([-w // 2, -h // 2, 0]) + vertices = vertices.T + vertices += t + vertices = self.transform(vertices.T, R1).T + return vertices + + def project_to_2d(self,vertices,s,angles,t): + transformed_vertices = self.bfm.transform(vertices, s, angles, t) + projected_vertices = transformed_vertices.copy() # using stantard camera & orth projection + return projected_vertices[self.bfm.kpt_ind, :2] + + def params_to_vertices(self,params , H , W): + fitted_sp, fitted_ep, fitted_s, fitted_angles, fitted_t = params + fitted_vertices = self.bfm.generate_vertices(fitted_sp, fitted_ep) + transformed_vertices = self.bfm.transform(fitted_vertices, fitted_s, fitted_angles, + fitted_t) + transformed_vertices = self.preprocess(transformed_vertices.T, W, H) + image_vertices = face3d.mesh.transform.to_image(transformed_vertices, H, W) + return image_vertices + + def draw_lmk(self, face_image): + faces = self.insfa.get(face_image, max_num=1) + if len(faces)==0: + return face_image + return self.insfa.draw_on(face_image, faces) + + def build_params(self, face_image): + #landmark = self.if3d68_handler.get(face_image) + #if landmark is None: + # return None #face not found + if self.insfa is None: + self.insfa = FaceAnalysis(name=self.mp_name, root=self.root, allowed_modules=['detection', 'landmark_3d_68']) + self.insfa.prepare(ctx_id=self.pre_ctx_id, det_thresh=self.pre_det_thresh, det_size=self.pre_det_size) + + faces = self.insfa.get(face_image, max_num=1) + if len(faces)==0: + return None + landmark = faces[0].landmark_3d_68[:,:2] + fitted_sp, fitted_ep, fitted_s, fitted_angles, fitted_t = self.bfm.fit(landmark, self.X_ind, max_iter = 3) + return [fitted_sp, fitted_ep, fitted_s, fitted_angles, fitted_t] + + def generate_mask_uv(self,mask, positions): + uv_size = (self.uv_size[1], self.uv_size[0], 3) + h, w, c = uv_size + uv = np.zeros(shape=(self.uv_size[1],self.uv_size[0], 3), dtype=np.uint8) + stxr, styr = positions[0], positions[1] + etxr, etyr = positions[2], positions[3] + stx, sty = int(w * stxr), int(h * styr) + etx, ety = int(w * etxr), int(h * etyr) + height = ety - sty + width = etx - stx + mask = cv2.resize(mask, (width, height)) + uv[sty:ety, stx:etx] = mask + return uv + + def render_mask(self,face_image, mask_image, params, input_is_rgb=False, auto_blend = True, positions=[0.1, 0.33, 0.9, 0.7]): + if isinstance(mask_image, str): + to_rgb = True if input_is_rgb else False + mask_image = ins_get_image(mask_image, to_rgb=to_rgb) + uv_mask_image = self.generate_mask_uv(mask_image, positions) + h,w,c = face_image.shape + image_vertices = self.params_to_vertices(params ,h,w) + output = (1-face3d.mesh.render.render_texture(image_vertices, self.bfm.full_triangles , uv_mask_image, self.texcoord, self.bfm.full_triangles, h , w ))*255 + output = output.astype(np.uint8) + if auto_blend: + mask_bd = (output==255).astype(np.uint8) + final = face_image*mask_bd + (1-mask_bd)*output + return final + return output + + #def mask_augmentation(self, face_image, label, input_is_rgb=False, p=0.1): + # if np.random.random()0 + assert len(mask_names)==len(mask_probs) + self.mask_names = mask_names + self.mask_probs = mask_probs + self.h_low = h_low + self.h_high = h_high + #self.hlabel = None + + + def apply(self, image, hlabel, mask_name, h_pos, **params): + #print(params.keys()) + #hlabel = params.get('hlabel') + assert len(hlabel)==237 or len(hlabel)==235, 'make sure the rec dataset includes mask params' + if len(hlabel)==237: + if hlabel[1]<0.0: + return image + hlabel = hlabel[2:] + #print(len(hlabel)) + mask_params = self.renderer.decode_params(hlabel) + image = self.renderer.render_mask(image, mask_name, mask_params, input_is_rgb=True, positions=[0.1, h_pos, 0.9, 0.7]) + return image + + @property + def targets_as_params(self): + return ["image", "hlabel"] + + def get_params_dependent_on_targets(self, params): + hlabel = params['hlabel'] + mask_name = np.random.choice(self.mask_names, p=self.mask_probs) + h_pos = np.random.uniform(self.h_low, self.h_high) + return {'hlabel': hlabel, 'mask_name': mask_name, 'h_pos': h_pos} + + def get_transform_init_args_names(self): + #return ("hlabel", 'mask_names', 'mask_probs', 'h_low', 'h_high') + return ('mask_names', 'mask_probs', 'h_low', 'h_high') + + +if __name__ == "__main__": + tool = MaskRenderer('antelope') + tool.prepare(det_size=(128,128)) + image = cv2.imread("Tom_Hanks_54745.png") + params = tool.build_params(image) + #out = tool.draw_lmk(image) + #cv2.imwrite('output_lmk.jpg', out) + #mask_image = cv2.imread("masks/mask1.jpg") + #mask_image = cv2.imread("masks/black-mask.png") + #mask_image = cv2.imread("masks/mask2.jpg") + mask_out = tool.render_mask(image, 'mask_blue', params)# use single thread to test the time cost + + cv2.imwrite('output_mask.jpg', mask_out) + + diff --git a/src/utils/dependencies/insightface/commands/__init__.py b/src/utils/dependencies/insightface/commands/__init__.py new file mode 100644 index 0000000..7fedaa0 --- /dev/null +++ b/src/utils/dependencies/insightface/commands/__init__.py @@ -0,0 +1,13 @@ +from abc import ABC, abstractmethod +from argparse import ArgumentParser + + +class BaseInsightFaceCLICommand(ABC): + @staticmethod + @abstractmethod + def register_subcommand(parser: ArgumentParser): + raise NotImplementedError() + + @abstractmethod + def run(self): + raise NotImplementedError() diff --git a/src/utils/dependencies/insightface/commands/insightface_cli.py b/src/utils/dependencies/insightface/commands/insightface_cli.py new file mode 100644 index 0000000..b8adbef --- /dev/null +++ b/src/utils/dependencies/insightface/commands/insightface_cli.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python + +from argparse import ArgumentParser + +from .model_download import ModelDownloadCommand +from .rec_add_mask_param import RecAddMaskParamCommand + +def main(): + parser = ArgumentParser("InsightFace CLI tool", usage="insightface-cli []") + commands_parser = parser.add_subparsers(help="insightface-cli command-line helpers") + + # Register commands + ModelDownloadCommand.register_subcommand(commands_parser) + RecAddMaskParamCommand.register_subcommand(commands_parser) + + args = parser.parse_args() + + if not hasattr(args, "func"): + parser.print_help() + exit(1) + + # Run + service = args.func(args) + service.run() + + +if __name__ == "__main__": + main() + diff --git a/src/utils/dependencies/insightface/commands/model_download.py b/src/utils/dependencies/insightface/commands/model_download.py new file mode 100644 index 0000000..c5a14a3 --- /dev/null +++ b/src/utils/dependencies/insightface/commands/model_download.py @@ -0,0 +1,36 @@ +from argparse import ArgumentParser + +from . import BaseInsightFaceCLICommand +import os +import os.path as osp +import zipfile +import glob +from ..utils import download + + +def model_download_command_factory(args): + return ModelDownloadCommand(args.model, args.root, args.force) + + +class ModelDownloadCommand(BaseInsightFaceCLICommand): + #_url_format = '{repo_url}models/{file_name}.zip' + @staticmethod + def register_subcommand(parser: ArgumentParser): + download_parser = parser.add_parser("model.download") + download_parser.add_argument( + "--root", type=str, default='~/.insightface', help="Path to location to store the models" + ) + download_parser.add_argument( + "--force", action="store_true", help="Force the model to be download even if already in root-dir" + ) + download_parser.add_argument("model", type=str, help="Name of the model to download") + download_parser.set_defaults(func=model_download_command_factory) + + def __init__(self, model: str, root: str, force: bool): + self._model = model + self._root = root + self._force = force + + def run(self): + download('models', self._model, force=self._force, root=self._root) + diff --git a/src/utils/dependencies/insightface/commands/rec_add_mask_param.py b/src/utils/dependencies/insightface/commands/rec_add_mask_param.py new file mode 100644 index 0000000..b00ee0b --- /dev/null +++ b/src/utils/dependencies/insightface/commands/rec_add_mask_param.py @@ -0,0 +1,94 @@ + +import numbers +import os +from argparse import ArgumentParser, Namespace + +import mxnet as mx +import numpy as np + +from ..app import MaskRenderer +from ..data.rec_builder import RecBuilder +from . import BaseInsightFaceCLICommand + + +def rec_add_mask_param_command_factory(args: Namespace): + + return RecAddMaskParamCommand( + args.input, args.output + ) + + +class RecAddMaskParamCommand(BaseInsightFaceCLICommand): + @staticmethod + def register_subcommand(parser: ArgumentParser): + _parser = parser.add_parser("rec.addmaskparam") + _parser.add_argument("input", type=str, help="input rec") + _parser.add_argument("output", type=str, help="output rec, with mask param") + _parser.set_defaults(func=rec_add_mask_param_command_factory) + + def __init__( + self, + input: str, + output: str, + ): + self._input = input + self._output = output + + + def run(self): + tool = MaskRenderer() + tool.prepare(ctx_id=0, det_size=(128,128)) + root_dir = self._input + path_imgrec = os.path.join(root_dir, 'train.rec') + path_imgidx = os.path.join(root_dir, 'train.idx') + imgrec = mx.recordio.MXIndexedRecordIO(path_imgidx, path_imgrec, 'r') + save_path = self._output + wrec=RecBuilder(path=save_path) + s = imgrec.read_idx(0) + header, _ = mx.recordio.unpack(s) + if header.flag > 0: + if len(header.label)==2: + imgidx = np.array(range(1, int(header.label[0]))) + else: + imgidx = np.array(list(self.imgrec.keys)) + else: + imgidx = np.array(list(self.imgrec.keys)) + stat = [0, 0] + print('total:', len(imgidx)) + for iid, idx in enumerate(imgidx): + #if iid==500000: + # break + if iid%1000==0: + print('processing:', iid) + s = imgrec.read_idx(idx) + header, img = mx.recordio.unpack(s) + label = header.label + if not isinstance(label, numbers.Number): + label = label[0] + sample = mx.image.imdecode(img).asnumpy() + bgr = sample[:,:,::-1] + params = tool.build_params(bgr) + #if iid<10: + # mask_out = tool.render_mask(bgr, 'mask_blue', params) + # cv2.imwrite('maskout_%d.jpg'%iid, mask_out) + stat[1] += 1 + if params is None: + wlabel = [label] + [-1.0]*236 + stat[0] += 1 + else: + #print(0, params[0].shape, params[0].dtype) + #print(1, params[1].shape, params[1].dtype) + #print(2, params[2]) + #print(3, len(params[3]), params[3][0].__class__) + #print(4, params[4].shape, params[4].dtype) + mask_label = tool.encode_params(params) + wlabel = [label, 0.0]+mask_label # 237 including idlabel, total mask params size is 235 + if iid==0: + print('param size:', len(mask_label), len(wlabel), label) + assert len(wlabel)==237 + wrec.add_image(img, wlabel) + #print(len(params)) + + wrec.close() + print('finished on', self._output, ', failed:', stat[0]) + diff --git a/src/utils/dependencies/insightface/data/__init__.py b/src/utils/dependencies/insightface/data/__init__.py new file mode 100644 index 0000000..665c59e --- /dev/null +++ b/src/utils/dependencies/insightface/data/__init__.py @@ -0,0 +1,2 @@ +from .image import get_image +from .pickle_object import get_object diff --git a/src/utils/dependencies/insightface/data/image.py b/src/utils/dependencies/insightface/data/image.py new file mode 100644 index 0000000..6d32c4b --- /dev/null +++ b/src/utils/dependencies/insightface/data/image.py @@ -0,0 +1,27 @@ +import cv2 +import os +import os.path as osp +from pathlib import Path + +class ImageCache: + data = {} + +def get_image(name, to_rgb=False): + key = (name, to_rgb) + if key in ImageCache.data: + return ImageCache.data[key] + images_dir = osp.join(Path(__file__).parent.absolute(), 'images') + ext_names = ['.jpg', '.png', '.jpeg'] + image_file = None + for ext_name in ext_names: + _image_file = osp.join(images_dir, "%s%s"%(name, ext_name)) + if osp.exists(_image_file): + image_file = _image_file + break + assert image_file is not None, '%s not found'%name + img = cv2.imread(image_file) + if to_rgb: + img = img[:,:,::-1] + ImageCache.data[key] = img + return img + diff --git a/src/utils/dependencies/insightface/data/images/Tom_Hanks_54745.png b/src/utils/dependencies/insightface/data/images/Tom_Hanks_54745.png new file mode 100644 index 0000000000000000000000000000000000000000..906315d13fa29bb3a5ded3e162592f2c7f041b23 GIT binary patch literal 12123 zcmW++by$-R7p1!;MmLNOX^;jP(vqX4M~6rwA>ByFsL_bT0HwPGM3{(lIYLxGI{e<> zx93^>^TzIb@45G!a}y2po{|zV5Mf|okV3T7jeu{T|K0>xz$YZyfeHA+4}j=u;BR9R z;_%9vT<=z3V6b68)K!dwiV-D{bQZJof4`d!3dX%&ZGRg%p)T4~=Q1*Xuj)7$&1{L& z0JocC+H%Z`oTj1DPcrkYIS=OMi|&1U>LYy`#rzD&|ZGuntRN9RMLB*UUf91c35I28&H zsUkLlF1038|5;gdQbj@qIJd>7xoF0@uo?*!N^@}cq}EWOaI_dJP@%w4F=#+Z6{U*B zg_<^)IOya$HJLUn98|e|G#89!)5_ZY`!_(YtU46_U>k>{~Zc;bS^jN@1R40%Lreft&E>0DsTK zA{Pad4EJnvm+@96;t4%T(C*Y)kVxC%f+SVE|2pg3#szV1vuInE7;9WQ(yXM!Q9&3H z4vWtD)7F5KxFFRFbzd@Lf=kt^xgav2aWT3MsE|X7xE~VQv~*-heR5IE6jzRvf@EnU zhUys|KCXF{qAhY&j$p_sRln@OZqF2Y61-JU1s4691>1+yy#A|Ek;8MjqvK+CsiN%3 z-OWvm2qVR-X1r$O3P1BE)9d(F^DM5f(0uT8D+~#x#vLyZ>U_=D)$A`kcNW;)yX?V6 z;i$oD%un+Uh;as?vl+j+djksAfT}m_Z7;r{j$m>^nuBkb&JljXue`@Aa`1j{;LMmq-gtG~JPy~x}b z&P1TB&(!r_dV1YCtQ$(YqYPa9An=#p2)`R}Z| zY2&sW#p%<>lShGM+_x&_yIm<ofe+RMVzWz)>)@VDI6Jb_rKtVHoy&mKix!N|fl@(of%>JxJ#86;QKEG4-|UT7t-^jIA=Pe$=<63PS_=Umth}Tc z)d}BF;0$_5J)h#whPtEAf(xsOuv-OV=(D*B=FnOphSUjXFr@0MHhx2DCyThWzI^$& zh5R<3R+XZe7GcO|dBS4j_~a~Xw70jnGtSvgK`fko{_o%UT+)+`zNo<2l37O)?2Ce`x>;Ph&vy#E+t~#%Y#ALGQZ;*RY@19C9w$`*B|)vhG+vzTL{FQDdtuR9 zH7`?9T!EjX%=R=Q5-75b@XIxAM5~o>az$6feMqj;^qzQ{15GlzrZQcBOErcJb#B#U zDhgEl(fN1K@L!pHr)3W*%O=wvCQS?y9C`n0RaF!@$l^hr(a|DqpWb2fMRh96W{%7U ziFmXNMqWva9{EGru|Z9p!27$D0+CZeH@e4-A2w6Oc6~U5%R@d=6EOa3d0_OgvRU^O!Oz4#ZL7|4{f| zB0Ye8bbj+|tvh=%wg_HY%EHQ8X-Pqec-xm48FpK~5_p~V0} zr{H0@sAk2Q7bmw01qmLuAUj^YV;?;D%=4K!5BMnV^_=r#iL#IG8S=Udla5#(rFu2B z)&{&IZl!4QJj1kz&^O^^iuPpCCotb_q@_l}w1EC;L1 zVmbhzsf`dX(X)3{XHj-;D$%Q9Q_0V}1vzX6mh|9wf9tkJy0X?}9Y6)GIfZ@x8H zrp4(C31-uwXC74ceT}h zBv9|O#`>WCN%%2hQ$lwkqJIO1ytugV5uR;xQ!MRGNGL5Od>P&tD?$@icZ{cn6+?Yu zC+&`8_~l=U&Zq__h4iK!G%p=#J;|m1;(9dA)3{q)Q&j%pho3-nCI@X@wwVA!ofBDNfgBR}ZFeAjxk; z!6@&Xh=@c>yGRah34a(??yypG;Dvigf>oLYr-xu~R_cacGkiOL`@kLn03? zd)k135st4!wLJo>^WD)$oKak`yt)`;ni=JYbqt^l>&BK zi;%E$ks7@ZzEznQBBzXyfId<|cOj%#?o=|v-&a=DgkWIumzX=2lPZ!$ zy27#BcgYeY(+(rBTZ{>9K|Rm6Mijd>9mWtl1r7VA-mvS_kY1kdGh3B4D#1`Gm0&ZP zPSqjW#`kbt;9NUwQ8Z{K&@^blL&|=I3*z%+o~4*j(7Ji)IFQk3DC^FnbA@OWXI|aRv|IcplpzL^;<5aENunf`U#!ErCzJhbgYb{z z7Jxqwd)8)oygoV#m51_Bux4WeBz8^KO{Q9; zf`l#rT;EOjQeE~W&JEF#=S(S6nF`im;jMqwzAF##OdJj*d*h{_{x+bt&@e|F*;E`i zzsbL!+&g40Amoz@ZK9AS zn5ufaea{c#s6JT}5qs!+9&&H^B?LiV$Gyp>uI@yWWprNW-;!dhP0l!nob6q=%NHzX@0)+`6 zh0o;YAMMid`>V0ZN#n$RJ$i{`oXUR)Gmhw7e)^%AtG|z>ouyWF5rfyYjVkY2U+})6 zo#ltea>B_@IR&**eZ5pg|Kh3uvsnWTRehRJhQA_w&bdvM>X*#3w{u%$_OL82HwlJD z1E%qsni@Nv=<+vat?xYp!<Y669q{^ss$feB@|WuXPNINtv%RY9%aj zshpp+Kf@97eX(hBB|~3-*;tFaqp>eI1VSt0B#9BPiL5qWW{Vl&tcS`AB^`>nhxU)(@nc3a!mG)+$3 zD4%K`DI&txr!rqendUcHGKM`#O|fW~JA}}wb^>3Z42Rlcr8qG(dCJ7+U)cJ;b`P~h zQ5!T|s2?7khh%Z7C(M%&t!?>wVcq%%vrBS19-biowAQ2e-KbcD&Pu0dor%X9g8!o4 zoEDmTfE>nl#C}$UH8pN-j0c}^l{D%bgi49u8^_Sik?%ITkzn0&WWep9^ULVcmJ>wrubAZhl6RuLkgIyGfsoxWe+2tC-{F_5fqZm zhTtfA^VXspqs!h2yN+(rdC`FHjV?;T+%|9j|i#D{S)yULLS9U26zy&$9TggzQ z)5gM|akrlg#VtO;_Kq?QN%Ys7Hd=h!HrA7+S%UJb9|NUo?wnlx`6HU%Ye-+$_gbnPIK|@Al2wUpDhrLbi)+5_FXfsf*nzHMrE}*?pfXSVxQZ^e0N+Mt z&CF=zd3(ElgD~&}@C^5i=&H(~$R>HqfVeQ_wU|)nq(|VJOXoX#~NkTPJCL5ZkP5swi5*>RY04ZEu@&p<}nPZUv^th zB_~&GI*Jy+q;F&iUJsSlPiV!L+0dA^L|DBEiQ2OO&5po;*{HIza^AIl*`s=aPg2CY z=Opgr#Vb0kk0Pi1jbq70;7E1;d_^`%qwaUG1V+BF6ZetYZh@W&o3^UmXwDaWSEAqKw#>3@8H`+QyhbgrdagTdjN}_L7xGH zu|!W_UmtxYt617$@~7FW^XO5-H*HLCXI%ik3$b&!jd0+Y+BudkIkgeFstewl**D>Y zWWmSWpEAYp{*7z@Io{t-xLR-&2ULWyd~gyO85y+cE8(DO(3{OEBoqYf*;V>>NkKQ=eZmOWsuFIS>%6|^P7v8e7M z-QUtFVqpV=t7K(TY?wWc2Ez$u3zWgA^($GtngfZizMrRU#5K3Yqfe@xE1m!^H*Hus z2IP&v?wLEa1Dnt1w#`efE*eVe9qs6ytE-?7RuQL@ytd)zImnCMT^vk~A?2CxgM*l9 z3K8)fsZ5Mmqdti0s(662ug#!szx$A<0ae;yt=2}Y&j|v z6rTYOt9i)GD~=Zvg@+%_22l8KOaj*4+VZ8uXj%=iq8a0Xt(kPioBcn3d_+OOOdf#9 zTr{nm*IH;_I0)!o18B#RZRA=BDg4&injCgNp!a}^(ND=bQ3z`Xv8kozWJ4WSwPT5~ zv5FL+$E8fY*9YqN=M@QFG7f6sp1Or2J_m zhOc>_4X|7Ip*&U>$&3zf*6zF?_cY&M=F0Q z{NkaA=fbBaJ8Vh;DUuMZ^U_u?9UZ`-hFCoDH$eGFFwkhIDAAYDe}zs}wp{%&>$UOj zT$zsP^%X(DZ*g!KPZU%HImClpMX!!pJg**+Mw}|;k~ivWq{lhSy{|y7^*6Dn-(u{ z_v0h_o40ZR9mZTxu0*eY7CfgN~6)FeJl$ z&*1eW7|x(r{;ct^XSXEt@VjeK6fs}Z7tt(o!Of?K{SvSPCG*E#F@u{|SD-YtIu#kt zI)G|K9)Cw3Ej0tmp*BLbW%1yEZ=Odk?|sx8YPFcon|npm39aX5rD))=VREIraixd( zgMf$M{~o+QSg|lO-|s(FDx7f!Xz8o|+qL`KOQoCrO6m2Wor~j@D$5SF+7+CaHh!b{ zXNn)fRN;y7u-HlMLeUIsjJIN923%4pVg!l?^tJ8gf@$gL{a4$`^R59Q|GnfuBx5@# zulmkPEIYm4*k3i+-X8*|oZdSHYEOnqG3+Yi$E$6OS`Vf$uN4@w5t*tPBWD9;+icz0 zaqv3b9E{m`xabrC82Qe4I*_k90%m=ey}$2oH~vKc0efflAzE&>_2+Df{O_JKGJ1wK z1nHc^w=Cw%@L>O3PvR+h8uB+;L!=0?Z(8rHT%H{l=dg)I$VK;<3;L{|Se--z5x09x zG7P`l_vm6etAhcfqfHdGz&kiK-{MP$q{a7+D9 z!mi%iG^cA;?)e2DeQmO7ewt0>4jC3q`}$0z7my@_$%8TMO+|2@$vDM z^ZV<)p@49h>JN}2%8t)Nx2x`r*kgbe6X~B|W)sXkccyf=MLt5b9&vjd6BBbCrU)YW z1ssE(EdiqE=NH`ta`2Ie8c@8uYgU*&8+*j0{aWAQQ&JR#4@+}s+UJSU{&qHr>DD}( z5H}enqo|RlKV>4;9|LYLJSEf+M!{Qe=vbbF#HwRoEl7kPHFf@Xoy(2Le$$5Y+xzCe z8zM92%9^hV)8fiqhpz;VUA=qHX_H(5yvm#YzlZ{)J&^K-is>v*wvp`MrJG-Vi4wC7 zMXNl^qYh7fa022wy>JR$Emhg?CC5Ng8p^2paV*;yJyAA{xQKpzw?r{#Z|`)9$@O)X zv!1|X2Is@69035&6<7qiwsHUl7$AqBxP(~oCK-Gl$@p=0JseM-x~MVl@X6|%P`qh} z6+`HnDJnX=&l6gjSC&*yecAf3uggS2V#s5y+4IO6U|T-y0)To_hpDpHf=jAY;{RW_ zWOG0EkaEz+b$0WV(}xF;qE@(<4H7Z5=T-;6?1d;yPn^ z08Cdq(+J^wGyW$t@LP+vUC@6)T%M@rI-I>#F##iD8 z&yvutUbN?=d@UL!eJ4~{>i?|`MWTp~Tjw$Q`n@Lg@yDMZ-_Hu86dZO;zQlf0mG z^|XFHwDM~d-Q_6<+dRfX9@*{}ht@lF1b1cpcs}GhK=+xI7DJk>0^|_TmK@m4tU-A~ zuvwK8{+PqfPcz=GaqIKw3o$0LsHX!#!kD;p8kh~OwX52?+3CYk1&v}JWST#iXg>uz zeMA#BQ%#fC9ILB8xakwrhrxQcm0re5TnrCRIs)ES`>#Q*S&J5S+A)w?`wS?CS*=*5 z%pi%^ls^YBrGWAG?v2%sEgPxw<#pI>#482i3;?x?$TOPS^Y?cxmZ((b9G>jp9?!|! z7a`%4{i;5HaP3WOz!^kO-el+%1~ww0V$+lrM_`MbDk0T*5PR zDnSzp9CJs3oQojLdZNGcR@*i8c0O4g9~1FmD&3GW4>tMFBQBw2sGYlw3ic_VKAgP! z`($r>r%oxOt_cT2YV}^QHcwYY^|4O^P6 z^HR6TqFK(j`tl>^59sBVN) zUz+u0NLvkb;R1kOy&4Pu4&RAC&0Ph24x9_;ix3Ue-P^anv~(nL7d z2p(1#^neai!7UYzmw1o7%xQ*lwPUhuhV&}R%8H=_UcOB*|3Xf;gXw;pJ(c+dH-wH< zg|8K59w)|g($V%=6IVd~(LsCWs@09}=5urN=|_``BDBPQ6B>pFT0=;%#aj`2x4*B2 z^&>jSyE8swmGC}Vp15eh@#>(jjU9o*%WgJY+RJ`?N&N(8T-Nmz1u-!(QSb{VMH2*o z&!Q}qLK>HdJE!N?Q zFyWx}mSL(e!EP@7k3Bg*)=O||cybYs-MMEJR3YeHwaavzIXMeu!^E|Dvm|3%*p;am zPCClJh&nTQj_(pL_M@Lk7LT|Kstx8E{yvWI=W?_zUMXR<8g7(J86**rbv^KNQ#(zw5*V}NUhJ_Ed=oDI z#;xvB*Zyt<^eEUmVlzoqPAkX+S}yK=1kJa0UjU5Osq8h>)m|W?D6GM07V_or;+ld!Y5OUFzb!OT6p?8%6(_BhTwOnOR$q%5izp*hMCP zW`sXEw`o>pPSfTUqF&1bdP$AuraJ}(Ire|M00@nd26Mc?$gM8_G=oQ8`*xxj9xtW< znl6jwsuIrJkL}?P5qFosP~^T&Vo^@5kZ$p&Tkv9(xhZcX{v?Brf4De(h_-}8-qO&T zUTDSWHzB`m=+!)i&mm_QL27>mGfMHbWZ`oKA3FSJoZA2pTv&L{Ihd#1VFQ?h;spj; z<#1QK%=bwQ198!Z)T!eR;J(bj799r7Glj_i9%2~hm+(^mI@QUMXJ4Hx%Va(ARqicc ze?s*{e@a~v(C&JirH@Oou+W4c;w!QXk%`puWjE;t1eBAVaZ~MmNk1J-p>M=VKrbq- zR3pR|H+Oq2)B-hlQaET-U+ zkl+qW(PCtqaz-WYb3P<13@{a8WdL;uQ&f_b9VCG++YFKuU#b5+s8nAnf94lg_LXrA z^j_jE$A!vWYK2EtsrX9_9$TI0gpV%6VT$-tTN9SPIyC=w`i*F(iwyYh_vbkqdu}!j zOwGu;U`L^8wv4B~$jYjM^F=nKGk_j9<-4lZ7IC(Rb%!K3{S4= zB8mEpKn2*aAG4iZ_pEsVqks3ZM}-)5Lmh}i00le02S#BcuMv>4_`tBEIQs%!kkC#D zBvA%Yjz345_P$5|Nj;nBSnWji-22uT1P3K^%Y+a?7Ec7#haa|B>AQjDuX%*03I7K;FkCU#xtFz z{~jUdr+4VQRGG#|s2c_RG9-RXO_xjXnDCW&i3*8G`pK3~_Z9+rp`}5{VR6&L3>$!}a zAdt77+Tr^8`slB^kNpJ!FbmJSk3qFBs;3{%`S%@Foy^Fj)#WXaA8d)+M{kK7QQbM`$ql{5>S5R13*!dwU>!`Ns@7ljFg!-vQi2@e-y~IrKLJ6SW`m*2f->Z(K z@UM!J0Jnt$-m44)&CXO+4E+E$}|SzpwwruH{Ck$F5lhc+IoQzE^bOb@J3WD!?X(1j7jFdt-Z0VE0;J zcau{T#woCdvy_;CXU8a;fcPSlHanrMs^U#G)rTqg*z*glAbjW=G|<1IVQOR8VDzZ{ z6X(1-6z!D4K0zI{r;bzfVRCYkup6V%R3I#J^(p6C42EXMyc+fXq?c5Ya>0yq3~AM3 z{I@JWK!0Qpp?W63Dz38s9fbWmPkijqw))gs$U&z8RgvT^3ZkeuFMx^=2A*#}Spj?Q zK2w5v)pQ#@=hbJ6ab+~Ac=NLcvxtHyO5ZKANUw(GnqdQAce>M=o$NBjMb&PdD=2M> z+C(Ojc(vT5SfYD*vu2x@t!ifMEzyw=XYeslmtvlFsN>nbU=?bo~fk_v(bW zR2+Pxc#^hr5)^j%%NlJ}vtS>(B%#Zy7$yTE5hYVN0l2ha>5z-euLXT2q!Iamw!8HQ zJzYM;!k{QXYh=>W)6y1~r7f48|LGfFf52H&tQF(UO(XiO6ZmJIKSby>8Z$~8(C}7{ z{r;n-%YKB=vul2+vO(YM2SA4bDUb|5O=kf%)7S`X!cH^@lRj2uR$4nq$a9+TcpEdNNwF8!3;kIB#pRVAMv?9zS)1m!hU=aV9>sDTqNyn z(;b*<#Rp^0h-1FPvKa%N4dS!f$rY23G8p!wu|fHTD2)N>RtKCtx-v32y$Rt}@hu72 z`7pg=IkJqRqU}4*?(KaeI*zl<I^ub|c3AdTFiul`rdjf0?oPE16AY!~5OWxsucxCzHHzu2ZC4>LDzN(D8+1g8_~C z4hlAK<)MWG|B_$clLKGtq~4B&&RYJ|{&{`ZD2=7D_3<^npSQfW0|^fn=ex4Csi$<9 z=|4lU2SysAh=IilKtsl~{3~S;|7iM0fkm!v&GWvk!LX}QXm>98e$VZ%?zhFUHVs70 zotY)w9DD(!j?anE;XaT05-Sp{=#y0ptFsW)F543eju1jTVtW zDxKn7mAKK9S0&DZ-S_5@xms19R=7>`(wR5o1h_{Ba_z9Na{BJG4xM_lnLXb~@93Ju zn89Uvz|#?_Q=0D;U|?6Tkj^-reElFm*!pAaltU+t)KuB05$Llm&X!$;Ib>oc;iK4x z9oBy`45<>}on$-k8;8;5_bpj6xy)0=T&a9M4%!&6H83 z{k6B$)45N8JkMaBl;^d4%<-UUJg0fVTE07yK*T8*AEOnS$}g!9t)r-^s*q@ARFYkN z0RMM~Rz4JoqR=y9V5ob}kCR0(?+0qiYR_7dRZsw=7y_nJS4dftaWhB>@@mi^`tZf6 z{4f01nzx$-Vdl$TvTr$@Gn6o&d&vD8Ef?h4(zzO*;C!*j>&Odu{o(CscnlGLH%C+Od4ojMP(1)qSRh(^G3QV<1BGx zFuO`FFprD9<09zKC?$VD#K~upf2X1{6+k<}wMgA5how%>rG_K~VF)97vUpbr6PKs> z^Ws{$MQtui()KA+_FLk-F8;HNQt2_*&ZN1>K71OBxk#eGaL~3wAyu9b*DeA&2~lI) zllbG&zp>=16opujLTIzSZYBn@nAIsBe;qP90)|rqq1LhwewCjZ`0o zh(!!88`&q4!Zg^j*4i+0+^=bK{L_L2TC&U)wHpq2IL&ErPp{E%?C|$W`P$(ol9yBO z`}($B2oZFpXwp&1$h~Z%oUKREFzROo65nowO%ls)LVuai;H;B~6F~4+r>o`XpDF6qPBNWu{i8xDY&O=H<)U_YipK3_* z78trWd0EF2;Z;_x)9%`tzovvT%2)CQIeZFI-~sQQCAVhj8Enj?M_CZAHCXez8Sx6$ zd{}zk>mNHZ8BT}%Mx=vl)MoMG+cEypWRgHRaY~Hnw&EZgm((KbhSpKXS%~vseUM6v z@pt@FAt>j3v%cc>F3>~1mRU{0PYMP)AB;P%(cm*Yo2dkK;)h?!B7L>~j#rL^zE>re zx?=+kKM7~O9*3=eMwmv|zmK)o8YmuOgcX(xDrh*xjA7TY8q!#0i-23X5FO+wcZ=Nn zJ(0*3s?hW*k$G)(&6+YriGQb_y{9FbQ5K=5A>su`&h}Hpa_U3t9{C zx>wzGaE1_W+NmGdH?mWF=yl8%~wL0MU}rEF~_U4fA~!Nk7rjE Ttb&1Uc?^h#p87jgyXgM`<&#U{ literal 0 HcmV?d00001 diff --git a/src/utils/dependencies/insightface/data/images/mask_black.jpg b/src/utils/dependencies/insightface/data/images/mask_black.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0eab0df555c23f1e033537fe39f3c0c8303dd369 GIT binary patch literal 21308 zcmeFYXIN9+);1c70*Z7*ln&D5q4yS=H0d3sNEbory+lN%N<=_9k)l+kS!t0PsSzO} zQUZh`K}rZQ1d{MAefQq)IoCOV&hN8FuGQBXYmPC;yvIG~TsirEvIJr?H#Rc{(a?ZE zroaz$vJ7&$8XM>j0$Eyuq(LAMBZ!uU14IYx(EvYCS|Eu2?>-154s1any5}_id-XZ( zzpv7Kcux24ebC0A8&8&*9^Zk-y3{f&D+H#u2NWc;sZfg>G}e-$z&CPp?!Nj4-rKu$qJLqkqpQBG0uAK;FEBI52wdd2>8H$wE^ z8jSoRe8K}mBLhS33jNXODg#L4^ z=@9O9H{woULd`jaR6Psi8}Rw`p{6u=TBfteu@jY3SH#P6j}N0FgXJ^H=^p1~5okdYV(9(+rGEXU+mQ z^s|9z=zw!{^rz_=PSZ1z}V6(-7%B9v>uU1_J(D&{SJ zzBhc*@Tu~B#$|iG%RW3RdwCI6Hb!l!IB^G6-~7nFn_nMPUkF{1xT@yY?if{5(Eo6M z$~gKS#>C104bvIki;_~(>KdA+X6DW=uGa%@1>TN{jf;PjmY$LMHV$EWAq9QTQ}QB;wp@Crl|;P^xWnv} zQ*6X?D-B!EGkB}m?@eC5*=w{Mj^nxSqZ%rH)#0f`)mOlI7yjCz1{h*&0+{0H^v4)q zKmR}WL_|hK|FP*_>Vt>>V^>~&!T*?6UGp#F+S=dz%f7z;e_J^9ZxdHA|1xs_KUU6x z3_%Qkg_(hYnVp%LnVp9n5FP=ZKO!I|@K?nCC0G86;vZ4}kDLHXXqcFoSkAHVo;$~@ zB`GYa_5WE;et?+i{<@DH2(H?(T&Fyj%#WEakAKnc`1sv-@%RgBAR3%IMi+X}e7 zy!$4U|M5_&dKb!QRc@=$;B&kDt#MIP&A63$qi@5zZ02p1vyW}xOy5yClaU>mS!Cz+ zuH^BBDNgP;7Rq<*IUAI*j|1Bz#$lUV)BC0O zDW!{=(XSMMQchj01)i$rd?O;^G?iVh`EJV8Dc!>8TT#iJB?m`I`%jHhmv7%@oxj

&P`%q)iAn7n5DtGnFNR6MRh@XM6lcK+aSYS!I!yrdpT}F{{nXma< zkpKsypLaB?B_q4v`WAOjA+@h8Or!%!5Nq*(O+B==d&$%>q?p}x6 zeeYnV>T6Mqd#7weRn+fU@>;G#X)=}HmxQMHTs*}Uc)I%LEnZ84z>Pum8}8P0xmLe| zWJHyTTyM|b*W-9)I+|(GAf;GWGg9@m9>w{_$HE|TDf-8oD-MCFRzKeSlALI2ZsM0Gi z%C+P?BNBL;z2=NU=*x_Ubx&nzTKvU(OT;n*L$m$*A|)goHZ!y9YRm~njaP5kEIFe# z9?vLE;klab_bO=S6>wkVG0Q-`6o2>Q&A_)QZVe@Vg@#B=3k!#zsCQqcT9kNgtsL0O z6>K%7y(5)}>gJq^N{Y?vz0@T$%`ubVNf2Rkhcl-(q>~U(oD|+?rl|qBR_`ApUQYBMoYBozAOVt;lq@3!?xfR|9 zKE841hE?6e+ZOc>k{eb6YPR%#l zu4b8TRg(13(% zR+_)eJ!L84T+bVytE8O$q3+>0OL)DwSx^Vw(-1%M@ZPjb{0)y6-&x9s*C0nfj9_Ef6S z(%#VIMP!olW|GR}K~Kp+PvKW=$-$IK?d?nlu;%85dqR-AyQL<~M#ll0bUq&4zYx2l9Sgr_1g$m zB6?jNyY&0zOGBYSL&05y9U+vnZ1D>Ng#cSW?TG4c*!ZeH1lw&MCy~Ja1er8u6Wpl3 zOGuMbZ~6JPfVGzWjxDg!C1}}q^ZymCK=R*rO{0YeBDSsr(q1{Ti-WHW~5XEX@gXK4@i(_~aciL%xQZAgbQSRt|ix5vl zO=5q#pRKOkHuy=1l>MtZ2g;K*xPpuA@{nW0#da|0{p9DTtA4&+yYSo6C86+eFsj+P z@OaNr@JT{}#%c*QM6SE`7;D@3E%nj5E)3}gm&3o^w!v=ws6?&)&r73Ng|Grvm8$~! ze@;ZPRIcvFX?B%+SiOF+>S~wuEj{7MQM8Fu(|{@f%6qD@{16nrhwEv(**cYZN#S4l$2zJA@^253cL_v3h+0cmVR%~&Sj zG+T&vTF#zw1cq|0xFEDiid>#3F)-`An)N}{9OV+wxQ*T6lQAI&j&l_5$PS77Da@Wfy-z>}A5}BhPCzCe;K`Ygzu*FpY%t9U z=uOSvBY<`PUyf)%r@^$86*$lFAb62y8y-SnI7UtjzCTK(Y+zaEDEh~cI`ATdjIsE*G#{dpwvdN6aL9?s6Z(7q8$TUCt}O>E=Ny z&NJ&b>agcB4vf{8D1;5ee*Z*nMUnZF*W7hC1iJ@ui7vaiV+5RKUXY>xJwxwaBLA(! z=)>Pjg9(Yc%g6HxWZm6Cvew>i?_PijaFsVvcZqNe6NDq)^9+9L{y=$MkeH1AkWA6t zWtpyxPx^5Jsy_kEO`d?>H&UBBYgv9MQOO7KzYhQqg`5Abn=)x^R5<}9yMrUFiTxA^ zRuJo(gIcbQXgg5@=!k=UNFrX!F%`MH~<*bRDPLeZ}D#D*PJI13n=P2C} z^kc!nN68_c1Rg4R`FOP%ja^E(bpjgRH9@==>>R{VLsA=GT$tS32D}9Lt9D`K zutzTI?+QbV=i;7PLwk1j?m^Ug_l^r9kKb-v%MncaceZ+K3q2ZefNqr?t=jG6?zfm9 z@C4{$EuK$zm-S=+jy(y>(Ck~g1VMEPq|C5>6Kp-|{|$CYMs6j4CVSEx!hu-4vI6@} zMQlq@;H}4IfEB-zzk0qY+)n%R148Nq6n6yM1=|B*1?i?(wKmEDr=r1v2cA18AQuSG zKT=}*GiyNmM}U43(8oMW!wwQw(6{vpOUbQl?cJMXTgC~=>)G54z4zpK%cn0(|4yA? zVa~l7=U>l%)wob^o`9U^V1kF9Ea3jenurq+OEU>R>A43(<&j~7GZgUGV?pRa&+Za% z-z-@Wd+d4t5PbCn1T>kw%O*!Rz{k5MAfM6`(AO3C@wpSwFU1oO!MTV;v;f1Xz$I(y zRyGxK+|~XIRY=KvN!huTSc>Z|alL==Svw+G4!2I+ zA(SO=4#7zF7>1ISD;f1i+z6=&lMS5n)Vl~C>zHh6)2BieY+TnzrOqLUsy~wIQ5Uk4 z=C$%MxAh4u=IME6P`PM=` z6Rha^=M?C|YQCh4u#V6;y(l*8mV9lkxR+bo6lpSIRq4K@?ESm{-X>I*UPVYm3T57w@t@?t{T$C zwm58^zqz57HdFfk;!@TdC~8Bb4a)EKJxVYpix7FaQX;lvtza3>Q&>PByphpD55rbN z*J8Dwfd#Z=VejJOs?^Rmkcm41rHK1T9;)_(+QrW^ z2~&TG2%%Aju$|4KMAvKQ;A?lL^#Ym8$`nsQ2q%> z#~!gY4n{gbkZOr1ptYo!<4y%C54wUpJ)?%mqFT;EQ7}X)`VVT9g^-cNIBN4#!h63H zPz7WiN%WQ@DW8DO&LbC2KqAMbXl??EA?HZ@yC{he1NPWLlekYn8}L$bB%10V8#Y7z z=14*Bz1BdID||}3uC27xvM3#Q;im$Q+O$if5#;HDZ;YRSbmd5R2oykdnA(^iDH6boAgaKXxnq373L)Vm1nH1- z2p>l_MC=m6O9gGQNH9DGa{?-a;Y+(A`@5tCfF!K}T7szY-H_xUBw=MkP9WF}F?bl9 z-0+#HCgSn~Sj^z{#1(6Ov z!H0_s_?1+k`c6O+;k$y(YUIQ2jT6w_O)8iA2}qnwIqF(Old!FX1me-hgi=8ql;})8 z0mYDZ-jhji1XOTuv>n_@HOcBp-fc!5zrqocsJjrNoIPad1oV(VdWDC4?%Bny{K6BH zu7=Wr3aRqU9~9gMx3Yw-2kFz&Hc;T0!)`>3Mm6AAH8R;%>!|w#q(+v5p*tyINuDsO z=Y9~C3lEM4lK{=lGo?t-FbbOVM0~B30XE!)Ca$KJE^tizp4w0_su3 zM96thd?U~%wg?dT0u(=p#&>QU;yj&H<(%P>6p!7W*Az4uegZlTSvx)f0T2m20r7xU z!AKrBKG>Qxm_$kFgs*zM$FFz6vu1FRpd;&r-Gu|ppnSm2^0&(m8;LH(hcJO(f;1`1 zRX6AFdZi}cp0G=V^OV_XQ5HQ>`&;8&14(hMK14wM13%V7D8AtgG{Fbl$b1Z6>Z;xQ z9_2$78O-8OZb|^|NZ%#KnN&2zP|t&bSWMfDLnOt*DK3!4Q|39r=Pz&Uj;C%RqFI#_ zlOQqW1=apZZi3}$)dNJga4TQx73^d37fi+Or<@>YA;Et0xU_$lkQ4Ci&bD5>d&9>4ZN4E z?VLUaJG!njgTZEjN06S4?UY0KYFrlp8}6-J)Cg)b3B1>tw0Hu_f;q0gm?g${xwZ3v z_W>3W#o8z{MnUh(7$O%)WY2xbs>=yT8(1p9&d8k}2+u>UE^^!lV{7aNN@MY^3Bm82 z1k%B9nW|QJMBSy!$2A=vRUWQu;S3pczABE?+UqRvyhs#`w%-hW)@{9zj@TI+NZyTf z&XD>2fw9A~jQs?p@$sl8Z#Jx57LLKXCAoKWtIau2kSv#-BET{I1V17%*?F-C;ye+K zD9<>?`HX6RFGxc!SYKfc8HZKeO-NdFBYXbIz&u3wQpdGivS)9!prt0^nut3i(L!M8 zu!C-Ey*gR#1SDsT3WG$m5G@kSaqx0j*!*n zCm6M01(5NOEUodi z_T8O&LDVj+69xcwIJiLq)=9nU8j&DF^84)x0nm&HKlFH2ioqN<6!pI!d{9nh_ix!i z?|dqW18OI6BVjz#4!8b<DK#pYeFV1z1URyH0m|kPe06<8a5w5bh?s4^;1vZJs8bKNYRE z-o~QMiDE_M4VwB8*I&XBnFA2klGXX1PWX%61*%-~jz=Km50#kx4rEhLyyq@8<^-e# zCFwXLF(?vJcNbve8lz~^TVNXp#1KpcM-{~BBmrJ=4v08_ zIOommkm6dxWkd|hL+;hY`oRzgCU&28O)!4T~|R}iFk9)f<^)Ll8CMLgQa#1kQiMyk&DPzRT6@^=^AUwl!C zZ3!(&F5h?3N-qIeCD$nc;I=B5w1R+l&#?lTE+p&-sKs|`f7hzL-ZFwfGml0ZQ(A>g2>e#+C+)fYt*w$rt zFqXPC76ZA4?mY4c;^T7zd=Kdq+yJU-kqUOcwnhHKcaltIvZ&UC1Pt~VqN)vZZr8UQ$;RM#B@X?+(%NPrAC4VX|plN0cX8#7tFuu`<3 zvu+oqPQ?PeA~(r6f(P>Zhyp|p zkfw*>p3d`tKef?n3lJo^3qI%!hLM}V$n_C#Fw)WE0;Pb@1nn#p7D@2Zhn2fnXuE@UGIt*t9|ZoXkxvcIHy zc>^8zfF2AF38Pym1wwHS)D~+*5x8iFB4C65c1&FxXDS0us$B)f7Y&YF+$71 z@z>VJZForF6%Cb$1Fh_`$Ts}ViouG+8!{h zbn%UTSzj$zv6Go-T$>60dd*FG`$xb!!7@;>__+P+E`vaD14Q6%Mbi7&Zp&FXklJ;1 zw*ZisgJdlLNJBX4ww5C^Cco=4*&1J;Y-X}ZzIxklShS9Cv;JJaGXgaQiG-2it5awo z=r%Hrh>1t*8%H0hyN8gWuKBD{2o$JAf?y+&XwCkIH-fQU$el;H9Xa^IGI3=CwY#u2 zLtZ@rm7jo0;~-;jK}s#|s0p^A2Eh*!j`8;JnXFx+H60d_6xYp8Z~~7=NnDD;El3Fq zVypdiZ#~I)7fFyj>M>a}&wg2dP69ffA6j=|vvsHUy!ssd0Djy+m(Oiu{JuA2A5lpC zzDjnH5V&Re6$ zef@lh>}xAl*m=8vnG)Tb=qf|_>j^|C!hqGATd=fvP(f+JhoqVchlSBmtRt+S=ixA(Gm$>oN|oZEES8R zvX;mJ9n7!5m|7k&3UdhQJOO>OySF=oq}q?O5Kll-l0y|gbmZbE$#*|`QUWNRa*Z%T zB6Tt3KzogPeCa0yT8d&Fr7XlILI~FT0AB!ONY8^l*^LZN$!Xkgglf9EFI zoYiO!_~r|XICjeDON3FMiQCz%3aF6pX=qQ%OZu)-U$g>^l-ZMzlf5YRqdfZmJHDxZ>@+A;p zn&5#{Rj&g6#P?^|>c`%h2Yi2G9aP}HZle?>apSx5b@|5S#R=Ufsh{o?axW@f3~+Y# zy64#Qkal zxl@6K^PlzPN@eS0?=tTHF>Lf_ zP?QbX4};2_fVSR24tW7u6#`JY6VPfha~qNhJptW$53sbcQ7{QiX&--wrdk81PC)yt z2pCo4kX4ZCDM)2J0pSmUb3kOwdj4m46&Op}hf*a@Kp8OVv>;gt&;qn*GcW~s{5SDG zqgHJFhC|s@Qmr9g)_;}X+pB;CE?LTP(SVek(r3NG8YL)^IyUv{r}{`y9)BnG%7ebx z^q}nOeTvS>R4zE1Z%Q(by{4XGw&oI2c`CQl%_> zkW2Y?$E`0d@X+bH7P`eficy7f835EmOw}d zD4eF8fX?d`$w>zAg^lOY3S&AV7Pr3;|r_X z<~1Q!lb3XN}*15NLfrUnH-ghaOGqnI|feeL9I?e zk%~_q2VAbFVtpk*xJBD^GoO#Q%~thrq=wU6`?|CwMV`2;2Gsi zdxp)fg_h#-gXJOH2L>FgiDU@hc6qObBJop?d2Z2XbCdB@YmJR0$HF*&JdmYr9o8Wz z8Fv4;yDo=xSzU-j2M|ec!!ZKhxl~Utt!Z(*UTha10bQ{BG%7s0T=RKxeukqO@)!qr>$+ z;enSHMBLlR%xo5~pF3o!P?7jKKAUv;E1+I*)HS0T?Wfi#+8w&w?OJUfRVLbAMJxVC zzf{9SL)9bD4GLP?eaUqS=Ee+>ymUX*2{torEFU9wGY3kaB?`cYT7|u`E{~N*51<}= zO4k}*X_pX_!w^*rPV-f!eQ2Q+~eKJdW| zR;#av=mw^HQ0ZKOvt03}L2GSH0s(B1CMstiiN#ru**qHl=52Mf`dZ(Klc&1ik<@3a zQyMIc8bsTBy-a>S#a3$BGG>vHBPPJqjkfEpJ()P>V$~#N79aZ(E?i4Q{=k0CbBV?w z4Gjjxn){5Y0b3;mjg1Z=5DQ~jt<7le3^tAFv>ZLD<4u)Y;YyQwM}=;(OqQD|ZjGVm zZXbR1n%ycp`lY@n8=GPJLgTfM-;t>pQd_u>ZiedA`4cdq0^usTAH+gq~$`Xi5Q z-_Eb4moIiROyJ#k>P(vM&JUAfQ&x{H4(1RurOo2dv)W=y5d{J_6W192*NBw)a9aC>Yw;=!zHGbgvJZY{-#e@g zeq?8C|NTK*WTQ|RPR<16qOMhU*=FyXhe&ugExW%(g2lG2S}h;5|A#D@1XUJR|2I$V zRCx+=G%%U;G(stCLSMS3Y%^Gxxr(fHnQ~TcweqCZuH(c?OcZd)oub%lDN4H?-t-?R z)74AYqz37F+4)s#9(ZSKQCyo2A5*#SYDXWtnqEuk9H~#)O@(y3TI5e0L!9g~QgSGs zTm~leFE}om>h$DHr(WNNUUr%FPF^gf1;HK|MU2y$^^{|BVw-ts45v0qA4o73wi8Xf zV_vJ4I6bh2HA=B2C6KC~MQ#@3Zt4}SAQxC^oG~r<*$Yn1VpBUFl%0g|I^`KX#eA`Rigvy?dIxk zq^-W!@E82ew&!{+Yo8t)3l@kO=<$hezOfVV;M?EnHDI>bD7>L}-zYeJ`q<&Q#uK4W zZ}i-{{PUYQ)YFeX7}Q+(YF+x=p57KQ>EM&}U{fIIynz8wB#kyJVHpjbZ)VrXIMcB( zucNq{N9GEBn_2#rXs>Mn{`9_SQ=i9X17_~694$3R*JwX~5@VVqj)QI+T>f=%=MhLK z&GVnyGs}6ahd+X^d`SpNFq&MH_(pj9FcmjM{?7eWbV~OMeVBmlm7V&g(GbQZE8Htysx_8aijPgcxoSQ!!b_Fa~}LnjG%#9 zX!Pl8(B$OkZo{~os+!CF6V`}9jr2ty1)jG-T~Eif1^BMY6GdWS4MNOkM4_V#TqYJ~ zPZ3bZO6IPjvuG#23_ig(em25hwa0#rGU2;NYkgOsc$Dky9a+TDSH``5a)IesnLCuw z;2@zn`@5wrpLhG9!{ehpRQtPk)7VarMoY@QGrSo{D(V)E+3K1lZL97ZUzCQ>qO?k_ z6k`fF)lRg=;%*V;2r|*3!IP zHz$#*Gc$m*&3*~Oqm zo=%q*AUSO8Cp8Gvh?<}t*XjTU?bKby+GkYg=)DVE9#v-)nKP!fCiqfeba zW1Q3?X0XPhTbH68x!T;hDw14{try7AMs}vnAsg z*9-NaJulhx_9+Y}hujrY{tUfrs`X6Xy5BG5$>)ju3x~t$#hpxNa|cX1dvSRi*!#5{ zVJD!smn(E(S@ec!d^Vr4uRW4@Z~A;%*3`W{(q0e$GWy|KcA;FHty5Td;*nxMV{7m1 zQIm3EKiti;d2V}fEgg1;pwGNKQbrutkE2@}#rF9yt@Q5<1seY7(-$7wBqEjd(RRO+ zw}yMgA$j_y%ZoT%z}XyDO5NRrq4HO1wdz%#(_m8skt6 z5tGqpag5q>ri8)VK3B8(#3t9-`xumVSfqd6NQAgG!IDWTg3otXqaZtzF@!}Yagv5M z^@-4!PF(P9kXL>BKuZ|jw(4nz=M{vrCPFsuWyEWUas%j!VGXpjj0Xo^FDz6cs-ByxpC`3nNP}WA+jkxnt1R zw&e80CA5Brw_VYGa*z~eW5x%U)mX_e>d**idj00%e8kSL{?vY`gPOvA@{HbSnU>uJ zp8YC)eOSR6U)OYM){}!n94=ZZiB!+Iv>%4^@#$#?>hCE`0=jUHK?0gwUO$F_GYrjQ zs%zCY0%Z&mgrH9cL^lVA>IE#l2>3&#-Z*0-N{p$sAwpw4g-$p&s7%XHF(q1q zaa~-z*fodabRJ7A#i8Uhx4cl^hyG^eaOsP@qk>8HTy7wrN3`BTF3B=?S>-=!9<{7a z^WMB%yPr5q(=u!dmXn)sG4t&3!DM}!7~ogOWQi@GQW>F4&T1PU#IN)T@o(JNdCGX0 zcH2e6Ukv>=&E8Mx?HR~cL1CJP@StyS1!mKW&yba&Fq*HaBGz^D$1n)SFW3{Dk|rJi z&*}~3i;Y~?c3I-JcZTBy!YfnYwgr0R5@B7_0GFAO#!fQi+KW{8? z`>ecW{^l&+Fw>4p&j_QDTG8crYUF1{U^43XbJTC{p`7^2I}z3ejW zhN`av4Y4`?V=59euO*jGZ#3ie}7^t}Ge3ibnPbiFahw>VfbUCR5zN zrw2Xwgibb=u_>0M-E(VW%xjAfT3ePxt(yr~PfTuF(b&IBl^*wqjlmiB%wvz5uOr>2 zr5T1hiOLmkmZk(di!8}7m0}4NOw!pRI>IY{Z&F<(QySU?RUOY>j}n3H<_#$0h#B2|iqcM^l4dMbnYDTk9F-;8f+js^uEc_~Fgcnt4XA(7=WeZ?$4|An-9 zx)Ebu`-Rs^pCt?@F;GXHHFx#9kOto8_v6AV$!|tKWf!Nzv?p^1x4u+Q0Kl>PUnCWe$G3EOl_@w9lhtnj8s*qn=nm}g{``O{noeV`qUR@~~1?sL( z#>T+H1HQeun&^$V!6zTU%@uJ~?9my+u<>HA3|y|QoaB&q0IG;Dndgyw9^T1bACJnu zZ&4wU=rKW$$ZmIJw9(qkZ#KEIbS*t2G>Kd<8SPs!hn4oU+-u%ybEGQfnv}DM z52ZBr_1`YacN_2+hwg6Zzy9w zVD;5vllNW(TFu!*3m=E8z010gk`XZlDQ)Nyev$P6p)`MZ*uo{8z)!woz_n3W3@z~% zDopcC@Mct6n>}tbeei+*GDC%SSH4XSyMV}}7d~($pZk4;^*s}-32LBl=SE$Q9Q`95 z_DX@#ZDd8*9QBeQ-Kb9%AaKE;-POIM(wH3Pr)>uJ9dy3mnb7?J=K#D=;_ zW16o2w6f`cmSZp*Kz*Nm?Fs-+$`3s636}l(1v~ zg_}V=utsrZe9VXi8-?PED)scPdmGR2v)D3M(-p?$k$6kmbOb;BZpSZeQoF8uvLrz$ zPx&|BeGR$X;)}l3Y1v4X#oHHd?ZwnW7MSR#?k#2Hmh}Fk{i`gFR41yPlb!Y0v@4n# z++ciJ0+u*7xGPoed!B(JGpw&Wk<|7EL0pVC63f6~0GZ_&gl?$OUC|PZV=p z&CtWUXHRoeoRg6hT*G0@BYapn_g(AKoUoKf*g1PvF(Sv_b-pedYos|dvZ!7Ri;XZ)AV_U ze==Nd{bPz~*)TgIGlN;VUi;~WDo4(m8)7DFa+u>ZTtZsijq(lQz}$NJtKj_`X$@b9O!P1E#c^`Pz&vsmbI~2;{s(`a^LXLx>=jbWTf& z;Lemf6o!wykg<&0x4owwww`pF3_x*Z5y|}n*Tv6)#ONeexGmJ=S$R8uNC9fj3GP4IZv%5uF+NZWuJhqeW$t2{H+L&r?mC? zE$c>Yl*+aukYgWR=s*9$;ogPDPMdC^8&0Q`>p|@)j%QQoXpDkjXoshHY1K-TdsF%B zVv-JF-;$!tFG~47kVbM2w=glM=CP7qMd-^&d|1U$9Bjn*&x}BzSr=$OAr*RjgDa=U z^yhKo7wMwCNS6$rR?6t3OP;3fg$>)%4KBbWmR(lGiJuF#*00 z($Fuxq^m3W#en%|MO;Uk*jAn&R?g)rn_KFBDf9iy2U9D-d{K)qU@qejqZ>R*>+Y2~M1J;@xjCiH4ZCF7nk&cb z%{C{t-2^pbiQYn?zj1>W3XdZ3>)9FeaVCS`_@ZkAGqiRG^<2EDce|>`$%{tsw8BnsJ9C*V*!3c`+%a^%_Z9 zvkS!z_&XL`WbCD9o797YjMLd~aZi|q@sIdMN^ zaj^gmDF%~u6$!CDSdM`5^7J-vbTo{O17%*E{S7FxbY!!FlJ(BWrYnMatNQzf}e zLqx^*qzqUBe;Z5+>gmfY#&@R~=d&HiCX9!Hwx z0WmvTaRmv8!-Wu6zND!lCj1(%a8l|6=GDlgPOWZC{qrR$?N}o42e*xJ$HzHcG94Fk z$S7&nyaA%A^8u-eQ(W-n=NLG8XUR(#*}U-8msNmzSH^@7>3PY@B%^nnRM&7pKTmY^ zL%)1kK;dZYJ&ATO@Hf$kGFay4XFzWlm@3Z@?r|#_$m5)Zbv++e)Es3%1wol1+hWGr zJxScM>Ktj%yRQGtF2^S;R;&9U{1aUmACS8e9ex(hMU*rvw(z&3*kTz)ZH$u;x+zgi zmo_^Wze;H)ipI}jzI1X-!44+PPp=7?E3$}|>@hG)raub!5oYT5rO?Ssfidp{6mLjp zQ2Z=^Aeo=vtLNM5W_ z#0)H2%*R@XI^*Qya$l*xBZI@`k(FA*YHgw%MAau5}xh75_|s=VQsi*xa5 zf5~*{{~^1AQ}Ou5TJPX@^Qul}g{W6S}0d z7Wd;vK!!ps(I$x=iWNMN7h-yt=2K~|8y%l35x)4NrdMVH`1LE=F$23_H&bX@;kTO* zWiVAUCJ1Zf=B`Vklgs!4vf?iNM0{Xb#2~Z0l}S4Js}~;0yP{FYI1Bs<;R`UioqmCI z3Fk_i2o2noe5B$Zn@@ZT8X(T(vdTn~h9 zhQi;&xGvsj8UUMF@87;Rrp*Yw&`5Lt_xYrw=bt4MTbZ^N3JqNpMAxdkos*Pi&WB1} zUaN&?o!jM;NMFgI4_nqAGUlGnw{c>%}LxFL)Bnla(=&s?dZOw$e7B? zje&c(txRb?+APxv1JU@ytT*%@{mxDRGhsH`5Bi@(TwW5beX<#++u-Kb`4)p)@5?1f#!(h!F^Iu?t$uhPtKiiUMX#4(>u zaNW}Os~nZ6lrgJs%LDY>s?7dj3-rqyLKEGZo8ut!SZTH$f8Yb{wMVBfEPt|(O~%}H zWRuezVP0>c%?Rt=C`qqnor{mo&=ZqZpjmBF&*)kmbMXQh#HZ(ku!`DCWS%)MP8%+| z=qf)Wek~OD$wVnZM)3(GprL=5IoW-BHKPJjSrFMjqPwtmuR;P2ZeY8{8xggh?G&ex zB<-DVIJX^B9F+}xp3v~LGHjz_Q{kn?!AeKQg?&=V*yZJY+<=|_V<0&$*Ucz2u80RJ z-fOOj1K82^LY=X&@r+M5KXYi0$L2lqSM}M*lDpRxZ+Afl1_qyxYn3s~70eXlSF~E& zsTtji1UqqxJqmi3=vR1oVgl}%2iipBlbwuq;IKiz{^A9wy`*_?ftJd6ovF$}y}Y`4 z{mqy-ZrDFZ71Cjm#0!{;+akv1%*sAFfvI$iE1bv#GyQpM4rMbopRYPo{MnmeR|Dnn z+<9vSzEiY%wX9A9&Vdb`xqMD;@q(Xe0a1cY)D8>rb*8q7$KSUp@1API*Y2Z)OV1{j{t zvn-{WN=klRKC4?al4>MVzMI#gTu+*7nuhOI-pt%M| z)y9w`DCPBZ2Tlf_R;G~1XR7|I1}5oOQ`7E<=dr7}B>ejS0Cz~ef_UzK74QfE%MvvF z&`D6jZZXLJ08~OGSc>Lh7DEYe2Y+$JR}y?95$=ps7lcXa^=2?$Madl=sFL#$jP=Za zoY-J60Efr^P$$tdoIuI+AF89yC^_d%szhN_Vc4-U5s6_)H_%4!x`M=wG}q7IGw!Io zf?LOegHUpmlT-0DAx!dE~QIHaOE z!|H-&94F77>SQyBCZ`DO#6v^^1PlU1i>Z+L8wOdIQJ%3pQ~m~HPNF!VP9(re@%XC4 z&!ktV$e2lfGKF|cT=zNgWFlJ;FXJe{7zp3`RuDltZgcpFq#{v=TJmO4mZQkgwOczpTsR-tu7{0F)4)dpP^g&B3e*ip!kwUTVA!SoQZ~=8M+qoc{oy{g_Db?Vn%$ zxQ<|r2a{wSQ5=}jjHXzD?u#i&B(bNW$`ZtJ;r8v~d5;H8>(zP(jw3fY+F>vg)AhCp zc;1UX=)@3nI!D3o$sSZq;?~07GiSLUep>iT)$vyb6uVRQL5P~LNd1J*g zE6hE8P>MspU#Tuxjh;X9x&<#hklqXS=+3M~*Boixcvg=ZoRw=i|o}Bldkxc&iYZhtEAwL`R9`FU?Ob zamzhLMiN}*+~=C~m(&>)pnMoP=bCI5alQR*lm{4&B0bg#2T9^b)>YvFSdJs^ zkh0+u#OI8xkSQbte{>Z=&t6ZAs|3b)=jB*b;WF(Kd6`M?KNJ(ji893OLK%SasApTf zzLlYjgtAf@wKiOD7GG5sAbaowo@mpYJYO7Dm}&>XJkJykfrEp5R{%U1Vm|iZnx2Ny zl4&AjiRQ;Jo&?DGo?2{)Kro{{%*4-h8Ys{)C=q@V&P4bCIKXis#~)PWQb{8-@PGEs z0IOk$4nH&rL^fHB9CO8C@^lFi9K`dKM2C}jYUL0ii^Z8e4*7mEppqtF^mDZ1P<1$; zjH(ed72-a->Y+48E$8DYxZu(M0LL^5m=78L3bIll#5kx0O$(&@paQ^?89n_}B`MA) z==!NZ6dni;&${r`P4<7NpbAT1;07V831QhEioxTI`FMGvl^qa_GZt_MoZ~f))TkiB zPnG=Aa~XyXs|z|Q6$wApI7hVNL_%?5%s?X>$3Ij>0Ixk6#S|YrcF;pC6Cci1BnPmO z_hz7h+-J0ZUlV5_^}~m{B?v$-gQ_eCFp5Nw5S%4^cUCC`L4--~#e!eKKMIKO2BIW; zv&zBVAU$r_NIil?uT#yO@QRrS#?}*gNaX#~G8|P&XB1TI(ee}YlyRVrOmY5oLtFw! zXUUvZaDv2j4-b_Fta!PXcZ?%%ruKMrJ;!yU62(puS%#XkIpex>RcL$2EaxPB{&G@| zJa@-GxEhcnZr1o`GkkBzWC z1jo1L%)l`Sjq%M^2@mnKfW_tTpNj$;i5Vk#{6UwlIr*_6*~A^sn;H`&J`uTtFm>6N z3P59hM;uj-kJ0lrsIwb9k;Mhm(C5!KFssZj98sj9>kpdHCqBi=F*DU-f&({N86*?0 z{Vu{2ClmF}@PWrz_gchLB7d&75QqnggA%GC&;2O1nC1K~R#l&GZ}hVGURmGD%ewqE z`nw|*@YDOFa&t10XVuOa`XvX&24eT8#bk5xX~jzvoM_g?pzHCtdPW#yqQ#knlEz5P VVn>NjzJFOvl65=JpMS2~|Jlz7LHPgx literal 0 HcmV?d00001 diff --git a/src/utils/dependencies/insightface/data/images/mask_blue.jpg b/src/utils/dependencies/insightface/data/images/mask_blue.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f71336b9a0d3038ebd84e6995ebfbe54946fcbb4 GIT binary patch literal 44728 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 literal 0 HcmV?d00001 diff --git a/src/utils/dependencies/insightface/data/images/mask_green.jpg b/src/utils/dependencies/insightface/data/images/mask_green.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ac2ad55f4fc580c915dfa4c157ca3bfc84e453f4 GIT binary patch literal 6116 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 AxBvhE literal 0 HcmV?d00001 diff --git a/src/utils/dependencies/insightface/data/images/mask_white.jpg b/src/utils/dependencies/insightface/data/images/mask_white.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2148ab2d09fdee6e3f59315470e98ecfc54339e4 GIT binary patch literal 78905 zcmbq)c|4Tg+weUGgG9C>W1k{awrU1r{e~$~L_%3+kg|=juY*W64MP-7LnT`wOO}w) zVr&^9WY^GOEE!v5dFT6lpXc{`pZEFa{k-q_eD0a+oa;K*xvq1c``qVR?!CdiN$`!c zVcwnqfI_JPd;kCl0MZ~H0K|ckIF}xX3*hDa6FJx6|7?HAfdLTrf6x?ialrqC{WzU8 zIrO3&G?{aG-}#5;0|!#mBPU-4s0XzVZ$^~$9dUKE(KrZATSW`nI zDGdVfa)##Sumn_d~hD>oF;1@%>QV!z2)s^>hI$p9QZFn+feTy z^opzIgH@yA+M*a^3XCzAwqyN$VH?b+F z)BiwN`Q!d4mka*EK{x)B^l$OJeS$m!|1F#y&f}k^f0G#7{5Q0*&A(9>+-`XU2mCkm zKTZE8v2gRl`22eW6#(7-+UgDgey3_2|> zV2~ofB?1DAfc8ECavV8%{^9+Px|})}n45L19sGMP=37>YCcRcOO1}`rJZmZENr8?fce0F!+6F@&{vT`X_T{c5a!y zvbwgu@q2UYZ@oYO_+L}@k7oaeULqX5xVX8&+>pQZ0&#`@t+)s`kAfzzsPQF;8&*tF zD~?axg!HVunO{lU=9h$f;8%fzFrCRG%YUo(ADaE&DHi|#q}jg|`?p?0fFKyexp`m_ zz!2D-+LiY`!;JK`!$T*au3k+mWkOf;(x&^xvu}KawpC4l(m#eU30|b^b(gy~kMrvS z4BSKu*QSIhiD_Mr&ifcrWtF@8)$fw=)Tm(;luVA19qHzcW_>C?4D-q`S2fmq z%qXNAH2m?bOzbRI()(*k9bcBVsq%sna=>V<722Q2PSDR6-*-4;#35>v&V!O-5g7WR z5{~Q9BzYc^5KaD~_8#t%yovo;EVz&;K8!Vvl zdT@e7vrVDFX^5Y`FNv-dBCvYQsKN}MOUr_8ynEIq=UO;-2==JNRU;}lH1!Z!cE?ce z6W6UQjQxjlIZa8))mh7xLw<%S`Fgw88@D3u)oWHz0TU=0x zJo!6}QXqh%;c!#*A2e%^8vtEuzNI~YRivn0Uu99Z znT)u;sU*MFY%r?A^>)68mm1RC!fU0Aeg>aiuyy#WG|RWe^1*AAGC;XA04aEXtkNkd zm8KMUyNCu+BW?fYaQYVir?Lj0(7r$j!k{!n{%1m$Y{ zQFJs6%8WO^j-26Q8D{1wJ_`)spGsV)p){HWMpJbLyWg9u#NK_;UU?=kf71t5#B z8CuuX>a~~4rTK3hns-_^YI2N7H_2i-EvgQpT|IsaIGktw4XpvKBv_ z5luKk{cr%AKv*Hfapoacpccy8>h^RG(4311Ro>qEc0b5I@btkM@k-e`Bxny%O#9K} z1`SNyEZ`;+cm|E2jQ6p^rrDJ@n-xyj)tGk3Uugw()Q`M8w354=3G#I|NYiHWN;&SuQ zXqUzq4SC0y%G&z*x(#d|c>KGC%9Tj3Bz4^hG-(D!?=RCT$!p!U<+_~6d_ZKJM+q~EzGjjHTE0Zm% z4|B;Gen6MjrhKrBCcUYQVbd($Ay{KA^<54IUG#SwTwDCOT;zK~sXjWM*GN*$Uy|`& z!%5$(uqC1!>{{b#ss!A75#pqj+hq()?82EkKYZ8YD^N_Yv}^He3oYTua-w(TSVNEW zjZ1j5?<*(37zPmko&H`3u~yt`j^*pj?9?U$x#Wnr+3os!Ku{t3!kcrPnT}hV$XQ_# z(VY~pt&f|L(KoLuQuHucqzsoA2XNcO(QOy%`AYB zvwc(3et6;))Vrut63zQp1j#}O@E*`-!BwfvFRoK-(w-Xxi1KO^HMd-GJ;jm(em_rO z+z}txx@5{|qoHnpM%3M?cyf{lx_R147_rXUyc7(I6Mx8A8TF6AFkY~X7SO!3Jp)#F zk5p!6qvnZ(^~S?(N<%gN4K+6jH> zEhr_~_hWZzZe|Z5t`%VYniU05n-W zZT@CbB!y_RZg-7gtlG%aaawjEAA@0!Uii=#rI#NFSsMiLS*yN)ztcpEoY1kpM` zo3;mBCy`tDm#DP9ExDJD+0w}^-ybeG>;5tx?RE{F$ab1}|HWVYvz7;qTlT@o>TJr? z4X(6KHYTLSTILSS3qDI@SkjijuE~#os1pf?a(Yt=PX$VnhqEjrFQ?WajnQ%Rn5Txe zeGc~qzlfD>|B2esrkMW>pNetz#2=FdwayMz{!BjsDFUzP?*S)pgAv)o_m0*cd3f+- zhJapTo6@s+VS|EUoz6RGe?g^ApBL!9H97jPnMk~#r=DF(t};0|*)G9%4!$9WGhj7aol@Q_6Ai$>zoqVM?kHUem!N~JojR$jKz$ONc% z0z{!u1(N3usfWBy6T}EwOsus;>;XA8`<>qPPKVpbbf)=@;w{u01F!=lqT#a^Lzq;V z9?_S(9#U{-fsE!#EM-D`I(y-TblyX<*CT)2Xg!v`2RI#|ZVLa*lA_sMP3didq7Ckp z;v8{~BQUjN5Pz^t!X!_(wbh{rhWO`{D3Y$QS1i>D1k^EU5S_=6JgQqL@lq-G^qnJ+t4&;W-nL=bYJ~U zf2~IQ%whqzrrb%>dGkryxi6X0-zDs?Udz-P2`_D8X_6N_c4xL+84{H-o+&=P@rrhe z+O0!*OeiSFJurItv*+`DsgB2_NaaoOT$B+K#Tdz%c;N7sJVokZy@i{eNpad()8~!= z?0D0u;WqK^V|6H)`6ImK9>B-kHh5oGs`i)IPT>baXW>O=IuWJMj>PU>2zD&Z?Q|!+ z@sK-qk=Gay`o0H<_4WedCr({3J9Wg*N__j{O}2)WHa>zeu2^JRG}^xFl^rrsw7<(5 zA}_mb7g=!e^?3;!xJ_X64t&8*6kpmcP0X_O*Nc6&km$&Wughqq3p{dr2y1QoUdR;M>Y8eHSzj4l=21?`w zCJ$a{HsU5v{UNVz&;Gie%va+qI_*GC4OgCK$TQ*ee!TAer-2^o!&3m+djG~|0#V!R}TU!$L0HqxIquTfTRZfU21{|Q2^Z^=ys2M|npoqjz;7$tc zuG5aAK3<#oY`BUvEQ8uw1?JGTwW)2@Ka9%d$mMD&rfp!(0hFQ*tH1HFWBsncdlQ*2 zE3%Iz;d_8VhWJJ<%}WHOeP(OpQdN^}s|;c(ea9*i{d??Mx;RvAsGM zAy<}9+ns;%QRzUuj%?FuVQZ^BAR}Dd@wTBy&0XUYPSdc6nCqWn$&t#RZiOwLSY(j) z2`ZZ=JiSx)hRLEyFciDg&YJu@UL25&TG5J7p%pUn4V8=zoY%Ua6h2OHGllM_$)lI$ zSH{J^yQOy=M_g43)>C@$^**R|LNMpLuF%_?KR+%w)H+g?yke*yau7rUM$U#bbv3q2?h!T`O`$7^JGxF||-ofYiBlhvvtxDG+! zGJAlC1=RbkeVbc6(IgK%en=k$KO zJId#N#kHg^fR91Ib_wu=@TR;I`LruHGU1Q!rm=gh%IbX0Qk65#u7vjhGMQ3K?t}R|G@I%(_0pH(s z^H_{3NZX5K2)?3Bq_;8BiBFM#e(=E#jPPcOo1tKd&CQ4@rc^VFfV2Eq71!|wCA_#C z9~j{W-*v_f=zsfj+gN0@1D)QCpea3DG~8MRSxvvTtmrJt8Phv~jemL9nE`?8ukHcR zTTg1UEk?geT;#c!i@(A>9p{c>QjFGrU6}}byAKI`k9vPcx`wQ` z>UZ5MYTo>GnhLqkk&LH6N#O@rkEGw=A|sZ;ld)N8eXpghAlpcaEmJYvc;=zRHmM;RXF!c4^0V(Sj&H) z(EqI@^N1!MF`VSXe1+>x=`W+Q)HV~IyM?n7W~uYK8@mzyAqFN+iLD>VIZwdK`I^Mt zDp1EzSZtf#kmv-4yH%1NwIhVYviftpCzl0F$BakV{x)Izy3DL`-Pn6`jDRmB6{(Ay z^Byb5KepvX<`tj3K(6+PG$Zh;!9x(|J?w$PhO5*00j;&UOJ;m>cPG|qJq7hWWA;~N zMWfz+mjznsmdv$N@6#-6<p`8?~W=+?=?JQ9eX`N2h?>s zL+6iJ+vYb1wV;djR`X;g9EKr?CD1&-JfjDTV^IejO1dUcJdcaGr$EG!2q>=YRClwI zER19o-nBTEHD@T)7|3%$JJ)6Ojctbdd2F8-E61hxEr3H?Jshrb2QK9#(qKT$uV&e- zX3ib4ceHhCzkc3QK?x2lkL&?y(Q45!)y1gK80ye7Jd8;iUST#_{`&duT1hhm^84=k zY@6X7j+pNs@P&|kTYg6G-T|1sWl&tR;R6GPb!0x#{;liR6Wv-G<{K$*B-^$dYxMi+ zumgv%s@iO#6(1u+SE!E4vJ7u$+(HNjfaJZ95C$2ux_%U|ePZ4*(xPNLkuM?bbiyX{ z7xK@J^g+@S+ndL)_~b;_D7!dkLSv#4GqQFkb}hm$Bh99ZSu-f;el!W~K*qf_YZYnwv-^3wP!) z&-Rmh6(Q9^=uL=oT!)Zm7iw#Z$g2w>^CI9&U0(<0V%zd}^1yK&0p`8GHueCHkA)Bs zLGw}kqq@yX<7=Bh6Sa3E4krzLR$95}q#BQqj!u@*(9#QCoxl~WSA#tRr{aaez`X_y zK?VEnxYP#F9xbAnas|dqMv@mDcJ6kv_<1_O>GCG2p zzFHDm8~Q=B&1YgOs4M!Nt^SA%*&`x-+~6sabGZ33XHQ4=Jgf#w!cx|;ajV;KW;W4D z%Kyb!x8H%?`IGN;S68{cX0Mq)S#09?2d<}_8I3jEZ3J+(-hWC&g)3w&^dn_=86&t^ z8o&R`BMm1~ZUhXGH)`gUwvQFm=Z+>(go` zR?;_`X`NEm{!xFT!;8BI<9@n-zn$2TPP_smPYG$#eh>WR@lbf}{#xtWHjjqoWQ}%_ z+~)_mq}fzdt`Jt|k@uO${6nUgGG&N9)Jq8(d#=0B_xO@hN^m_G>cKa}H%bsB2(BY$ z$MZGI*K>0h^dff_4G-`Yewmb?`ZW40ATU-GX9RuXa46Zx&F%0CmDWuVdNG6Cd@&DG zb4tE?G5%_X1)5j~m)iIeY!K9JiBUL#vZuC}l`q8QEVC|UKD7e#%1-6Vkj3u=&EaD(a*|kt^efg>W#-_`&1p@f1nmN&qT-~>vm%9%2b-( z@XhSHwup$%Bge?E)1I-0-koVs2wBoImvbD-8FIV~Wpb$EcNdqrfDl||6#43uG9Y_7l&wZDYk z=sB05hfT4RMGD1`FY=ldzOu2Mq{0MuG7_c<2G86 z3|#J9f3~%XCh2^DNh0mN?pkxH-;W=z3#y-zG$h^F(lTKmh0NUz6^ssV1!a4X7j19w zYVmu4e=>_`h&d#J`SNl_Mbghj)bvA%E1m*SQIK*Wu;q$Qi-rC=V|)L8ZEkS(kh{cWuMZKw8%-8g9MCZDu4OHE*ewY!B7T|P{yi2upviONM&HRU-NYhV8&d= zN;55N^_AG*;Q7EOVmBOG8UD6an91n24Sn}2`Xim22NJo=)GE_xk_wd+U=?7leW_I( zv-70GN+EDb*qIrKaz9=s+RgV!o_#T%Z`9$mK?sY?AnuM3*1w=6US>P$>=V7?mZE{t ziX$+{Vr#77w>C~cDOVLeG!>5pr(zxr83A5|1K+oVRQXTF#~+CQPCJ1kZU@OR`|&5Q z&Ia6dsPyMOCbl2{g74Gm=+Fb^rAXEp>+Z=zqWqX6e-UDQ&~+_ZLL5u+;WEh&_~w=Bxu&|`ZNlHb+!V>=CY4;j>{u(jz6vc)$GbBvU;M8KTZCw8ZGT3^vyc6_gB#~lw+)F=lx#s z;f@Q376*murMbP7>*O4Pt(=LL$2yx!-!Nkr8hmsoUJ-lq`ZqvsyLh&sQ#KNzK4n+AqJD{5ec9}?1An+mz{|;aI%0II6lj$V5eFVx=gl9sNnR}z#Ck?j?=QYM39VJlHKRm5I^e;t8QFe zmoPL~^0R+cG0CVL`bpg5Y0{PV7RWf7%vQ99YvoxNolnZ|>^|*3souc8JON;9y=vi- zulmbfMi76_R;aXek31j;Q+=SWAuWc7fwxCG`QRDnMOK9BAf>vpk#fBQq70j%dH#0t zLYDKiP_o)M z5u|n3#CRHc`&oh@ff%y~=*zYg{JFF#bjbS;Gu1p_EB5g=Qt{jC>xkEkMA{cwCIl+V zPm>7@gRP7=syTG3-v?*Le! zPNx$X15&##lNaL0&~gw80=o4pY@203vnG{Z3QyIRY2Lk9XJ|`d)=b>s%3H(;=xVDd z%iNVRc*?)dSSe=fB#8**Du;9jngtlqt^MAw6&!ikfm3|*A@8LzP4f6`j_F(=VpT$7 z=QZh?F?4@p;J){rzWNx~%q|2|>6eU=p4@)wFUOOQThFK{h5lluLJ$UxO#*eXg)q^? zk=r$6@`4IrNk%D_GAQ>H*Yg=C`bpI0jAA;0fK8|BgUG?#(KoLRpL^q{btlb47tE%7 zcSj)$!CrriF`+9Om(ggy77OTdjU-)?j*RS&{?bf3eEspJ2}UfA=7Q}dLf+qec%V%{ zBK47)6o+SE7{~eW8#`1wI5=`mScBmvi0umCmz=<@fjOI{m&!ej={sN230_ibusy(P zmG;g}!?k$}BRGXwYhw({j#k`!eele645=Js*>wm(1w$YM+swD7IA7SA^Wt9Ep_eIo zW>@Pc$Ry(UPJqz8=!;In@dPQd*UbY$=5nXQAmiE1_3!)glJ#xH+eTAdaVsHoeRM&T zZCTa#__NbmSyG_~uD;=ixlUSX&OoegO8NNnr1Q!(7>2sF%7fFpp}TS}u6&HXwP5|x zRH-m!{ONUlrgA`wHYGyv^7*2hJ%>o8Biu^Uko_Cw-2uidGIRJ_zoXr^PiBZSQ)-%2 z!~`b7%P> zE4i*m#B=4&(74)TFtOhJaQz@CQ~dYZez%9M1D2mFB`Oq$lg%;eG!!a3!C_O2=REs}g4ap%Z zP^)r{Wdfo9ZGVEEMEueA;-$bB@)MYpR_sVNK%+2i{`}aoAA?&m;&mBH#7O35&+y2c zG2bEA)NmN)FF@krei&Xj+*Yswk0HCqk9)Mfcy1`eampFYc&av-B^18WPo|yA}Ke zuoyT~BIOo_Qql|E+5;*{akIPFt0$KFut64b3sXV`rRD=~Z=KImylSrLUQv6oE$1;t zkP!SKoiJgG?(Y6>88x1D_ZTbQps9>$Bzfp?$`S*DI8KgDadFjlsxg2*wq{SA zCDrc%o?Ga$QwIxjjSheJ-L)G$uQ9=o7@ehAjhpu1HPfB?&cxCtk&ztpu-CBvmGiCa zq9dZ5PLt_mius$l=!mUfw;Wj}?A5|4v86{i9**A(6sP{UITK@N}scfaMgw;nRMXcQS;|h&^4&5Tt8l=wEQ(6=}YhCYpV%keNgYp zMxO3i#fWrTE;K%JZA*Ay4=8yN{G#EISn~JByb6(k-h>x4cqg27X>QB5Mg44+)}!0{ zkLiLItieAK>q~e(`Tn;ao+m@5P0sMg<48oU*u$@f)=RtWPP|0GKgLyY1y~s`42Bq< z>wRLZbl$t8Vx;^spAerQf0ynW;5AOE&Fk4lCVOQpGkLDP#H)iOqr}Lv5Nno^$bM7X z6!5~c`%@E(@`7S4;>hYMC%8SgT(0=b*LFAny38ULy!0Ks(c2a$-3JjzxOjE}m@Xhz_HRFK$ zK~`ov!*wv%`Tgn5yH)QpQ-Zw#jfb_0$DEy(^@3QAMTb3=VpB$C$vIUg_hM&as$E^2W*eP8l2 zVF8E*%HC^@MmhVMC8Guq^b7o!6S2aGmSd)D0fO>_QCOP#rH7(FsFOFv2g+Kk;H@hGB zRH|t7Vg|%oV)d?++={+%ZX$zQ&=n)38*Dhho^`M(VYtxU3++O0Lm=HCjs}stm;aO; zWVbs^hIFRMK5db_%01D zsizoz2N0hx)Z`JT>P`r$ zHM?C$lcASj55HVZOcfMmFLdGJs&Zx^mqwUU64$Y>rDqi}ZijhXG*Paf??Ov?d$2hT zxZieq9s8}0{Sf`j3HFYVimghe$umj~cg*lQN8gPVlNG*q2x3;};51e?EwJ@`czsKR zFEF*^u(~BsXYjNT#9bnCHtQUL6xXW1wW^#8Yy}r7d_76PjnHKW-E9fe_n{ARu_RLZ zxa7797a=C-Hn$|R4Ex(P(A;O|)&-?Bl|h7XEsn@ZIcZ|Avd~sxae3bueB$5YeWDM@(Jh3BRbAG=tVlDWcDgRTg06TR%T?J)XmH z4(nYi>}Txk4}vwzu(C@4uwB?G6!X09k@ zQctybf9~&5%i?kv(x3UD14A7f5o)=3IuY0WQ7oai#P8a;OIv}9K^C`th`EnVmw0r^ zAVDTUimAN6NuIIK=wKD=klVgFJ@==!8>cnN6wrrSus;%x9^ix-X14OG?;40%CrG7R z8-XWQ@N@fu7bu(1wdp8isoEEwrteTb_hZKwy44hXL>h7Rde(?mn%ter8`_TMH{-7j zOj8wo(lnc4l!UiH$R5C>>~z2J^7Gaw?umyHhcNfh)FT5hp+IBquUChzzdU^>I5@UI z%T$}$d6tm)qzRdXBi_grluOQrUMQQ>=6Uc}FVJph@=JIW*xwMmMaf8U%m2)Mvz(gz zm!-Y^v?&*FWC)B9xlv}m+(_2CIk32(Bytp+L0y&i-P$M>f1~GS9)ngAG#kNq0V=Rn zsV?2AKoze0n?AR1dsDbBcch{1{fxm-ym{%(lF?5^elKfAFh%>MfD?Rk7WzVa0R83F zY)o>veDaU3?|(&K+nlbfuMP}br#Zgep;QcqcV~)#Rs@A`-6BNc>yL8}d9?>S4hsb1c>yhOn5K9;a3*%IBhV+2ut(l*U*sCaG?u&E4PCX*w)BpGX8 zGOzZy$7?M}GRa(rkX8{;w0=&{yMk(q4CgQM9_XgH0*`9;G?MpL*r*3feDTZ~o|~ zYXWs!k15j_tpXN6_;<7>9ZaplC+&|13?^2ZnZ%~VBj0Q9v9&}7EAC(k3+iBzHEvSQ zML6@+SC}F~3yPx~G7GL_w{VwFTKSz(ste>|?!!kC>(=HFvqr*CKYSL`t<`$obSXm} zBu@;NrAEUgE_A-Pm5@$adQ?X%V&um@y_z;2bbfOV@qKmTJ*M7j3lnF@JsVVcg7{VjihOgz@9=KZuVsDeIg!Ll@ zBSK2{{Ta?$T==xF_AK9s6|dE0pUrB@pQZ_9ctNV{U%}%?5m7{O(o8tQus#3s@u0Fd zuU(-vM)0NXH5QF64$3KN{Faxh9kmM_5~k0ZhQ(cg|(7+OKrB>eO&7W-vpZ{NiWnYZ%_Lw9pJ2;C4p z={Ys`4Q}y^T=VnSk}qn~O=7JkE)QMaU^k4OyB{ElCQLy?R+R_uv0^^Teec&Vverqf zgAfQ}3zXRF89?=UPm+So=k?OdVyPDUALQn|Ln*)Mvf=?;hsIpE#9Nx9K7fXzBV{QW zem~ZKBKkpf)u3YmVF68=1d(Pm!FLW9*I(nxiE%_FKyE11pr>I(W&wO-WA=))bwaYDqDY*X)BN0KM%hr6|E!7^2!a~`FQl{gQ@|M0EErOY9%O>Lwv zXjbxZ7YbA)!WS*l3Ak^Wlh#Sw6PmAN{`8q zs2|a3EoZpase%~KniuATSJq3jdvq{^+rSG}7mmIu-sW!CiH)n)PUR%&Zqwj1fw43q zUQ+ZewYK)byE{|CR3)Xd{)#nitu`()Cvb6`=ELNe0829{Mv>3ypYo!dpa3k6Xg%rh z#dSbS=k=GGMWPk27QBs7W;{!G1gMRfVL`3aV5AY4^pv_nY3hrSIQMnYPo0_3_n;_| zCc7!~E~hoLH2b_{`82{?99LCstGtt*L4SX&$Y0QRy7+VpkRcbeLJ*@B}kG!ZlG_K?%qB8Sxh3u%`M)} z2o`#MB!b!7*MH7wc=5x>DooA3I5Ochz}nRTJ**s4ub|HKh#HT5_mpniJqlyPsfI4$ zWij6mf2f|f%$rQIZp{f}P7uxH(|G4@T`9FRT1;+C7!MUzZZf`&-Top zM}APZIoBfDHDyZRLQP>QceV+3&kLVTs-AA;-S+xP1M6?eY9<&#cS)zd{alt*X|Lee zObW&@F}kbqI`UY*ZI|EnL&2UbQXt~`wZPC2I5%-e?HRGp>64|Z(tdVoZklPZ6heQa zS?+pxTK|a2=jUgyDC;E)h6Z;zg>w8qpcX`~kmFjg+=6s1;QO^z0F{VP27~+JBbnJH zQNi%MdwNOUp{}R7;+6D8*opHRR$-+RL*Z#sP_Fsm?;Frea1m2-eIokUgMz$@s)`2- zgkU($jW7|y*&O7B0@}+81xE8b&t3{c45n?Jb0NMTh4Kakc3EDNN?+2CTkG zTN%{K#42_7%oY{uPfAD`Kk=N88ji#@cVW|8%S@e)B#Q`uIKD+oPKY>GplE-}_amZu zJPMr&-jXBQ)QO2mFJwdrF!?fjZiwxWd|dfb#t1*nfQ;D#$XMQjQ>)%0kGw+()d7JT zLfyP!P}~6P+FvQ&M;KPA4fQE7U&btZdAM$N_A2}F8p1X}fW&pj9|}&hzC;;`c?i0D z>T{>PeT|J$HCypAQ_5AG9Kxb0jb}ePqxivGE&0b00YQ9o;2Bxe3C>Ofof7)+d8+*R z@poxo&Awj@+0K*Y<2YwFe-@u=V~>ex9%$-9K^J|}-rvSB`th3blsWs*1g^{W6U@iu z3H9VD(BO|Jc`l26iVpna&}j>$Y4vdb*aoK+ImiC0y9YFr7rhVNfPpgHC=h2xPW#jR znS813sTAgej!c1Y*wpG&boeUuCtiu-J<%AdnOC9n`Ar~S8$)txLge#_qHw+Q+-Yie zqe>qu<25uQh=z2xB7KdsD%oZ`>p!|I7E!9&6l$5VtyM?F*DvMp3s1EqPfF4Jo@zt{ zx8@4g1*;`5lw5nxnarEK^poVAN%#Wmw|kDkvoK%sltiFJcmDYCB*{Yg?U4hau7TKl zL$xla$0Y4f+4Av($wbz05@3OKrT)sr>WXj-kMbj>`qdGm7B~>GOnV7gDpH#{lVyPQ8bXKSQL+!t`z-1QTF{B*?52xEDwfA{I(t2A}eg8K|wSthxS zW>A1E&uPD{cYNAhPb2Nn+2O(T+89ITJ%D)JEW9A=NF0!2;5G#Ebg6|%NgXL~Ye8;0 z)g2j^`Lz7d%WUvL0viw@GoZ{~c2P)HUIt^|9Z#CLy2M?R8qrb7l*fWmfj?@anRDJeGH9WswoSwBU6%Lo(wtrjw1#VG3tdn%sAE?71bhS9?|iA)`BZ1-1jXW717?*;h-q>JK4dbjSB{W+46AfnYzTqP=JE$(ljCSU zBzj)xM*kxo{of+ykLp5I6KZ6vT|P?5Ab3m0zdM}QuZiSp{}YIhs}altAkb70tE?ceWhwc3YU$4*z z^d1n-F_JbHLv~ckFu%2Lc^rIEY%Gqo-n}P#MU_}-5h?GM8Ya~$HQTFr59nKtf7VyF z4@sqIt3qlT?@op{UW)+7m7Jj z3x#5!K}d6C(^J>cd6UI)HBOkH@%xG(j(+_qyeooWpC{&9{Qy_%Rfj6lA!Zbtl)i>1J=)%P#3MXXNs63FP&O;H9gN z4#5%?iTzH7mLN zr5@f_!nq~Px}-}X`Cm61TeCapurRu=JvZhN9T$M?Z0JzLsm_VBujf*18=MB0k@P^r8r5K5#OXr4j%3y`fa|w`&glr8&SxhqN@OB}ys|5vdG zNfEIR&){~Q;GF~XnfcMh8G{d;R9<$Cq#=1t1F^l!$~Cn-iq!Y>dq61imobcp)V_kQ z1+5p3wpdHDIBA?Y88!mY-FZ=AW#uN*f!PZ~?ac#v4;R#adlhgF6)Cb0K~Zf@Sfv}b zkb=Iu(oaOn27Pd%uPt+KaRJSoeJ7oZ8JRgrrpD)nD0A*5Y3Jx zB3ee$hwCJe4f;Wvl<7Fo`z$bgecSpb5a$LHYBZZn*ubW*0*oA&_A*7C$3zViQ0;Ob z5rO=(2axPD4wUlpLzzf3UBQ_6stJMeNhMHoo4O_~3WJ6%r=X1_CMrp6Z5oX6MsjO| zUVvoT`6xJ?KWM^vRf`51>3j8_I#nODP*E&2Hj+LYM={(9+PO#KcL4-*Ow-9RhAtiA zAak!wsw}T@8>6Y|_txdmbFv;%A2M1dyMqf)yi7BF*lM@VOed@|ORS2gC2}5e9LKFJ z`bsXZy0;`Pi%on%X4EeHwlz|BFmIJ#Wu@=NG|pXNhn!w~VimJw8Hq#rPcKgg(PJ%R z@38vuuo}@fn(0)-WVy+4gU3j3?LFYa9$>xO=&d75E*eVxZcDppiz&&C@Aw^mL(tkeJ;Fi0!uW^j5g;y-GYDa1`6?N4-X@C zL+FONKZ+S)_Vc;e!4TR{J?v&rE8FVxhwWSv9zGY5va);V(v_Rrui6O&!9X71N)krz zy*&+~q)*w2&GC1vdLVXEq}CH!-ewcdR3@5Bs8V0z@C9-zfZ%c;9zkdPzTC-|%%vGe z2%PXu%eXC&eK%+(*tN~&3DAk~XR z2-N5R<9#xk*6qq8TDf0I1+z*I%5CEB`(MTzL` ztzkTr6Il@RRFiV&J@Q>2?v1pAsNG#EG_HG1d7NYG+0y0hd>g{?OB1-7d|if=z95DY zU7l_9ojbiImu`Zi&*-LM*K+qu9&H{@gZM%A02jl%TR5jnPRCn$o_H<$ZE&(M2lTh1 zZ)GG`)GC|@4`RF5=(B63rCk$}zm^w<>ZFitT?Q*>dI+!n7{n$22ajlh`02(Cv*K0z z?C-rUfIMR;C+wp30K}*266l=*CDJOSo5@MPdU->vC2S&=+|7F_`F~M#<$+B9e|R&Q zD@vEuTul*@qqJc*9j@f+6iHE%l3A`XhN3iMlv1-P%2kf!3L&yNGDRrYv@!QJa}4|b zKEMC`h0o{x{=DDM>v=uT^ZFcPK68$iI&EaSP9`iKviPAi+nDA>-|#8fsAIeTKtyZ( zSOM-W_v8Sg=|We|F4!yN&%Vq7i!pEuFPw|PnhJM+GsDwrAu& z1V9!aI^abQUz$aunBCsi&|8fuCq0GJ1i_}+Qm#YR(dsA3F`3286V^!nR1%-*wDoDC zO@G`qJz@{|r7Ds$-x$s8T>n>vI+C5v^4&utZ|%dpR;>v@?FwlRX9&pw0fy7IP>U+q z#%jK?TO%Y5g5>!C9YxV50f*hGRT+M&J@n)hi;v!nYJ63i)kn<#=9~5GZ5yqs`4Vaz zZ8){Mx8ZkTM(>?W=G`5u!E-}jHl>g^eg?OXCOxmrU5mV)d>+nt&s}qZg2V5lYll<( zuV!hIc>1BsP|*@%!fpI8FUIWBX(i8Fx9sDP0NrHVE%@&AMG;8}d3x8`@W4~0%aE>p z_%4c!DCpxp-~D4+8gHLLs`p)%;)8g}Sma9cZHebY8OO+eQDfjcrD5UEB*2ms)Wif6 zu{6|Grj5XUA}QSj>l>kN!6RO7pze|{K!=xoy8N$FUUi`=UQ*7_YTVGJl{iP&1+a(y z8Yi%0e%E|Faa{5}z1apvFzI?EYl%j-EUA=WcL&|pbX7@r)KtPp$4H@=D0fxE3HC9o zp&R+G-cs5Qn(R|I0>S(g%MPNh)#ButS_!ihC?n}`^ynuUkXSCM_iv>f%HM(=bmy10 z-xH(h5YH`0NF5f`jN~n4Dq_RaHD%``8j6oASgQ_}4iCMpiaD|Eg%g`@gHYycp^J%8 z@7(7f`k4{a=cklN%H&uk^2hDaH0d{wy5nqqx_LjA`Zv>TU;_$3htq;G<&hz$?|K_$ z9m01Zl$FP^OA|B&BV(szfoJoZIFz2ETJkYuoblVg21v8^v#BXf*PoW~W7PIVxAb>< z?)d5J^jFV}p||sT`6J|A38<4Jw5u1;3>zXJrQbYw@UGYWlf8vF)(na8FD=~FC-s)NcCukL&6B!FUOx?j;N1y%zTi=cx$kZpO>l zj6P-;;6oCPL&CI9={<5UmX-QR1tgD=wOeda&Y#}Pya{obQf-W}qivs}4*@R0CbK^T zF{_t;b<)(^N5_mhoKR%G&F$(ToyD_qM>B2gAaq+NT9?gG>m;2-qp@MS0k&i_aC+$g-}*0>D2;7 z+5PMH&4`t;?K7~|AkL$2LulRRYdM}W^$cxG*5&zOee|M*f8WH9yNw!dLD&%Fb!t7b zfj_SWouY|6SuYMnu%gp#`JED0GJLgb*P1IH-cat2ld@{&7?ZN$VrvzO@f3Dz<@wN+ zJ)VJ51H7QAq|tuSEt`jjn&I%9Sd{su0j^w#(f_sh4%Sx&D<4WY)GNXn_2DAb zVeYBZp%}yU8^*08e($_p-&fVb zeGj#dqQC#lUCROywnfR0k@hZU<~<|jn;t^mkV47DQrVK;Y8}t6N`JFL`oM8hblU!Z&MQbyq=dnk|AC4M14j~h)K5nB|IG2!PC!YP{n&jZ3GDC> z+W7!Z#5_N}oXh(qJ3D450PqN+wtxpdZ zSp3oK*tYHezT|BO(8dC%Eq(f&@~*bLeXM;aC5);4AtSv>@9=xsFBja7K0&1aak~>U ztjRFoZLMq&!o=ZEv(IQfOEuJ~Y=w}dpe{y=tC731aQAQDdZf~qZJ6o7)y@ZuII6UN zB%`Be@c#M;Z*NDv&$kDX4Vfs+Nm`JoM>QSNRxs$^YM1S{s`W_y0n>$`=HQq6)mb+E zAGNogrDK?^=*%>K!2NixtZdOU&0T3Rk%`z++Uyv0-(eF8z`QVn_9oI*-r-5;%lZe) z%q{>K_DClxB}4qJLEM<{NowM+fPc~R?NQ@B&o&ANbR(+RSSd3O!{K*lBTfeUQ0Mvh zhX6-hLo>cNdUY=-;V_bwDcGa3+QQ?$JGJ~#ra!iiFBwZ;;}#dDv^@HDPxrG#{caY} zTBVYgFhzGed(vqIjAz=7syq3}H3}35Fvji3?af}-KBo9yRE#_|EF3J{MmqSI%l)| zg@dQRZ1@i(j1m?&6cpb|HYFQsDhej1R?q+OtatZ0yjX;qVpp-@01yhn~Ou+R|Ms?g4v@TY%9UcPSw*Px9K=hq|{P%h^&4`qsiz~}n z?N2JtwM=Ym5_J?)&ItkmnOY>hE+^;C-G%1tT}bnl=0JncDa!xxS*GkIdy;s51gb}f z$o2#-md(iz6?VB>>jnXmtdbww9a)**i~Ho?aJUi<>4tDhz24fz48uwkoGo=*}!&l6??Qi4XvD^ytwnuX-kBjOWlLxCrD zf}Xsu0oZB7glqqSnt&hBrCP5JD&HT>o6fquG>$}xt3+O>D5l0h2Ru}`!W@UL{_fmm zu|y6NAH;B9fqGr{$L#w1cnyKkp#i{dQz5EhD8f49v2lllJP-w9fUf)y{7h%Wfny3u zks?xX3_-t9oF*idjV9iPocqC6CjyAo6Uk9%EHfMp#5P;!xNj0SSGje#6rY=#pbaJC zCG_d5$1f)sf1dq|YIf{>12j=Su97StOjO2FyO15GfUp4l_2u2WeG*64FprW{!Yt~( z(}J6I?jvogUrOMp$wr2=AQs@C^7t(+Wmz2xO0Czx#aLsJ6CI}X+Y&eIv~MxfH#woO ziRn=Dd28g{_ZuTE!FOp(Y;yvcK%0;J{7Ju$)q-^AYpwtW1NN~iM+dB-D2O?C4REa9 z0Ucztdj|9JN!bBXa@!efvba_!Y3{%ccj6GJ9v+@7<$(VWH2E>D;wJc0cCxj92A;)U zW8OU{Zx?yPRNjyyFXB!ly#wJdX*6H3)Y4KN2w4$dU{v_FxSKeHVJOC{;-J#taq{II zmENAJh789^$7>(G!pPIERSjH<8L){f%t~e4uJ$gQLws+a}DO`j`Rn}QB&z5@(&>N+JdWl_Zvn>vq$^Hs@xp3 zHbj+U#;a?sa%K)q8c1s2&$Rud}UxM>y7+1eJux??k&R^Q4^awuMF)+VwFsH^!67;E$Y;i+Q><~ zgpYnA_;jh5hCg7xGaZy~$As>o#(sv2-;$1v+>$l2@FIh!7`V9!CwHc9+yT3JTt^@- z*;KI|FG}eD6fIFGsCmCn(~H_+%IJEJIW*^?g)P|Tf@)D0?P!JyMF5^X`bvgzAWOq3 zwtEpB2cB8&^?m=@@Ntj(Yu7p=JS&>LQF4>-J6BmT;$$oP$TOI>C^cM^)2kA;sq;*! zZAV!)he!`Q4#c+XjS6zh+?2vkVHJB!G>o$K_F#en&WpT3m=`eQgzEw8<-j3rb*8?G zvEZJ?rWD$MK)6tgT?_vDV2_n&)WaCZO19mZ8++`#Q?OQ}3QxOyAr_5V^mIVNG}!dh z-PePlZ)^f|&<{K5~ngKm=i z*tR18*KF9kxIcg3^843e_mG}H+xF}IluvW@uD||yBsfmbVxF6V%#(Ph>h^|WCJ`g9Gb$F3Vsf6_I9822r zIO%Y^*Lx}Gd+Va9?yl)Z*Yv^u!zNCOcZox0cxrz!`nE*IXzFnDm7|-z8jsg(Cc0G} z9mQY$Qp0Tz55!sNPR;|m4Q(w=ly6k`rR0k?_;^?)Nnvh<`^NVZ=>W0#fC{L3X6K$q%jC_jiEp`*0ty%@zF_Mj z`LwMf@dULR2miD**T-mLc>4BKH1|i`jrUx0^V#RlBMrrZ7@6!&iP6d3L%8Qq%>^K! zM_gvtv3U5qw?@pUU2KaA63$cXggBqoTe1I{XJNVa#G^{>fm$H}PPiD@Z@xn!x{ZEv zmj-dM$qR{b=R&$6+3ENA4KA%s4`A#%#6n@zWwNbhhWo5R8;`FneirwwNRkI=sEf*d%a5o1I_f7|^qQ~T!BLpz`Ap1- zk3G%5Q@3EeZcg=#E^AR&{{ZSD7((=?2CQ}=dv!LhFmN%s7zwPs{@_#bdp2fye{sZxP_lB&c zr(sRv_PyMuFyKQ{y!P!&(axclL2}O$FSls^O74>c?W56nI~XTBMVGdRn4wy(=1aMS zw9&X`IC`CPe@Ui1>WI&}*JmBs)X~_alf7?PGt6V%ZhtG%^bdG;)F0eg0o(Tp2s!gg zQQXybFz^1(G3B>gV~oCAyWnX2HL;2UfpzfJ4m(vbrh zL%bz#`VF7UTTq}z7ooG8!w|X(+-S5SElG(zfHE{D>DY<`e3=#)Qw&a@Q z$XvjKwiEo8p(|liZ@#EFZsd0dbSgY)uo1rQDVVyfWYXkw`LT|Xf|aRg?2WiDAnw4V zRfm!3LNA5kQJV{SW8BoAjQJ5`F{OZ;#HxL~TpoJE>3AHTd6GtlBB$o)=&1}_Y*M?{ z)&ao;VD!HR9nO5eS%qp`GzzEC*D@6fgS1~a!kusBz2H(Ft^-=t-*VZ#@ zHXkl1{WWR+t){J|tfB~&3>kZuVa|HKkkTsW=_5(b7!nUez9*qvZ75boc{nZ6S4Fs& zYV6b{jx8bq{Sz8+xkNqnbM-E0?6*AUB{loj7p_6fN?j1Yrh zvrs6AOR_{1*NY=JexpF&DD5B&1&`gWir8Nwkm@uhg)3AtBP*MwnIjh>9xuw)q{E}D zD2~^ET#eEGmSXcwKwlLymo_Yt9X0(@$d}2~`boveny7dJ==LjnNx3+#78LV%O4LJk z)}t9qi5LQAQ766rVqj}|2TB7n{u}dXx_6lX=;A<^OA%=MJ;b zgSjW#fdU|PF}4>jRxbF^w%a74M)4dwbC4#&*YkmwkfvGRDu|{#y5oo5__)9vq+QO3 zgKQw?59a8@=gyrt@a#x?mb&VniD5K!v^!8IJ7Is?>A=eoO`Me$t(+or31t0p=9Z>A z=~I+jaK=+Xd{DvPzbDYo5{_m8dG6=YiM8C{)#-6i5;Mdc9zoUqVE zUSFVZt{x;EQR?4m*nv--G_ny#Z4!Q#Rh-E9LeHVDauG?tKJ6YexmOsb(o3lkson4H zo(V>1wfP(VEN!+%HK=}Ncr=rawB2tp>yNINjMA@~+YIkPf9EAzwLR{TX&&hpz?Qjc z&#g_~wkje3yLz4DYt{ci8D1?I`Uh~^Zj=fWvKI1>wEtOIi=K_@n?TTp4Djj_v0jVK zMuA~7n;6BO#80`%^-NBRsaie3OVsK3Lm5z!U8fMgh{CsHr4#q_N#JIrxp0DA*UPxm z^(p04FbbsuEk=g|82@)*{PySWX_AaaHFm#>?unj*_jn^%$Z#QUVq!INCzyECyXoD_ zxqZR>=wWl>7LPaq4&=F`m*$B}?Gw%`o63JX13^v7xWW3;0%A6ecvQF@G+}A}R zKnF<{G(Mm|5Aoh+i<}_i<~FAGZ!Q;j6+tFCFz#J0^M`aI1FhY;UFM$R41-YivDd`F zo!&8FLYRu6E2jv^XLC2Zuj96_l${e1<&Y)Fn^E)9)-o5O>%c7?Xg^ceQ|*Afhl#`h zm0Qu7ea{heMjVVY`ama%HXVUtL=GPERsJ6;W&b%3c?g*Qk!0zxkTNd{#vc?Nhcg@-LNWiZ-rD7k{ z-%Dig5GbPyw!F)@^^*^7(y-fW36*c*9$s2`TxDk}GsmH7We&UBCG?@0(jG)A>sr^= zO*HgQjY-@4YxWnOpb~?&N#Rob(O zKj~mbe}3t-PYlOAnz1scu_YAz0*>!cbTHk1C1fFNzHW|`{&eSw0d17JL;zAt#oC?- z()yia`(XV{)y|3+@H^iF9p4R;;Z zdT}bPC+HIOUBJtm*B>G=2AT>|Vf>0(m(tIbZqeJpE`L}j7irsROL~M&QzywCt=F9W zq}yH&T_5}Ut2+2meGAj0ZWHe&A}8HET#z48o?Bh_S5n@v*|vkI=vd!$IO}mMJ1)gq zacthMn5j0zSBaA{yZG=IvD7!sFjk>i3o3=761+1S@WZgFW^Kqpw{(rquO?6Z{e*dy zNcy8l_JU!eVXCnS@lNUXSI+tO_3EK*QK%M>x2hpa1+%v*uesN$K~nE661&BE!K;Mx zpxIRPTYCDH?fw*B$g%4C6#aMS!DJr@j6H>g@s9WFdx87(`U7)TJf~ew%E!_JL)9hF z0*jnOr3rtz+rKt9Bto^!M?aZT2oE|AE#^{Ovu&O2Kf&O;Ve%&m&4Mo=XI^zwIh!@= zEkbSjk`6i8Ztd923?5g+JOWt<{*a>G|D*i6MK+%tIW6VXShTMqcJ)CvHSzg|`ghIZ z+GnQ{KU^@cA2wt{aY4v8 zkmoh;qtF8XG!y9E;HO~kvZ@!1)z$vp#!WZl9i0@Q_TfL_Tl^1Pq~c8)O9KY0Rf72# zikaYwv0HO_9Fngnh>ax$Nb^F_l^i_#&5tKn{l&n!Xq2Tx{|FSsu2*&^87 zbwLM;?dUEJx;5`xpj}gYE#sUrvcrt~Rq$i`HGGr;MqCq3%$^x1kkwoxp2w7AH;s3h(8oXJ*$m~tUO50B5T)o_sO*0 z8#W)C$1dCoY;|_FGA#$XP-|*e{w#cU`dV^;Tj>mGtuqAM`WmyedVA@Ee$U*hLt-Y4 zG`@fT{J2OJq7MY-1>!0_DYPX?C#fqQzHdVp_OBHVJO^cY&hPr71eiqx9#8zt3+}$# zxqrL3m@BE~kdE9i+cdAX={h=fO-IoJ#yk6K)^}&IJU$x8xNGPzj_sAImC|jqD%Y*8 zsVpJS{#BL_sASs<$f`s2dvA?dT}+Cc4;uj3>A`Ax`Vyx{<$F`Y4<(+bzd#x}iA1T0 ze2`p=&n3h8aP|I5xUqK}3{Hr_(XB#{rQ?GT?G5Z!r(`S_rOZ|1ib31Y=rxu2xTH4- z+3Ml^oUXcBLvxm!?_VQ>AqJI=HpR`^>zwrW;qYaNralwGsR{dFr|dM9>h(^k7t7>t zdlIuR%7f+rzXjvloAUccmZ`sMYk`|vwbsup)VXdSX&TiLs@8r!ZM5-;TA-D*CKc#g zP=@(ZBvYANebtsK4QlSf4K~mCyo<{LaJ2BR)p7aQt~@qye4_K(%)?`KjklfL0#&Ed z6fodTo$L60b?Frvh{KE%QUN%cnmzXy>FDbnkkR7D5@5YxE*;+m?MF=vXKlQDa>|+y zU9U5Ve903nxK4$@Zeo%5UvlXL9(PSG;&+3A(dk$kVVhLgq_rKW!bir|sJ{4G4OR<8 z;3jn6{;j4CEGgQ`kRh0GV(OL^FLKq6h{jj|B32dCf-Ign>bXU(1Cjy7F4)HA0(PIA z-f2q+;GBSgxK;mw)S3(20gLWYO=*(qZT2~egHfO&y88F+#p?%+#Yss+UgV`gDqRfF zoSNP?U5^(=^_+kWi8WPSRRu_Wna;va7i_*YNC^4$M(NZ+&vrR)ZxQ1KqgRbIi*&^V zk090)GX~aUXNG%^rk*mH4;5c!uPxVSO8AkQ@;CeDt?R%~W(GvRp=qu!QOxHlH6qHs zg&&t__b#d!)U`7fK1{c;1SaoI@ysIr50GzZKK!(}2okbBxVccjwEVtA;bHb`s{pG& z;|4ajo(&Z2m@Ua~%V$3(hw;h5Xr%ajcj|2&Ttfp(s~F&^+8r*;&s6SUybt%;NNWDj z&bo5s@Dt^GjpjaqTnfF;qjvIxel~rNc#WHsyRr!+0y6k(GVVUJ8?~EX7*jI|pk7{b z_Dtf}b%Iw;7m tGe46c33GT1RvuFG;;gS-IMVPgDp;)#3=LN{9G-lG60v(S?kzn zT{k~6Pf-XkRWJZ9x46;4^yr&cb4UST7P=P7UwY^2`aEt7DY@uig;9$VB>d1DNMyn$ zQYpriL(VVNYA!@Qg~A^&r?7j~tB=V4fdV>T$Sap3t-;`CR09){^UpEo`fx(>&h7E; zo*Ov~=ibUmQ~uQS@76TF?1d+)9Gr+^*!7FF_r{+#gS(!B7Boo21>nz=lg;Ev`lSG@ zj5D>9s}edj#hf?;d6MSRmhuoJqYh72JV}8fHzuoD*9S`^q*%zdAoeZ52gz`*hYZv> zr@)J;0U+MN5ekv%{2!<%|45i-AX6E32?Wny;UwEkv}p2&cfw8-2-l*w($vNrP)pyp z|BxIoiWsq*5fv&x7~F053J3y@TVzaZhUHxuN%&_dAg5BtQIf!(#iZeGx^4qE z3+H;rU@$fZJ?ZO{c1X@z`EMvsiX%jaGK=nj0zGUP502R5*%F2Bj#_Xs53p)giY{K9 zTfVeda1PbHoOYPRe*@JT#&mr>3vzfBZGX#JS($~L5H0~ink6n_`ize{5RbLcC!C@P zQ`#w(4gHhQ$h!0m{6^N0HAERMFJ#_b5}zO)VIyom>zk0kkdkJ@nYq8OK7}EADb|yY zWtS*cK)%{6>Ol35KR8jOB(IyBd>rJ6>)(jF0!nt5pF8hG=YK`cB)v1QZcD@H6BO{x z&>}!uO)POTytyTA^x6m{XM|qEuXXW@Z8_Y+!Bec&;<;-eaGzEa~7f@fN z-6>ys^fc-9=%^z=`VUi}bq;0cf7F(zY0(%=x-mfTcyv!>Ke;5igLzE=8@cxf(gC?G$C>9+%u0H%RNjt0ODLN_oljQ(z6G~51t z^&-H{A}neYh(ACNBxX){2An4dH|ha{%B_6jSEnB(kEaKg`6_kSa_e*Le?CMxV0pZ# zc*ml}f2H5s&H6mwaPS?DXbVOU>6k^Au9QZxHQEuw|9DIjFGy>cpj1sv5^xERq}N~$ zoTeB9OTegr7oR=Q!8xv>tP+jdFq7Ym(g14CNvx%nCRw4jnhey<#_T%<$C}t_)M66R zA)GLe$-(!k4;E{ZV`&isQ65n`ejX~>hLWnLvFsv?Kbdkerlm7mQ}7KOTJCq-AaN$6pgVe1p0H?r9r(}=1-2gdB;!-0kgyiM zXm1*7W6|RN%k5+}{uJGe82VwjZ1DiTwwNOUmiWV*pwXr@rhpLGMvYCVmdzbTOyK8>HmS^k>ZGp1AA=tFZRiM zZZI)P{?HsCaPdM-`Kwc-k72Ws8KwlqckX8o21je0A?Lyq8&wn?2wvtwp)gnfilSb$ zW;Rz%-;GLp00oIpCQy3(VvOXxh7rBp6hb(VRhgyo3d>n*H!zKZR(Qx@a*hs9PaV1z z_T@E9Gx_p1d>U89cxGjxO#Ew-s%sFaI0&1>^&%#wI_~`Ol~5^sgR5to z3pb-!$Kq0?9b_3V-Z0%&6)ST1tL^un$3gVN^+%Z3nfLGF*#uDd>*ODaA1Q0%mxu+e zq0F%Co6MI52IeF#lB*)UGQlKV`XZ;S@dD4==AbB#U71)LE7d=kA|)Sf>j{MVM~Q~x z{{y*8bT@@v#u%rz`Iv7Kt=&U@oI9^!#ME|dOkE@^zCcVdnnayaFX>1BYPwTGAsBZr^GMY{`2u&6rAsC1+iZhJ zMnL%bid5!~%ok()SPCKXTFyTL-Pq&b4xD<2(IudxN(2yJ zDaAJxpwE~vcp4k}W{DpyKKAOAEF|o;Egu5sR^&t#aqZXL57A6Et29%))`El<83ZS( z&nr&f0zQ^VGxPMKM1L^7@ANJOG{;#UNOpm9j;q(f~%WMzkuu6FNMU&Dnq6#fez5kC?r&JhAnW-+Ej8fhRZ#&4i8mB>d{Sc;72AeWka79Jf;f`8#$Oh!ezIo0##qIWo6u>woan z>keR)NMgvgz6(Z0dEDs!-Xy#6h#P-L%X9A?KJcu+xun`=`;)=wdSL^G{|-b9SwD&` zk5upeIEvHb+Pv_c4Bod|97u#tbbZ|QBeLyY)PEqEh~dA-bv0++UK=sEupHJC9zrpW zk#TB_aWH+Q4Y}6*#j`so?Ce0by5fH2Cb4U<5voNtN}fgtE_6_l>iBtIN#^R+nQWU1 z`z}d6w56vp1t+>u9&!82qoLB^V)wEdn_m(A5UJE3sd=DeyGQ@3!gbGH(RG{PW#rs` zbAyz5j+DJLYaA;+3&Jg1D1BLXH!G9bV4HvL_ykZN#X8yk<5dU<+>iO}A=!w`C_B$ekXOs5xXy2GY z2Utt~JTA6#L1+>C5u|zIP}+&?8ybzO-1o$=|0h#lxo!EljY^(|4yTxj6fn(sN1LJ4 z$3YK^-arZ?<1ts-UOQjX-CO#&O(DIXrfL;B?uZ8NG2#UNvzF!WI2*Oc(B8T?8;4G& ztN8{rN+v51Lh8S3E|f$K{-_GLocM>U+%iL>ihe8iI3jKGn~%9jOOj*zLn?r-?yuyO z4^P;-DJY0MM*rnZ|HP%HKxM;fm@~7;Q6Qq1oiK=w_)adA9*_&tp=P1K3JXf_ zHUq(c_RNhbc(sC=gCpfP)DO*BS2*0kLUjG%Ul z7;Q@v>{^Q`#EsYPfmNxPAxyZrh_Br6p+xUgST-#Q*G~cNhaU1=d#nbwMFn^okN-e? zknG|OERw^m^N#{NlkZTo0frMy4Bwn6y`igmgKZcPDjy1^$SiF{^F;qXzLBq{0KR~F z?om*Y{+K4ol3C$^$;r&ex8|js2QNX3g#bj|`yf+NQyvcJrBm^6O6HSd8H_%cE~AXd zxeGWwlO@o9OO=jO3>UqRh)uDgU(NOpcj`-pNhaH>*tVEI;Lqn~C3-=^V@yz-dDJ8n z&wTT~NfTVoYPu^Qrj<%3h%>Y$*7Oq$+GS8I%>e6O>UYIdovSXJ35lR*mcq&ZS@UM)Vf%L)D=+SkMgYoeE z!Qz`~Jk~b2hB?_Qsc1>K^soHrlJrc>$t?p$p_;+SnKeM-Vt2DqLWY}c@e)z-@eHCa zB|C1zMg?6zGq-x)ztz%*dUA{AmZ@YjZ-#@;hl)U>yOO(_O+C5F&7u4y)g`bNJ$QBv zzY3T!-d%Y9y@9nB^`~RcaJLw?lAjb%zopMQPcs0@?O&?@SFricwOHY27lJHc=FS0{ z^0BH5=aiUqXuIWrArmeF`g0z4j5r4HVD1|=ap8ZU#G8lzTw1SBigGX_qNAR>QY>^MdJ8nmV^kWCMXHcH461X9n4leCk@y);7~p|A^xC0k7hj)c%qQO3Y`~ zfL+x54vQ639T}RbG0M^K&N{v=|<`H%G6{>^BqZ% zv5Om9jYO+f@4T>9Mh;>Uz)1TL(e_=}OXj0zXMy!6nHR zw`)>kz4SIEPKEa<7wzK|U8eV?BJ+5tQs)~r}G^@@L3b8A4W+Z=?fkUlXU zwf9%Tk2kLaSqjq@V36uSEG3km3!wVFsqT4OuUq)qFqKW~kzb!O{``(fkzEV~ao}qFjj3CH<(FIcd;36o-%K?y9r(fz zF8wgNdoF?&7}ktb5m1KNJHfW2_j2%nH6PV%H}t$@1Pr?*k1K>Q&);TUJe4WPS7Im2EYe>1l`@= z`UyzXl12@rH{<_2!Ek?l&Pr8}O;Ln`78NXKdN*GEh&lbm^CU%<=SkuA!nqq1KigZ2 z$i)?o5|9vrNi&Et1yxo*^lZwx-F%V|0${tyTH|x*_L~OP=P9*y;I49fuZ7UcjWdZ{ zT;@F2l)%F3m8ZnGA2&P(!6)3+X z$yH_W-{IPFzpw)37CIxEa7%#nD-G?};nZMvXq-ukQjH(Sd?T5zjvdl)FyPa|8KZM^ z=X9C=v);jt#@o!cIriqfyV2jSEF&k+@zRth6TAgt+!X^`_?sao1!a!+gBBDYUH1{> z5!RG%?-Oio*`mycs)eWl!n|CGhuOAL1DMJ~*NQbQCv&JNMO*HURnU=J5qK-^2pK`J~*zhw21ZzN}G3+bddOK%5 zGD4TcfVP!(!7N80H8QOB-uiydC>FNIe!A&p^UzC4Z*HDCz@;SJX%&1k2EDd^ZBE7AahYHS=94@)Sk2>2#OPN6eonsnX+nk1KK6cI{Am$D#cLX z`uO1Y{+u@T+VyKSb?2DEm0kXx)G_0g>IXBckY>}Uc+^?=S5L2%|4-P#M`QOLQl0WT zp21?OR!s~8*9YBxH}%BTQTo~XN7`nP)M}A;)FbP$)1xz5o1Caj^Kdc!H@fO^EEx{M zidLBR3!>%Btp%460?CpXR^wJmv@P4Ri#n5#RWx|`V@;fLrD{fBK?r(vnd2jsv2|&_ zc-^#cXr{ z@O!i{!w+}hm;Y10uo(MKcTod&$#^o3Zj6N|JrW;SeR1(i*T+3}7hG>8XnT`uZkDJw z?oyWIDA{&k+3$j{ZHw?L^xZqrHNDj0e++zIuA~3ucfma_ta)TWFf~*OVA+T>^Ur#V zeV5Y=h=p>|Dj%D0pnoTDkM50Umc25`Itt2CZXmu6JZ{K; zk82qR1bpL3e@+Ol{I<|YJbAACw%qs%tG;C13BJuy-9R3Sya~;fN^tz+<-xeTng~kh z>+dT}%r`B*TA*>c-m)trn-|o;H@}qtnu>4>3w~A03l3OY&!$q;#`F0Je_8QWQL!rMx7?rbKFPVd89v+G(&E4_C;Z?I()^{ka6-JNo&J=q7eqkEg< zd%qX|fgWa?qz3Q)omidh5BnLdrY--F8okI#CI}J0()fNgh~YbZPCy@=G+0rfdpqy4 z3T)kTm~3eNTnIDotus;D_6v5LMP=-_I=7!B!%njZV)+MVG9qy!1nb8e=3g@2p4{o2 zy8oWLhQ)n%N)8Hbwo>G?$9Uk-%YPRS6iYWqo6LYb>5R5a;E(yGY*}l#Li>4*37IM$m`(^FYTdZ)d{s<7XSu#3+xt_TQ_5QL!d@9WJgcNZO~(y4qIh9mGda zhlke|E=m2|8<%v4+PyrtG!?zN33!fbzTQBJ$B`u7C@xbyNfog=U)fxl&UjKnuvTa|KST_Qup<9XpJ6G3xWXlS_=S|8#et^=J zCT~w%4D{rZI3mHi_Lh$8PJOJbVYBH9OGU)}OHv_BzjlQKiLVKv@T~*hn_LF7YuABn z!OO<{QHS$9AxN-!=i!QB4GBlqUKDX=)Yw2WpK0bm)3cV@oqjMS7gXn_Z5QtGf4@zIwbU%7#}w4{lnJ8IH1;qt*t1y5h! z-S!{oc*Mql7&X^N1R(0|mKf|72WZ5OS*xhcAT{D*V8Keb7n5|hSwUtJR}W2cj4U%_Ws}IkUIK(lD8Kfm`CQ7rJBc-(+kw_YR1Wt7x9X;g#kFU% zd`)4qaV3GSE#a3kvY0Oe9Qx2InCkyE2WNxz@>OK{dDCV~4YQ!-YznU>T^a((oZ4VR zcI{~QNd*;S6>RGpK-A7~e1|sp<4)^jhfpSm*em*ZzlqL_QFI`hEemsRCZA4gGjIx> zN?lr-VA$y$5RiiZ#-oiV7#>UD;D{ZiARh=K27+Vy1687nR+~oTynhw0y4`cusdflp}d2k4eLxAL9F_$Kp}t+@}kmd zg4Ian4P?%zqlM1a&o04I(*{f#FXRATwg%TrKlJOgYG?j;+&F%TTZidA3O>4BZ_#FZ zK;F;SiQG>=r>;IPvQ~yX>)fp^Mo-&8VF%&||iHlJg_}*J5R4P7c!$2H< zbh7CRyQ}|IiAm;4c=E^v%fD73p1@cTGEnICoMi8jF5Ru0%-XaDW+$TN7#~5VJtro! z#v&aYq^#TVQ)(4}!>3K^02Dn*KR z5&MsOP8whVyD-oQ5(sk!2b(>&Tgm7IFB*hS;#YAjcFwMgFo^QtV<%FcazhJh+%$R$ z;2JWw%ItN$tluf&lhaOVRgN~=paGjnd>EF^|%Ag^%Qdzme{=~z^B z?0^mX` zjItQi$@u!d6Eq_*H0R9n*MgTePJ=F|HDBg!3A9AAB+29eX*jpgbV<}R_?7nUmw}yx znUNQbOG~m$U=lrC|6w0zrYChPr1L_i!^9Un^>a%$7Nvx|2eZ}{XxuB%fSb4BKO?Z} zOH~qe6JvS{;83=UqPyypXDGxZ|L5{9+o0vf!ddG=BBn*AMXMWNv@VWWJyJ4Hk%lpI zRAZCw7rjG1sj0Wmh9}ksqYdZg81wHN4sM6OEn0*p%>y6g@5FD``%Eb{fsQb-HzDXK z*!Lm*%9<9AIoD4IuJGyX2mFQougvSzi3~IGy-j?^4C8)I?KSfLxAE)s5yK%xSK{u1 zfF3M`K15#vKhYjuTzhSoY{TNvzcykVzJ1ak(`ndVVPW71)C6_7E5{{gw9Hdm{sTpC zcm1Vg^&^X%(YIEmS{s02N02T(`$moPmY=RPSEyMhyc(O$dL1dectJfGUA<0NxVpa$ z=0YY&5>2rknCPBci8=W|J#^1i-dHmt%3J`@LPY}aIuSyQ28+psiABr?^ghv8=|2NW6 zPhTayhgQMkt>7SaRm(|J;jZ>ODW7b3F~7_t+W#Eso%5MfLcz?J;l20nrY*RYfS=bx z@I=Q!t)!yNLfs~#{V4B-TkAtL_&FNf3($-o4#6M#nsV&c_QZJgrB)g_wjNMgEBq@J zdU+kDwM0JdWW^m)VY%e5Nv5IW(KtrOyRDj^l8~umweYj}I^g z5;$p_FN)M19|sdW=t|+*N72`N9zc|LSUpYiaDzcotUvC8P8Ynl94S(}JU)5qSNW6t zEIaQoh2hUl?MBm0JW3Ud4TU>nRn(r`pPmjnlb2mtuHMRF>SP^S8%}nFnUzGZQvA|> z3kQ|>HeV_po|@AsVExR*KFr7lWhH|;!jzF(u@1kNp85^qol~!TPO))qwH#%gmr~f6 z@h}!d>F^@X0)uZJwCw-+L4QkoeuDRoWUO9&(YT^&l`vCkoZu7pcey9X)0=WWq{Th1 zpB4l#^uOmWzRGx5JX_JBVdfTWN?qhE{Bb~w%NB#vN1ndkSKrl=d!lt$#>EpOuR#KK zxyAE7+kb->za6^E`85Y}k~nkRwLAt=1jr;ev?2Xva-Y3w-EPhNf#YLxC<8ugx2k;g z&$X{HLbM=gV`fE>V8TQ5D{?_E<&5O3n~gf#SOJdqsl$K59{`iwQ<;RHzM4dn2eKw9 zmZ-nsD}d747^@0QzkbqqcetWrg#hRGi{=&8$G6%ZeA;eXOt`lssT!3=*t_=RtNN6O z7xg;kSzDRIuSkD1b{dVNn=Zv*9)EeJ&~_lPp*2OStCtKXEH6#1l89G*3nbN*4zTxG zWGGgc3&@cd-rv`F7Dpweu6lLIDD#u9r_#cgcP(tzHPxQ=KPjjCxL)2;XLS;(VidMX zEV%nWiq1Wr>Hmx4V=}kqUX!^sMW|c~V>6d>>0+f^5|T?&$lT3s=z`YVBGrs8a?7pc zekXIw%0#)dY3|J3T)w~0?>~Qeu*de<`+d&q^?Zg~{9bYl8nV>Yy(`7zCfW=}tpjS! ztLQdkLkpM`Eg!bIw;x(?I^RU`t#y<922F~G6goS<7(IXId}7>Ck3S!!Z!)dbujB8| z%}Rh1HvDJpCnfDxq{4%>5uQX#GIyK)A?FA`+>Tq;B@l=BKzoi)hfgjE^k@pnpl2D` z4chP4qMTfw7@D)54rje2O)z91dnmG28@Vlf-KQzIAn7Bkg;n_P{ zml+YBx<~x;V3Q^RjJ@6eKnisp1z(johnqUOK}EFc36ET$HTJQ+OhPP1o%)Bl8Ul!& zh5O3y*j2m??}fmqV3}IV*!bj~v%-M4vLaLS5mxJ=2b%$&pQU~?JwW#plaG9<(x5ad zfMVCBW)F0iKnAIAt>dGws}!tD>2}C;9yA`*xZ!i&9Dj}*KI{-x34~mKomOhlQMYra;6i% zoBr)3EvT?B78NwReQ^HL?d{yrcaa58LTTYK?p!jii3&-$%YOPfRpq&b2-MQV zjmbO58;YDAmeDel!{&@Ax47e^MUD#nwl%Z5Q?GWXv>2tlQqo4;|hvD|& zJ<e8E(?42jq*bqz*r)+;bw#uOc9OFMF)%a#wc{g%`OcE6&8)7`NQ6PlnHr0IvW z+TS~*rr1FVs&v>DiONE5e4_apE8I#pPO@9-y$Pr2 zE(pt+j5Rz+ZMPq4u>UdWNgGkzV3Yzq>%6z^l;cTHwZAA{GIE(|(_^}EqYbx!p{4ML zqjqr}H+rs_-Kg?U#2z$G+ql#u1T|%f!}q8peKrv~5?Jy|iB0;_b46QBOcPLk=`rAx zu}n5i;RBT-f02LxwJ&VL`9*IC4ZcqEVr_spez#jvCB?Yw*6)(`dCdm*PM!V+$#~6W z4bFDqLac0-ygk~EA1?m)g^cl{YU^5v%3XqUc!&RO#URP6y)LFRKZCkZ)4 zFnAGhk=JCzl={mqMSp??PF$m(e~T*|KKBG6@4>fY+PNmMzAS$pB1$s>76HT>su%~ORi(AB3^(Z#ChKx9vQ~`=7K?+xYj^g zWZ7(>+?BAnC~@eqPik!*Pua|6|4v<2!VYJRitl+S^^NY{T_q+iefGv07wJPurBh6i z@UeNXgrnHk7ND;Z$WAyVR%zH^?+s{k=FAn0hGEZ#RAOp$7L_QR$0%~rYaBZ67$3tm znoJa;WO4zvixNoGvH4o7bM%}f0$A*$M^<=Pq@zA;DLm}6eJjlSj5Af9K#W|IWdIkQ zwZS4#Se@-kK9rSW-n^+xQ_7Xuuen#;oo_lZJH0Ewi=`_41Qg~C)J(pCBF>(kur{f3%hN>#Dp8{L9UvzwPqnbA>+x?`8#%)Uk}8xcFC7mc`AuTnq|4 zUB*H~0M_q#Jt#ucy%NDiaM9#l`Y?!w-0|{H=ni!iSNT9_)sHq{KoYk_7PlGa*Zu;3 zrqAKcQwBH6_lVjo$WG+B&F$y;!wAcvu$Nv(U0$p*P~dhbKea?=20SxUl4IlcT*{s6 zErOuuPu^l>e>&e!xi9YgwBvA+X=txOY}WkuaA0XKXm9%>^R$fJgjR|%F<_?#Jh(TN zF@EGz<+Ffvze}SD)6bBs#GhGMAi%+e^49EPU*fu@Rj%II^yn4I&k~3pB=EPyoQx|J z+FKHcU686`d=eNMe+_q*f%)&?!zY5Jzj%*tcb|zVdfVPwo&*`%NfesqmD^CMwf*RFk?}Otd>HGHUd=Nd{@v zN57xbh;f|~C!rf+9I0Jija zLd9C=Zr;iDiNL*@4Mgnx4g0+dl^4_woRgyXN2yZ4D*9DDD6B$*nk$!f`%7|oi`-KP zpGH5Fyi3BZqYJ+)Y`?oNvQu_do~m#Cb-WRn#C=YTe{PYP+?=+(zLnMAM+ntxtJbe2{a z=Xo~;$@o+AsHKayZiGAhe6Gn;3lPR7n{>hSl7IdHPomh-+&Lcm1}?Ps?#rk-i(=^? zeQ-Q4r(f&Lzk7)&NyS(~WHs_2jghi}WaUkD<$mI(bQi+3q>w2)r3?w<6$98N_d znVSZgs;$D`uWJ7Vn1_K15UG7S^dqY>SMKM{7i?FPcBeVp;7+x8LU!~jqhB`kz?6U{ zjy8+Ql;ydjl6d|6X@j{Avi;qT7e>xCYTS^rmO_zZ>9f&0Y$t=rllT42cAt8v`F>BU z^k~FUQIUuu`$Xy+xOs|2C{s(c+OT&ibOKmfVwv~Be~OnrsXrcRUG|<`OeF^~c5D?4 zPWYu>3Qi?ZQ#+}XS-C(t^>zJr>W8>rjE1gH{x9!LQT<}kT5(7#_?Sl$k0rWe$y*yt}aMTZ(+{ z%(D!hcDB>#HJ^a{=}rs?HK2c;G41bvpO^;{c$QU3^1IapHjTsLa;q7-SjHYAGp9v~cFS**y-pAYgK=~PtjYBx)YDpVxit>0b%^dEnG%HK*~ z(1?{5v1DBl+uJaBCZp&3unl#7>hhw=^@^{gu?s;$fVJn7JeQ54f4X-osk=9fbGozc z>;3eZ70LJ^i#cX^8w2PfXCF50TNu4OX*#BRP1mP-xmWnkyxro5TRTtUu97Sl3X-G8 zc|=p`{reB>&Yp0in4})dhbYlnIFwm!5OX88B^7VzN-Ju zOqN&pg~`Uo?v-t`Z&e=k>s}>N#bnwPRHO*19T1*X|9%b-*1YVg=lQl zeRK0kOnYguASuC+69{aw&v89F`!ryO-eV_me1DZ)Y@{T27DT|#Qj4y7PDZF`YIuWO zdoP%4;#vAe0Dly}&PzICIFrw8_&KVTWH!3q$??FL+>{YPkq}(2a=t=7ox@b5Zm%WZ zL_oHXRDh$VnnsKeo7`S)K;2`^4RWUXl zs|K2#GXSmv^A{zOyG~q(J#n_8r5=Mr~je1E#i%6`RcGnlD<&z z9{PdkWT8%y@|So7L{Qo4GBjhz54qS}Tri|@{8iIUP@0o2B1!87H8+2Kqv&}E9f=^c z63N2h9&*4yNV)DrZp~s!$01pOtOa8d)te6Lf(vq6YLIbJ?^|4@hBZv8@G&~xTTFnT zE*pzU8?vD~aGOR6W#O8ZR8=NS;Gs97_gg#Gd(ry%0|~A+o!E83*R2`HVM~SOyG#JY zW}UMVnS4@Al`reAu3GgBJ|$FsB~&Sva40Zn#hB_9|8#RA@-;A^m^Uo{Y;1Py(@)-; zcjMsT)gUw(%fctqg56n zsc>f^OP=(2odt*1hqBw{&A zKHm))VJpeYj`%Ng0vL23W8{S)3AgnLmLdbP4(F^5e06*F!%OIi6X*soFrG7WYV0B) zQztVuZl0=$tAZ!PoyD6J@8X?tH&3keW@P^ddf#S8c`M-@AoG>u&msM6w*YN6fn^M7 zNJa^2o%{7UL-WT%lX%zIPFCV4T^R@-H1%=i-Ycc_Zf;%_`TgNsd1pK`uvgE2pyce6 z^?5hP&0m_ynUfL{O{_sA#GnoOtx-#_Bf%9xg09g~KoRK?t;FcZ?IFdu{0Y$xS4!wC z-Qb`uC>weu1m9(RLA!MEU>Bea#=jktui&1>J2R6k{mBHg`JtTsNdsr2$`oIXXqw{ILE~$Ac>jUKuj{wc2h`_2#+HiV z!y9kZmY~sdc`KV~#~+6vJdn=AN2jSP$+2Wsf52YNR^X%8gUs3fK*pZd&D0LV)zqXP z(L`UUKbf6KgS(#N`q4UBq~0UC_yG|9l?L62CI-^HBF}qmyI#Fh?L*We#tq6-G@%es z61Kv;Ffsi38N`i~Xb>vOz~F;ik(1+PKI;!nLnBF=d{S_VUi5f=(-Z+Im<6$u>dKfB z2&JX#3AdI^Z})#_sR@WHzBl{vrrM0)SGSZ90e-0_Ah-k4 z%5qjIm^&=^(!(k@UkYGECC-i!)L*p>99iSJ9dgMBd{SO3mHrO-A4s=IeDa}4N6|wr zsBPMd5T5A%?B?}((l^iZiWFnP*wUvCu_$AI%UOaH;{EZgV43Puoya z1uB;iS~;Cs6{c|jtNGId~mj~UTO$61#Vw8%oyy&+&q z6s_J}>hjVbWB=F`UJH02)hDa_8^|}e*+5n_?#WBVui?WCKK!N-2({6)fc|dYaOmgb z_ZpvW>y?7ityKU%@h7Zh9orF=>~c}9DFy568^V~2a)MkMcq;GW^DLUq-mBmJ{|rRG zYULi$&h(9U`E7pbmQx*6uzZ+b*hH8WCZ^m(WZWCn2~*%gHlrpy23I6!4nJ7U8zysK z#!t9GHU1nlrrmtg7t(T0<(AGO)d4O}X&7fTWkXfuxM${?pVVEc*C=;I*9PrT2THmp z9FJWTIPJ_s&??7~@Ied`6)5FD5(?%rdn?iS!!wtH?>Z=Ky6DPmT)%B9A8G+XCbjnntqg2*CKNt$4 zzLe2aMuidN6<%S3dUV0Y+omQnLNMHq*Ov>CI-hs|ypBN!;Gf}N+`c|m=ULGpnrw@-n_Tt}5_c5(m z9kw4(?>=;asKr<%dj9O}Ucq#B3U-4S+n|ot8lR`n8p35732J|hkGEwrb69U%IMyA0&_=#3!Xx zjBTtm03wkNOPKlZMr9< z!;rutsF@jsJ*a{t>$D!0nmo*G;g`8^nU?DX^pz8D+(JzHyhwT4JNhcCkwv&m%yFFs}wY!91Hlh?n=!+PE6UIP}UlSz+`&S=$ftXH|2Qu zFd#RB+cE0F8Z1a2ibEdEeQ=aw%08Nri%Rz%zv7V#>;V%Bxh(>ZA%hj&7{OaLL31FW zPS4~dw$uy29G&AewSHA&5_9MK398(3;2E2Ty8ZGuJY{M-b-Enmta1}A^-?fugB4@L z8ObB-fNy6avXQyP>Z-FSXv;~zc>~&RD{u*7CGe%zXSWI{Jxy#PL6ZT8v6Gy!6UDDQ z6fgAtQcE7zzvn!mLf~swA~VX`RSVdPPVm0-l24=dU50pRx!J1`B|W&P4BK%GNO(IW0(&a zKA#5h-n6J)=AvPZ3}rWV&vk#g%J?BRH!x&J@9Jl~_>-AunTmf5QqNULAOcBO*NgY| zxCcHrP9j%&U*|qPvUq+zbf&B4*5V0csJgl)ju`Yq0@R>1_`dI(YTBq)b<&Xp<<}KH zpqN{DCLEYq4kU>?*4YE zuO#sw8#Nw|myZogPECF?=ifOO%49p*#*OKOx+lk_QJ1D@OAIL&?d&EezYyv<0GT{e z2l|{?0~!Xhm1VRm;NjF^deNhjWIeUc)z8j6CjHCpCPDJfu5^Q)V!ck8oHlCMqa`Dt zV2n7p8sq{x{^A#}wdu{MBWCbm)HNQ>;jH7gbVPCw-GnQ5A^}M{d$|d=!Mb%K*d2ac z`JQaux(r5~cGuC#Ex?&A_HnBZR7QhpQjW@X3U?%T;cLnK;;#SS)J0$tU& zObAdr`hbyQ)`Nuy&JL~?r@4q4mcAR($=B@|K{C({WC8b_4`tBq(nH|;9f#>e++YLb z(&%N~;fLo!WVn~^t_1_x%PvJd(-|*}@z^II>WZ*6i~90+(^v{Spnu z=TDz6Jqf-7Xb+6JsC{1*%R3%vL|S8%t!$G*c=8W5!dY)dQj^nQ?z6E}v>%9-xHgm# zdZmUL4S@g9z(Z128LS6Q$dnLG{(qW$0k`)>!?w@tqI1>A9fZ7SC0&j|ThC*^uUUrb zXfAS<^_pFe;iKL8_h8Rmr*PucHA#v6mXP)dBmx~O)j4Y@cI3r1bh{4J5H6ldhg9H_ zXRWuI{k8uCr6QDk4DK{}WX<<#S?4;_(=(F%Gviz2ytJ`%7%i)gyf_&JZd)m$a4o%% zix&9jRwo+A93>ah1`b9Qmr#@^HNAGDib-VTX`nC#8P9IS+sUo-pK`GBpnH$4ZGQAZ!mV4XsVehGr9G_mT|-w09C_1oE#1 zalpO8tGS(l(*=if%$1hbA7yOF?w2iYxAYM%JEvsl!x#u+EN$}OqAA5c>5@A>4>bV> z$|yim%}|ggc;&gDSvpK6pBS6?3YFyNd;8t|*w+dRagiNsuQaqD_BttcZF!?Tm%J$Q zf|IQu=Bh~H)mxh%Kc89Q33XF=>EXhX#^#||s~CHbosnX^feqL%ws#s6{FB6Ltdc5( z=9f7>wIl7h@~{E>*!G*=k@?VLwK2n%H=}T&puh#}C+LIFduuR)Kx_vOi$vzEYU)oB z5ShUeN=dwW|G&e}4h{}VbfP};IglsPnkNEacgM;8Spykc8o5guS?a606HwDIHgJx7 z@H8mU+OJV1cI%54#ZPx1iVl$gS>QujAVcQBjgYvBq|!+nAKHY*vO$dzIolY?o3GcoiN49U8BG9mQ{L z{@~qm?>5=Sz-Qnrr`K|sAln4U87Ih4qi(lQgAs^;1O+fDX^7LqrNZj>{{scn; zy-}_64`|#dpl&fS;WkY&qJGlLYWZ9MP99;p!uQRWfk8>OP|@>$nwj6trOg_{Iow?6 zwefE^`n65U+X<8gKO%34df7xu9V-7(d&JES>qmvgzI3!H~0Mi zz^`%JXRPF;8F+aJ7&Xrs%CLvZi}v!SZ5_Mb^>YH8@quWdr8rgSxw%U|S7ib zvq0&k$STfWz2V_qi5N{IA&3`uRMPy=`mJOz$dEHeipP_G@+n; zTP{HdAL>tk>pFLR8FXlOlug2y@>`Z5Wv zmjzUGz8up^Gj;qNO08CETt9CmXtk!V>dcGq!4t{O0hnSHb6I$bb<=2UQix(|qG2dw zW$)bGi#9uUM|OvecAkbZ1NVR=D(IS1PmiMv5l@sO13Gw| zSNSGLj}M%FAAh>`(d8reYLYK5X2A>%HN)B`E2w;F5C-gde*RfKuF2c}hN7roV+rlz z3~CS8p(+#;oaMS5_8W8l!^qc@ikhDy9eAZp&3iQgCJTkUp2xfuf9S;hCM91bnO+DA zSm|+YVx^LYOoQAL?}JnKRLQ>jtQm`Jfi(xSf9635 zM^H{?z}V!yzgz9-UD>Ok043m3vgIxVX>7bfn_p1T6@Cpxc6g7cPw12UaAQS>`z}P| zg;=_?1Pl$+S7OFvtdW{Z0WM&ByIX)#X8y>5t(00eZeip=CNe8cOY9;zG`<=}8n@zG zrXuI}=FM+6nV%*c{kIUxBRqegBx$wSq!@DvWQuvrf&m@;6(-vd{-Z6@^@t+R(zA8W z#A<{-Dq4 zRx)6dEi#nGRV4wP7Ce|<$>Wi{v$<9D*6jq}y|^>#mJmx;?)Bxw>k0o-MB6)WJrDH$ zzpUM#@@Ilo)OfQR%=hKkOLjPB<&Po8DTmb`9shjj8yw>uJo@{YM%D#6p7-h^@00y zuq>0+fM4b7)jI}?XP&W(SO3e(og9{nleBV6j#ImmFp6u(sEKLpKj=w!j$~VO3vDQ^ zE6Hf>SfR>>+X@_{6e03^e~<=yuEdB4EJ#Ycnb{?KvPs`h_{UG7)zJNr!e2kCxeHk1 zh-F+>F1_;jmlCi-SM|L|bz#m7IZKSD?s`Gl6?PZ5J{Q4!ViiXjYjoQG4hqQfFqXBr znSYZ9PIMD9Ldn*}l7x$_pZRzGu-ffbd5C1u4gpF-S{tnM zDBs7Hb&E|15)!q`1R#WQ5dBE)(Dzq#U6ZM3Dx}hrM7=usrL{35Iqsc8tM+77ayb!42FFrol(}l2^lTkrdJVbp zh-me@<|+;5GF7Q4+q*KOh2OP)NJY%qs|#{l6HYgSpn6*@QtoJ5DXgONseA9um80^0 zRU0hiZ1i}-YNGVJFx8T>^jo8Dc5QBM2GB8!4QeAWhhCvU!qwi;tuODC^sp^LzL=(z zPVh^%8&^tMtJ2@0IUJ9+N02l1C3a)>bq|GtI)%y#HC6PKrFfFbtJwd56E$q*>2tQq zX+NdL+J@U&Avwq8y>163g%8KFKIy6^h7acNUGA&154Xs*pBW71cNqYt4h4@)GgQDy zQb_3xw?=;|&o#&|xvv#zxib{am9#j~Z);9hcy>E|OQcmNjhb6hJMSjpF5W%p<#>O8 z^`cHLIN$Mg$@hi$vS=%bn4;e!Yr~}SYmg5Q^qgLynTrKO@yBjip42%*G@p3nK=i&Q z;Sp1yPaZ@}Eerg4D;;vKLUl9!uHJWpmFHCxWjqv9VN_yE#d7)Zi(5;@Ilpa2_ZStU zoulPnb&`dI)GuSzHEfGleLi^{LuM(Uwi? zFA((2i6*+fg3u5qKDY#zWtqU2a>%qx_;h#5WiIjt8i^uVVs&S@{tcw_D3d=?Qw)9m z_zxK_0n*rZ?7U+{xsjQQV4h=~r4Ba~2efqTXb*}ara%7ti0a5vt^~)_#-FZT_5i*s znqc4UQ#{4*^@(}c34y;RH}@LRAWA0*XY&4hUTrJ5tbDQevhZ7^)SPC0Ed$A&qs^yy z`^gnCE)_xe1V_wF?h4Se2@F* zbo>hggU5lcx)E8S0&{;|+u zQ7=G2{AxbUd`|vrPz?fhvT1$)LEYDjf^LVGkOHArczAS-sjv%@HCEkmK7{gTnvgo( ze1ql`+PMf|tgV^-sVTWGIZ6B-Cd0dO`og959j;iYz^itt6*kFLpy#acAfFI-S^ z58@_QhqOiSxYqmix!O|wfO*P8^21-p>SAn0iP6b~klFFXl6pww8;eC^;HNEAT5z42uIS3dMfX1fa{vj8x@3pe4d@7*UTWOPtf z_&}3o(c^=h8v~PK=r0wsyvAbLk~BkzWxWMZXS?ha6*8`~i)3U)etR&*MtH|yvgkaK zRkJ$>umbf<$=swM202A|J4&wzmv4eVJd+;Yt^ku-iEBI2gH_pr|A9PrjWui1d>#XN zBqV_88hBuSr$gm)uohQ&z#Mut3Y%jj({z!E&^RzS%BC8O?iZ8~YVaQoNazV2rSoi3 z@t{GSLQ&_=&U*^Dxe%#&>Xk()M)Y^fO2c-|hU+Q<#YUr)R#-cJ{qy-6sc!G2ATI)_ z9WQ=>e`68&@SOam-H$Ln5#p(JR+f)4I6%Xj*j5-Q&!p_{w_^lIp)TXi@|o43bzKlU zxfz)4*^Lh+P=kM@&Q{KjuySl4?)v_-kZSN5KVu4luj)~vO3rcR>OFq#BU$;_gvu5( z^BKYIRWDvW(^{q|*)-hm5rf^TSsSmoXsfeg&L`#!ecK@gp%}QP(khV4c75aD|4Cl$ zg0M9S!X*kM?1ZK!&QSW~^k_yKp9(G|o1!0Eo14AN=|3BB$|k|)3>GmBQl2q$!a9v& zt_=PzntXn$s*?&g**}s?<_|R@-g>R@y2YEUM1e2|&F$|?&9nC*hFr0m@ZEr+;l_{%7vcyN8f75s6 z^T{<|{&wvOBw`rOX!Np{TfC20?YfmzBV!Ef+YQ&)A#tK zM-C`@9$@3*pA-h@$xGxiIJT%C;vI55aCn-KW(Zn8>&ALfnCD`0)BxxYfZ-forEW7~ z4G-7ZZE1e}G9go~=)4xgH9^wEWNO34yH5ku*IY;$@a`Yn*?%BiIPX0SD?Fm_%csZ! zg8>IjD!urWYjs63s(zX~me6*_Qs1NGNOX=5oEy-%QR8Iw zLl&Nq*ZA}aOZB}GX8GSQANnQWj!~`tBe8-5f&}2jgX7hYDoh>NZ4R*nuEpk=&~?_% z@8RcFJh;wpU!b^JMUGr9qc<{!pm#@ii&ip59h^~4nbrm=B0+9ovgj}ngxo6D*~Rv% zEh{7_&eIfu#$G<7*erM8ec}!4Ab0(jWh!B5O4F{1*J%uZ2^N@jKfd9{Z%ckJ{~7EK z$J*8-*v;(EYnU&7uX=(MqBNfH{o%_rp%k}gE+Z-W>zt@7{eGPwcfpgtlAi$Xp>ZUK zc#U@?sVhIR{3s*61GTn|qmM+Mf8o1o=trw^_9#P#%nudT?_JkPe^EvB(Pc8hw4Wk} zZK@i+h1be$ghvnKq?AVd6MqI}3tGK&mX7>=H$|&I#SdEnl6#h;s}^S5J{%2C3d@T6 zB>YKl>+_M&GZNj6US8wM6WoyXrcIO_zR_n!Bz#A|v2_*0LU$aZ5>83Ygesx7IIcUv z|2_{Zs;37uE9Uu7whcZs=&cPU*L^KbXZRq|{xo!b6vjT9Mbi9SrDCvhy_xBX0^$Db zl3j~Hffc(pT3T5z8M0&#APBWb@z89ycJPtU{2&Dal#oE_uh{4Elv=k?nwPW3lXiTN zR7Wr5k(YI?VCld_A$M3h3(RhUi~#Vg-Lw>S(OZ@asdSgk+bjqTF+%y z)v~2D!X78#`if9}T_(*29j{(FDDXts9g*Ee?EK_OHI`Uug*D55ptBD`3tg0ZcqCy% z5n)f)Il_^u@;y?2U$@HND93G4tJ*_1(ED>28&bI>pXq|`>QNvlpk!r7AYLP$@#Ug9 zX#i|lEqk1ysHQYzP{|;(lTjQpOSAtp%TqOa{Bt!pMi{xSl&{N3@Y5hJrbIN!E#>KQ zh*2B+$a7qU;zXaxqXw}h6{b4H-rC?e|}YjEt{t{stwcF0U-e)Bz9Efm_4H6KyY!y+qu< z-U=qWHlqFao>~6&>mpi&Yi#vG=ILwup5s2(WEA;jr*Nsj?$f(dSB9Fcl??C`^el*E{Jvc+#LxJX&q(M*D*|MpGP{m)yl=_)#sQ}LP z3-9H?CZIu+)l1L{ossa;pWgB6we(hudOvWTsi-yFZsCf zH2LVgky_J*GawKL9up-J_FKy5sU&YG;vW@Y^o3yPV+55EBTXVgY=PhP=Nb_z3}X$V z*-oKTVYjQ)&U^~A!HIWrbw-rHMt_;_jw>^X0_)Q8Cq10M5S{&yYWfo%vCT5`@od?5 zhjY?eyWEcJ=A8MQ6AfckQS;}wV-4ky+t?}F=NpGD7Vcc(7jujtcGi8GAx4{UyP)|F z6AyI%)gPUbOF&(J|L~a8tA~O#mgj-%)vr%HG%9pN{0tQVz&RP3*0YVF9!Ni|_F{Y` zI-vht`ynz?@^8f!j8qI{u+NWgueIw1W#-=kPFa6!a%~*CkH2(c)%C)S&l>&xV zJ=e+JXryl_y3xe(Nc@r5P=ty5W-#nf(?w@H!fh!CJeA%Ex7k>JwqU0v9a2|e_%=;a zxO)lW^jCIl2ej&0=XJycw|VQihT2E74zR8aK-#t3c#UbZ@id`&7#OyuN-s~|kkFUJ&?3n0$5Gxat#}h>BGW8!31L-2r+bOS<+DmGmG|%w2sCOVy91;}xkm1*N0t`{YpE+hQjf5-J8-ZqE_rrth3ftB(9!%q)ref5Tzd3)iKObbOSg32 zkY>?p(ytP53G5E5nR5+7d&IW2a`{U?6E8J1EEoK9I?iB!U!$WyEZpSxqs!n=Bhkat zkGjeJ2caeJa#o7pXdNUxBPNb!BXxmm#=2Aid)uk`%hTWDJXI}16uhh+d^bwNP!3IH z6xm1_Y9H0-^I~Ek5TLDrebo0^IPU0z|EBb3qVplwk+mc(s#8{GSRLgky(Pu_hCD+W zBF`o>O85Ovr8gWc6+bhq8?RrJ*R*39BAm3tZA!#+!(jc=`Y*HVpBBa zQgWhqo|}T?@@XYXv;Y5?=C*m`_*WN}p35rv3x!F3_6W8t;MK&7r#!Z8Oyu)?cQE0p zcVtLomK=oUY;6^OXsNIp`l)bdnQt(P1w@t%fFk9SCsP5&tM(4c>j=zK9ETWzekdF# zD^Gr+ZF?C|3N4}nIyRT|Np-BO_qi*9(mn`ZW znvvIQ27?3m9jPCn@QDUJ_Wk7dc8WJgBJWul$ww1Rfzas~Gr*VK7%%$u)!=WquQj=F7{#F-O4LSsoatT$$4MO%3KsyHvYNRUUEq~IA zpJYsuSss;Xc7sIzEu9$GpzK}tjYtsklZ-~lS=KjZMi}8HcaeNgiV#-Omc}LeFV&e~ zO18&%&dn%6&*{#TF5V_CKM_|T=f$(jDglu9{&%FdNs~5av^s1E&I@SB>h{NEj;?y%WD0}9ry+%Cbal!R7N?^c-CG#B{ z+@{D~v6fkd6ty5|YIVryGEla^yeAgVoE!1>Zl@(jUi6Bk;7I#gKcVYo+pd>2%!?k1 zUJ-4(>l@}zs%8O*i|~bUvB2%F%4GcsXL-_cZWg1UflM@o~e<=Qh&<5p1ziqzEn0PCNAZ*LFMJKNP zz(U#@MO(?kl}>LhBWl8c$@+%t7&dmjYE7(_-;;NeV6b%!;$$&94rsZA!50+{eWngl zKoe_&YyX$f?EG7sdKRa}EGp^%wqt7lCy5Nu8YN-diBledKR$0aGd(cRB3Xz8j`V>@ zk@hJX2lmD(GP5BU9d+I26Ywk{v@)Y8qv}zdF*5M6i#|B9o#RIRYXK@p`do6@niVn2??@4J@MWA_L`xbes0^S zk8~*J*R;?d=?W2jC>qp`aS}G4+)gdZS6hK}bdD9JCO1)0!oBso2O`qQSDxiB`eXd8 z{fv}SlZP=*kV&8M$%90nm{VTYDOVQtuSKUHh}~q!Krym^K`R<;CC93(rNahX?V@(s zh&jCjcw}hEcKnppy9S!tgF4aaQfA;?qJOWZ{~x^V&)8=BtK~jr_7|nVsZ46EQvQgo zF71l5Y{Z=8iaU`Zd*O`6uc;ffD@kU#Q3C{&m2f~Nz0FZxF-Q|CtQphxI212R z+*qcf{4gCLS<9>=->yo8^X>y<#?F7Bi?KWr zqp^u?{=h@WFQ`$9Rb#?O|0`PMBH=OJ%C3UL37YEYLzmCCd!7axS76sxEF5Bgl2f1< zA^)*j7)mndqV(CnuFYsk-@kL}c!Ko*BLp2eZ=2rSZp&Frt|XH*am};Qbh$K;Z!AMU zCMhTO@PdJtm=-V|IS7A~KF?4~a*u3PI04%$u;>N$*E42vPl9nFg65`i`w3dH6jz#M zm97kDt5@G9f92%!<2#A2qHYd}qeL9dHwB{J@d`MeqMZfLme%Es*bU?-iPD@Cts-$H1sxGU6Ew1pl92o}HhNB_{kbBArQ zT(j>4e%uvpVm`TMv4p(y=>M1vNHDwQ_uosmdZvAO+rq`SJ?NhdXA=UVq~2*zYXr02 zF1z0*VRbt|>+^3GZJXX``qqR$9DaObaesVm-s=0rX~p&i_sp6v4A3DdssqzwgH>q{ zn(~QMHf^0IO@L!7g#Z={Z56G*@yUd3`AhxZDL;sOY&6x98ap`LSG%Ox-w8nc>*R;QGl%N z5@>aHFW99-!e_NKGQ`S|1y9mA@PE??A)Q+vYO&B-OwrrufOB>On!n@4L*!alGP|8W zYs3h|lD8n0%rKU&r0s#oRkb|zTkqQ~R6cXv?Nm~P`u(LE@+yOm4Nje;hzqN|werpXJkBM=o`Q^ti|I0PY=ljGmB?Yf<24lyLcM^49SCMV`DrQ6^dR z9FNM_^^Dx1f#k9mjjSvsG!h9QXoVPT$b|%SqSm<-ZT9XL?HKO=QFJc;On-kI-%Lhi zxz(1rWRq*cx@>HW%BAEIp^_Am+%}WT+=fy#_Y}oY$|aF5F1aU0WTGP1X=Ak9?;79V z=l2I-d-z<=d7szo`HV@X#EJoDCs|)_ST4$#C*`VU3C4qbTP1&SWd@2OramGfj=T`D zKa{5k@$a=!GXIMY8UoPy86T zX9v!Cc(ULJM&Ui{JGE3m;?((6ZG zWSZN_%;=~FzWC=I`MzWFK3TJ~ekzBw{g?K4JA&B7K-$ju1aJe6DSb1NnOWcKdTg?` zKCJuiv)h}ZhP_4>1S+S0+UMosx%n7@WeJmVJKFzHRn@-Utd~g-KkuGBkJefy!4w4p zj18}eq#TMkze#gOy>J`uDsKtu&z5Tpik&!~S~y{mn)}OG7lM4E6*8fA zcO_E1&FDalmeR0{Q*{y;q-*Ac5Jqm#K40viw8?^pT`o`ecJy9(;H_rvHa9rtB9l?4 zmbaw!WYH-5<)7JG4?<+M_JWE@&&!FdqKcKNim{FJeY1@}4!8AOW6rOf))E?Sw-FI~#?|G_5sfyV;FUY*ze8CY(Ms2dK!O2t8UWN=YOq0?ujA2rYFI3w{VOqg4|a68 zAYyYu*-IlWmYUrBFPyqs<{h9g?r}LaT1sIlw0RC|e6Q$CuRhcb|3<_B;0P;f8o$#{ zhYEvo%|KjEQU4&BxZh9u<`2ZL(aZB9oP0K{c`L_p>on?fcj5i!&Kc&!4q%fkA)e~E zFC#8_lDARKLDGYU!k9RL&y7RiGg{Y3`i1TTjnS-IpjWatn|Zt;fd7i-y~H*1##fK_ zbIZ!wh+uMTAe`$K#A&LSbb_mB`9T=gFwXqU#bwlS1&1mRC3UQE5HF+M(Cd4zaG+&? z7F*d0(qb6HWH)Z79Fs2dJV1;&^9BO%?1WVK!;F(0>&z`7oG!b8!#S}Au;t;!lGlSa zV(O%Vc+N1c11`|Zn|T8I=zgV?3%GVSBq*z>>RZKq?_|sSpDkHQp&ktodQ_$mspOT*>++b87$!eeo3tELmxRx zmN{@`>Oe>-regitYY|Jii$o!P-M0H3E^aF1}$oM3~;$n-l5IaOLT=^JSCm9fbg7~lHo%+Rn_0Vp~DflhX;@GtN4Z$U|t z%+b+#HlJaiXeyV3?YIe8E;6q*g9&`FKN!u6XHf1n*Fw=%Voc$fkr0L2B1E;3`+Y@= z&VxVApu1Cj>#`^3Gkgbke=^^M%jjE!pH{FJ`J9I|33BEcWi3E6aCT%Acw=&`faKrcx` z5nQ+B?^3hpald4*z56a;=Fi4blAC&H@<^Y3YyUP$pE(7e=w9E+z`0S0Vu+_y;pMo+ zezpFT<~4;~Cdh#76E&x9XqR;hF+d&YnBj`3_k6E3Rpcw>h&i;oe54Ira1$(XQ>OdM z@BqmZ$L|M4g)ysN+di2~wbZnOsn24$70N=GPUOExEk-?> zUMwMzXvu;DrZ8U72awU2#bks#mO!|?fCM6&TTZ8?lZxH#Qk$h)V_H~MW+31I^1$Tm zRUgCSKU7@kQUE{#mBYw0xgv8W%{0qXwTH6|0gOca+0EWvU45={S5u|=9oHC1o8dp) zV&Uz)^EH3XT}NS8m)m`Ge&0ylRlWVaCd6w&kvPbQc|>~ zFZbuf^p7iXi2FzUQ!7fC6F+lTe&eub(rnjX96aUIqpypWM&InkQ2IJDZeE8mjo zz?qwxfbktP^;kujiCgW&?ljrVI81p9Kf6+|vDU0$W(@0QAE+f%TUpdA0yQ{T!OU!8 z&^G~1OlB?_0JB`}#|fytBDb5pzw0JgUaJx0=Vf{IGwN68SITaroX}F#`w*PjZglN0 zVdvh=Q_p=h_>T^ipC98U+2 zjqB5xlaO=~7-Ud#rQ^`@?sq~LMP%1qkRD2bm_L^2Wt;j;f7Na%9NU4y&SwBK)0N`p zy}J%V9`kovI)!tnJUlOh0jLgbvu$5~R?b*{vn!bpm9seX{N|lKG*NUkjA$4npj>!j zb{FB05i4o3vmim9!=!wvI2m@JU2bBG>ru%%*#p~9`bpDZc~9w|aj}pUf{;JNs3F~x zb0`^Y7w^ZPcUDikd=o3oQHX@0`rcOfN8KQ24Zy|I0YPVfNpaaB?d~N#PsES`)qRcw ztdZY?KfJxF7gC&c0!6Efe4FouW8oJ!N8J+X9tpPOyIg-h!}1T7W$fzx26NPRBE-+s zfmgr|X7j3F>RlX4`ab4s=b#<;+WE3rw zPWPJ|qy{Dzg?xd5yp$Qg6i0&FC{x~kx%EHwg`7Z=S!!5dA`mlw+0Hdv#qk0J70``o zhgzExaQWgHpZ(8k2x(P1c7V-5SPAk@7;e_#cZ~GOhD^)zLTr*HymO`<5P-cFcV54C z>aK2M!%1XXzXCP-Qs&BZ#HY!w!U5fM@nOsmg=Q-O;9-g zK;EUB3E62xB0@YC+AV3xL?;7QGBem~mzz>5*T0C*dUoQJbpc?;j`gj#g{8%t^2dFV zOZ$u4VfMX?beVBk@WnZVnDA0QC#FXPsGjICn|?kbSQgq#X-cG3S?l$PGI30k`GKMv zR;RqMdusLqUWr&NaGzfAah4ja&$c^|Dnttuof#Jp8iNx2-$)Ge~bS>H<3By9W&VKr`hZrUkU1MyF6b10D&^}dblNE zGOR8>x-NyEv$n!|;e45JuiGq@nl!%c23-Lxy8D%@(}c|?K4~XfV7cIa6iSV*WVJX} zW~gBr5<&B{KzvzM02I1Ei{IPNCHbFt3u@kLb8t&CQbeD^Pu3j4sMeo(MwqZ}hR1zM z%1@gUiLB%H3h($H8Z%DSoB6`d0S=pStnUZh60b9_CuQv-fmS-UypEnkS(2iIgn&X8 zf|J>drz#p7eEjnTHZSKK4O0dfE})s6(0t*GjXeqS>SGgcP2fs;?UY$y%;Z%=Kapi8 zE*-Uiz#3bhHX%u58@XpA;*WE7i-1QgJ9;q9fEC=q>1MBXxQEj&lTFJbHQRp|L@*sZ zr4Eo$WctJ<^~Dz9C}Zme>W*Ay@k1%4RP|*1gdrV>gimpr6mTWKL$c2b`wBT7W-9L( zHGVMr4H|uq8 zb=GGQ)5mNOb-5p+*q~K^#P@-AwAOJ;`)ZQ-d&%bo9fTA-+bJvb<;Kif^$9ZCw^xJ= zKYwv;3B(~ZNvcD7BK9BoY*_d7=G=(~(baNpPU75mOP1|$H!@HmxU>Sh|N3|Mxv182 z-^9z#H@{YGPKe!n3f4TsCWZ5$<1fOR?ld0ZSATqVacFv8_PhF3 z4kN3=aq&M;@&{wsAA{g0TQ}?LKUVEOnE7lRX;mC}B}*MGeSA(*6lcdE8V1B4fAX0+ zaQDdV@YDdA&--jM&;QcnkR1H#F!C}Ie}<>|dU@5Bhrz>|Sv<#8kiOs9|k`DlX`@sg-F~PNm8e=bd;M}D^YO+v@b#29^ zN8Hocqzfl=JiPv|UQfotnODnw?kw2cpIr?P`w#R^`|~XtR0Z>kG(s}AyW;#r32*tn z6owCb}Kzt3O+aWT(IN^l=6q3!OC7SR<$ zh&Sa!6`T~zd9$s46VjMBJ-y8$?$s$|MsCekzBaKn4X)|?FHQohI~roKnS3wijCG?C?6%dFU-_;K}8>S7H9E!E*G9EF|6 z@0Dg*JksvqSr+ivOr-)Z`SW#gILf+Ob=`!p}(VUjDiUA@kEl4NaOJ7<99H zQc_Kr{#-G8=EnipwBm*^0+`Q-qCaV80fgUG6${n6evo~I~?F1EiF3u;yTPsi*&4n^|NfQJ*9)$a!R z^_ktHzBE@0W{bdZEjXo#mYECak5y!$$EQ87%VRs%1=0Ddul7G$s?qr(W%93VIFPWl z$mfp?=;=#o7}>V}29L(j(*}|oFlp`T5YzBNv)$$S{>oM4&aExp*voVe3%XVD#6sJ8 zOoo84U>K$3^3&#_&WPz7kb{uNIL(=o!@%@65=vM0)trB)9~(FK2%(r8h7Vd>%LiF^ z3q8~1D0{?)vMG7Y!C;m2Q?+TwYwY0MH*5_Yn~__~>wB+!`P%MEb@&|eZCvYHdP=^a zZrKu3;2_$p@(!VECSL{Y@$x>=^w2kd+c%ndqTsBPaUE+jz~J>%je1$JrL>-=HPuZ5 zW*wKj8fd8!@1*~%Q|vl$E``Drbv>M!-M2q|ViFzVDd51a;b zkCW?Cnt|4vao#c0NmbL*!QFK+EgUsuq#3{qi_~0MdVl=UYx%kD3AOF?(01zbfFQ9g z-8}uc7j6`bVq|p?YPbH`3j5o>X%Sw|iBhWAxbUO>TZ)NurA|ca_AjMXzMynFJL%== z4EfB*0h?PPEI=5jHma1ee5}&nL1eVwO~6NC!q!2s(K*+!6((ZakoUyhA|ai*tI>Mf z2CGn~#3$}63e8TO14L2{OkWO85bgT$XIjC7-J9s3Ri>-qwpOl%yX5m=ajY^UJb8Rz zX|+6FNoPdYdw*_Y_Fs}{yI%4`uz`UY!ezqX1Od~(1s>@CSt@cWbruIpV_{dA*MMmQ zj_Y9m&N8)D^GrM;`aZCoTmFM9_F!Q1t^xN+5MsRr_(Re0pu?xNEOpvX@3xk`i$MST zztfF>3LCr6*Bx4nMoQ#(P&(G-?jBp~SUw=513X zO3P@$=Li|Z4K#p!a?gx$xPz4D5pz_2=PLh6o;K~7^f#bT7ajy;uHVf%clx))NIXwV z7wy4xvVUxjPFSI&^`Z7DRy!^sJ2z-*HwVA21)hM-Gi)lfqgl%(g|Wx9;c*FaVSfow z{xtOmm~6EDd{+~%+{F0Gum3Sr^Qo|SvV-umT! z5<6#0rXQ+Eb9@5NbTk8J$J?kSw-#)L_dGy%?f`hK9HQbsLV0^kubW;HP%;=KRJ&Bu|_W_TRHkoEco5zQyU%9Y=l< zS<^1Zd}2$65k!sh?m9fN_rFuv7AL`>O9T^eyoLPTZ%#es%6v(B^RlG{HSZN{L#XU; zxOzmo_<}}EubL9WlD`q@!?7iHO+*4GZzxEU^p^$b6O0!YbF(DM_+B% zEPQ+)nXxRDEBHtdxJjt)D8=gt*62-37e3mH8aR!K92XyE_7~ zz<3KF8x^ab*o{h|mRRw~Zm=eCRwH>@9a0tV`3QgZp7P$^vx?)NO_)Y`eWk~qWoK9G znswTWqGkH=3z!kFrP520pWeG=K|E$RFQyoq8YtESXkmZ<^A2}Ny4c|kPCjp8mQNHm ze4VLZcmKj>j4%VLh6bRG=2i!SYHH2ozllo*=Z#5@>vE$Sb5=?p%e19G!(sXf1|j^I zk$)akGHYa1KigC~PY;2f13axW8`MRjwDtVWKII!3IsODPeTyLiOpX)Bgue8>liRGL ze2-zi)axH_)YAFA-KSUo7>lmtW@O9*(_)9`xl<4?v=<7?R?OinDP{4L6-+*A_+KVF z1p5_Atgo?nn@)PgXO$CJ*)^#axIZu(w?JKErAyfr7Ifm~1(#HkbHoTwSuwg?>p-wH zW>+LvB2x`X*=A$cdCU0{ujCUhg(S6JOIXFb19jD_<$7bK{C#V0%vHaBIjs_S#>zn` zAGyux-MWn}vJ5)R{X&Byk?vLDi(4|be*!PxI^Hgxa7P>;AcckQy62MCf?zh`*YhQ> zo?c|e?poQmb(@iMie%B z4>PEnp$O~+tZi8qP#WGnS+BLQ-ZCWfVzvFb@RE2&pk3mAZ@DEJHHJalavM0wX@YI| zeEzuo=p8vaKq7UxZTF=rSvgIi)FLD;TMcM=e1~{_8dI*W{~mE7pzyuTOW58)!!XSY z?rBqY_cl%NLQpvC=mnPe$rm?Ip050`_Z%wp@wv!v6`C)}%X;w5Xp_?*YT1tRyXuFR zw~NDq*=X|feM8>_SqK+5cVI8qQEvbFBO|SN>H8Y(pV2y! zwqW`-5}EFm2wFV?arJ&wyfAZoQQQ8IRcTAL5Kcl!$Jm&4Y`FXIkBHucsao7_Fa(NJ zB4Gf%Jb~YZ7b8#PYK~2~|2U|=IrP_Z2(vEYoHh<6@crl84D|I94yPs zE?!&@w2x*`tLk@0uM-fE+-43W>l!Fg{od-wcC$;an{pTpb(G{)W>F%r9Mrxsr6Y#b z);Hs@)F7y|4TrpitQl+AmZ=8PPa=zx{B@uLg#`ZX(<5dGh2{6TG)a<4Pw49Cs-Wgu z!W|9tJwxazWB_L#+|2Y{brS$@|>UgyoM$>D*Hjcsx>9A_u zyObpjjip!+XwRrICTB4b^yfN-lx}brgdNI7(q-~aZf+B_jBa}V+kjtbdyI-E=o$p$ zc>RcSGhX}9h00xr5|YOs@1cp<2n!jv$~`!dqRmZH>P|9~C&5}em9AR10#-7 zCN=bTaTh0C42{hU&hcjgG?sGU9#>3|@4nZq{o)f3{1%8f5=h2MCiYKTG%JIzaGt&L zdTGom3XH@zMj!ZvN!#;DvozxKWFV$rP2oRKD*wX0P{2QA7p8=Ucd6&hi;DEGs)qxZ#}<>Ec)JhcEKGat9c z8+bq()1G*-EPFKKeuAN;!hSkkC=7qQLh~{6Nklg^Cu{E=O))NSjt3ETpC2W;!;I}v*5+S>UT6j8i*2oQY)rZ=J=IXs9LuRT&Lw(&P@ghI9dxGIpl8)8 z|3ovJYXqOE=R_#8dck@BAje@mgRMWkecU-aW zJ?YwS^dPCKbcTU6#3PdY2X+Q%PI+XDN(5*0lbJxZ4uJPF%O5&@8ayN%Na>I+QRdYM z=S6T*Ok6MFz1`7i@(HOD>@4ni==XT0TJo*JyuCq1ksU-x((vN|sM6TVbhLFWjbOHJ z%dk8#H<;aNO45zQ47_1QHSF=o;OVK(?%Y6oUL|#^F~|%mozmY||0m$SqyC$#?=|e0 z@+1%wu?jqM^S?T$Fo%q|G9LjESaXH1N2+9CBv6*_dkuYPGjDsFja7ITlWxIpUg7tp z`;=VZf(j6vDG);h%i6@RRGa`D5fI!jJtTty5V4I17E41E4f?9t=Mcc=a-V)w(bD=> z2ry+U3Jz^$dy%pK@}&n`=4?LPJZPt=Z=6yy_jQZ1>6DhIFjD~+`lBip7c=O=T_CdT zldUlh9sq$iRwcaoqK&Ena=G2u9!TPrx*82GZma^@5;XC79DG@F+V+I z78uNXqjZlmpLElI#+@@$Y296VbW-62mDdLx733fLxnBGiLCuoUAk? zBi@3J85me&Z+n8wQ*kvb z6T#GYRU2<#_eL*9W$dO6RC1+aE8^F=fyRIUhCnVim6Fi~qyQECfj{Rw#?CEk?kT8_ z?_A+ZZKmy*luHk^Z5@5LXDF7gjNZIM4H?~7U*lWe{@oyb<=e{wrL6f6&NYAqN6Z(v z_LqqYT`bMdg$9qb^Q8lUk+txWQU2o4i)5c?#{vC9TuwR>nJQ_y9T}B5HNKGH{b2Id zEjs~S?%koksW4khoI(nA>p*P)=kPJK?=3q+&;=7;b{d_Y!w~?oH@=kBc@dr2I=awk zpaXTSCtMOU^sXqxs{3;#lAcaoL$H)8tfp$>IIp$aQ9d2wI)Ri}8()A&6xVNjPj2_d zxaI9%hYG~hE!{o`8j>t$+Clk}opZb(<#)o$v0yB~=8&+@ugTDSg#vZUF4Ii#Yn+ND zmHKT#K%vgW+Vt)%f7i%{KrvprpUXy^VyC|9^#aMtu2w^oBNE z5{BzB&h;4@OHc{Q3^5{!d&T5UZb*jlUWY~)?|pwE+oUm}Xe>WaGW0sQ8q`RbZEMMn%PJR8N}PRiCGX>T^M7IMvjZtMMHA<|J;I{A6H*lPp%bZf zO;@>E-Q`B8o2DA6E1-^M*7arF$I_xM^6K z8fZ;jPE2S--Mllue*tHFycg7NMvA(J0>1U@>eM#GQwcj0`C3k_9=}b`GhTW++Y=p^ zQ4^(@$@wNA_D$9toO>olryINq3^d3)8I!ykAvo2S?r{H{zthdl?08PzTAVw-4Mde| z{Q_PZ6z#;aTyCS5S^jaz)iQ*?r^Gkm!zr8==2rlIlmIarJQjB(Y30{1_seyjj)-Po zT^1G^JhE+G)Zl)Wq)NMs$ra({Wc?dnqmR^Yc$EBCZsb{i?3J zUjj+zx9~#H%L7Gl!8Bw5K!uxjA97i&Q&XsHQM$?;E70`9W|d);nr(1BmYvraW81Jx z%dCyFetSJD+;yyj=WUO#K;uT@HtmZR{c_S`t5fGd5@O~v<12~}!6PiBuAGW#*Rpgd zt0;iq|Ah5u>R`GYP|KL0Su|sruFsdJYT@`RFPL}hJ|<LfUL&Nw^J_f{o|xr_BP^|iw;bg z>s~pHVJT1*KQyZ)lwHu(nb@qcZ-8100K%J9%9p3G1iyk*!_iYS42#?B5DtDv$;B30 zcximpQ1rZUp5cRi?Xo1Z(VXphm+$@OLP+xgnjo6=73V-R-QzUlJp7HC4*Zpuh>!=x z%}ZZm5f1YsH4sKt=Nhx$VBg2>ylhlMw@Ykm(1Y=pIPUTo?dXBQ1pQx3<6_{@Nzq_+ z-eFF~;&Qm4Sy~tS=gj&#K#2cf7IE?#`sq0!VF^etPZ2Q5CnK@O_FqpLy?)s}X|?c{ z{>Wa1oos=QCCA0_X_0Ti&oa>JcLMXdvnzO*^~UP9rnj23=G$1I++Q3(dlH>T^pCp=fQ``PxYTDHKZkV!v=C7|q+7qUmfuf9aBH0WiSQ zR{oOvibuySY#vGp(SuNUsos@im;6GkPVN2*AJHvLg&^HQb3K+!EOPltccfWM&hozB z;yP%kaI$_Nk*CBv3jPofNGE;S;TEH+t*R?uC3ziVFQ;l9V;LMB6G@RFS%ckI6b>MY$5+8*@N!&G7tu2((Y#Fhnj|LMlu}m8{2B z&3u-%{bY6Mujp@3NzIBy3S#ZlAMjYID);5|UoGrdOE|DFe+@dP?S1rGFU?XbX;78c zWBy%t$L;5#5-&2@hwyf9dZ$d8|7Ce(EEsBR6V;g6Tb=3WPox{I8JI zdcKy2N+rB%SR8N7^>G|H>b(+Pa{lKRh{6c@%U+AG+`HE@mN%m=&!G;UkYMXp9A9AF zZ&dxWE{=KlE_Q5Tc+=t@g;^6Zrz_eFP^jD)IRnoGCJl>^a-(0&Yy~|dM@j^cNeQSj z?O=}p`d-?c;afB8%m}3X+tCMCL_<0gWW_d%XqUnq@f14aW+_9u z|MuBe7XHUb>E}F42KCPrJm~zlb5^EDWPgA_JpHsRctx>bVq1tJ_F8PbGW>&Z(FxYtyJSh9 zvkh$_;5g-mKQ7{-FGfbrzQ@~I4AatbooOH>&0%GgN#!5?kX^<}pTfCbN&J&W5$%8? zg3UDbL59@ZzdxvcsH;nGy*P%AjYu^sm53x2?MWvpF+%fU*l371QU6`$wdT)s6G#kj zi{aS)hXs%qOQOM0HBy*fCkqK-+5lXZXWl~x%4fW?b4^s`5?I0v6L=4GmGi>?)Ee3J zY&)&oOj6uS4X&^O47q`dhZYdwRe!NhFDG50&}|b1S2_}~9A|YEeA$8vO`|T>r;Yn78|6S4km|o0e(s?2w>w_J!O1wbkl30UP>Y>PS(y8l0Dh2@ zv5bQg7V{QYS6&*oZtLyeBVQM6BqFT585)hLSk01DICh<<4`kEDIt4=9{TzqqM^=3n$yaeU%NSfM$x z*@}0o1R;UxQZ!;bYfv#kWM^lo!$GT~18OO)^`J`Xc*iSpwMa@iKf$*@gMgCo$6a(ZEn6y+)lea6I18&+BJ`U|ESZkr~3Js?yj zA|lESX<>4h{#@oDJ8v_sK}$!@G%iNG+{0F=KG1^V%R!>ZDOJa@^y-C+G1RwSIhdiU+nXEXY!d52}^3WvcMpSS@1G>dOBLQ0*2}3>I%6cSpJ0Ozcj)x{*TRfm9v2uD z)j$*T;=dsx^524E4bo-@jLU649Nf6*m!~D|{?dF@@z>VYjfTJG%l~)%;kT`+)SU$M z)jEIz#aYGgcrE6`B!Pd<1#e`ux-h2_p|;7xGK*JBF@hsi!=EaC8-%p5!=n%tK)a%L zzLQz83Y<>v$Q`mr93Drn{jn4nH32OMLKJ-XuW>!og&xF#3t)14n5~APza^4AuGebK z5A+u`gdb%F;`BM_9BR1N3fum$dsbY6zFu1ILiE;X?JQAIxM@$p*c|GS2Krx{d4!uA zTap&7V>l2UuiM`3u?N-UgpQ^3m;BYmFfv!H+`AqTH?DVwH52anh67)Ue*;%=k2E6r zm(IS;LN$?7t^pkwcEn+t#Qou^nE@PYlUGFW=1g2_zU%HTlkQThHYE&uNMYJ6`Alo< z6BhsAoL8Xs$LM{h6k5543EJh}3v=fKmA>Ey6Yt6IgpgH%&N%>VRAC{MgXOOjU!E9T z{$z&UyoY7s^NIkS$*UKU%74@7hsn#CK} zwEK|tX@3n{xh12$6n>n5&o_&gH8&BG{!(`tnU2X2G(_EdVRu|iGgD7f7pDdXW&^-g z@bV^Pa(ZXKrR-h747vk1(j9f(WOO`7NZ&lF{(G9>SdH}DZjN$pYe=<=(xt82K^xbQ zrSni6!2-eI=Y8LOD#((4?!d!Aro6efC{x*sW)p4w5WE}|Enbvv^}g>A+Zm8cgE+!z zGd+eR%^V0gT+o_-J7@ zhu}&*a;Lkks)MFPcnp1Fp?cNmQrMBdd#~TPh2M zH!D~>cvZM8cl>UwNk8hLYWGlXw?m*jT~V*UiL;3g*1T@FE~^p~GmP|*8E%9r6hpZ4 z8xAM_?A+?aaUeX70;XB1J1VHNQO0%G*zaI``fx%|w31bnLPOO1eP2qtxJQT%($R|( zn?Hi(<3~#D`X^Te;Yi@##YM@Ebv!$Xe5OO%RDCN3Me$RiMO74uCh>U(gi6>CbMg0S z=>{nc!;40(FCyJ1x$vIj;9n#hcO3{Uxm<+lw&U)zqXOC6f0$gy{(|HN9KC3UNR&If4;}2ozrN-gl*VcKvPp0hRF}9hen`AOR0ZpY zx%qM>B)6lH|F&;JIQuu8%HQ8QJvk$4WLw6jFZS3}^X6_H*>G%Bx%2$#aI;vmlQ#j^ zA&A6W^)}yq#G-wSBcA6QJkK)9RA?(bW3QgCftHX+CqiFF123y&;|W)ve~(T^2PO3i z>+DD6a1=+wcq32VG{NdmDvxi!im)KP2(ge+qVdOztdTzi-lYr$2IEw{A7VJF@wx=@(%@7|~+w~2A z_vn2na}Qfd=I`0Fk&g4%_qIGSgJv)+T+JdIsAQ+fg{u!x&ik%7PGnkezTVg~4UaTP z37~GxUD4^{soj*2Gl2lHW8Y+Qo(=Wu$8UZdAt%S%E^9rSCm})Ko?X(iJ_WK3gI3= zmxGbTI_~;I&Wtw^ro5{M>N=jN0+BF${*&ITyF%L?#{4_{ z>vh>7+-m>U>f-qo?;S_*#UC$5tbAzxY5_cJs-{H zybP;&$vuPVS8{Y|)?57xgI_wFryVRJH5p_b+12Gnw^hM-AuR)OPXS(^#U z3`u=`syno4VC>N|hV~l=#UN?o-Crq-{#w<-!Eo_dYnV#IP}o6Yw@^Aq>5!-~jm6n; zQYb;6D!$ojj*0+)xMtK95IKXWcp=}%760(9vv<{>M*n{G2anyTD}PL`@?2xW!Z{xr zKg5Tl!_aYP?aP(1P#iMawQ+U2QQ_ma`r(_t&&0WI9nWcf07qkBatJHX>Jwi38m2H( zwR8FIAe|tFFwToE0NfM3?*rf?ZCEJ+qd4;X?1ICQ~KD=5zjCnDJH7d~o>VXY{#= z4*5!YED`C2JN7vLPIcwp!PbADCtrSKOOEVQBSbZ&$kifa!#T40+5QLbyf1CljaT;2 z+U~wWJUgg1Agm(i&FGDh~%NN-V#744uLjZzo^_k8m)8=aW_fnJh z=j_x60S~k>D*|FF-cj5vr%nid9-eZC#xUTwdoTiE26C1(<m~?d{X2TMd`%=7=|At*OPbg$!)c`6{WjYF$G;`Bt^lL5uO_2|6@jE zS$=8ShdUn9p>tSX!P@+W{cM)T2#MHfbT4McNv0#yie8W)Zze+SAP}0YAGYpw9xTQ$ zCi74PJw_}|4TgN)Ek2nkQG<2iO3|<^=+d(x)n6FB-Ij1+jivk?wfad2h>7)#q7#fqq+(rT2*9Zc&mw&Zx` z8CMZUwYehKonLD`QJG3ZelO+iHbklmDZM*`yB?g=ZZeTF$y4+pw7mnz7T9-ylx$(v_wr^oZADHkGOM@ka00JL`#{)e!0k`s^Xu_&xG)4b+5=DHX4*VQ-lT@<=hIR9gh7&Htyl!06t#H` zx-Lss^z2lyQ816_v*1@tkYwhXOh;|hN_Z*$x%^Y7ec2C1b)&9kQlkJ}-_8|HF>Q$l zU58{n!E+eawH+!TaNDrVN@fbM!ckYRG7~G&x8Toh9q}O-qjdHW=X(u~i+3S|P-1-oHzu-3w6T2(IPw5jC{GCDGp*l8v)S3MY zhD^2_EAhV)JHaH2sJOWl>$oNxzEi>}V&xp7HDWX{)M&6dU&NBP>xO+=9i7c~BSAOT zpZn4iyKCpjfMG_&Ab9pd-mDI>(_;<`UlWdw_i;p^Vt?Iv6>II3LkF2OqgPkiN}p(2 zh0~a+$>7Lu$qgn1OiauG;a{KSZSj;$Qdi#7G?vMD!0S_<$=A=6ro#a1nfs>Ff^6sU z#@;~}MWJH(h6F(^5aNw;$iNutv85%k>@5&BDTV;E4g{y=GDOHmSB?1lVM-mC?)?)ng&I%}tyxucyVn zsHW+jnIPvNS7!Uia^(+#M8D+3WXv##9fFUXg{grjGT>%)3IjKr42V89*YhP_r05rC z#<)y8yp4|{Y_9R(uSI87yrY9bL;CtAyb&az>h!(twM%AC20ewx-{h%{z1aP&GV`fK z)bvRj!GODj>50w-CYC}+15SV*`uc$aDarYHU*1ZqAkz!u*3H*buKfoR0w(BuNBY}N zqc)FClgWE7iUQtn^?#s?8M`FXjsS1$mQ{t19AFIl1O%Xbdp6K6LYC)i*Z}Kz{p)#E zI3{;EX44Go2DP90OIcm(g9IfZ3pv7&90o_NT8*ExUUIJf+#B)|O^^8%;HG>4U2k*| zA!n{C^O}I5GR3rZIh7-&3GZ4(p~{V4cw72R(lI(CK^?%EKmOnP%CT%sX(QW+ig|bA zM+CE*;9W!QuanAUQ^5*EqvuT%7d)CCd8(^~GKtOp!r_tzYrN#hQtdLYYxHWhsUCx^ zg=j_d>K9h2i2E0$)gZZ>kZHY~a2euWbIN2=`S3!R@I%}RYKlt@x6f?lma=anc{l;o zp7G=8kWbqqH&HG(E@L2rpLf;X*5cDa>C%jTEWqsDj9$G9QhprL^`^q_R|jqmt6(hg z?O;0Lj;=bUH!#pTFq9Apa3RmX()b*$6$1U95)f58v)OkTX!g||0^@A0=Nj~4p@e0@ zH2CL?{Kt&gE6I@`6{EFRwkem&(#!@SG&3UeJPrk)ZMT_puoFhWam~Xq>9D|1=n_xi z)z!aKH}`q+>ByWQUIA`?Kw(-4I=27TA*pyvyvNGy){3C?VW~R^*BOD-u~FQF3>1B^ zBz%AKTWvRX#BebkEG%)`-b%Vf!zp<9joTw(oiOF7sPQwP+zE#SZrr#GRZPllL;|fhO!APKDK0$aAe)Wm)Z_VqChgJ>A=Fc?_M!!jBQ|{opoolE>_|3u!7BGe|2w2zS!EQzv3E0KrRK6L!z<; zgYATdj##f7j+$(NpJ`lL(%>Kp5>kL; zV)>o$^;x1^TG8mb37iSnycdh@ee_V_koT31bQM^B{Ddq$LK z=N$I%7KJDinVWJjkWlTuA_qbLjrc&<{|^*qf?9^axwnr6eYt3K^1Zw9K#>v;`Mql0 zj^}R_Ft3me+CTg@qP%h2 zJ!4)S!gvk`D!RqtDIGt}Q}t3s43RnR)gM5V0)P2T30XI}Arq{E=pVwz1L^3;Q6w`? zyP3h7a?Fkbb;Z#7g#sdK8WLMIGKBi8GWpAeWD=W-T=t%;)mMMEL81ZZcgd3-;9Ljt3{t#>y#o z#(-SY5cc70t&YD`r}G3Z;o8nF-`fYP(+PT4bY2&AFMEHxT%YIph}4cv_`-lB?ft4q79R;afq#9g?V-x90gFDO+VR-8`xB{EJ*&Osc%HLUW+` zo0VrY-6vzm9y!lld7iQp+Nx4y6Om$_$8qkiKK}TfYx}DJUwa>|cds&=c>&{iss_vd zM5OPZm3n80(`2Ie>|KRg*=JPq{eO|BUQwJ+8 z-J!jB<%2Y@RKTf2y{Eq{fHNP=T%d!v{>u4D&)a23Q3xZENNf@R*J}?`_m|gyijklbN|K!~Uoq&!B~9MY3P-)$VEG+m7blL3Fs0I-?HkQD2qQB4-*j-=1NR(7wPOlL@n~_ zxxy}=oLS0by{Rfp!Gjk+h+1UcH7~euvmyOkcRuFwg{%w_hJptr4k|4-1h!hz%754i zk!weoG#du*?gW=8`lNMskBjRh$h)o1k0qI&Pg!1j=~$;Vp_4BX9`1vXYhc&jZhqK$ zTkkKVP7nMJWtu#{5C-6HlxpkkS3+L41-&vE3b1V$Sqbo%e02;u5kKQDXc|EVrZc#aOi%+pSZ{7S)G`?sP9&K^;(-xENxA&iQBdbdNz1S#_ z57~Yp!Xaa$@kztOl210r&TT8-jcc=#%hsO>0*VH z9|J0gCEK|6*1Ll<{PEu7p$k6)L4X||So4!?ir0NYP#2rO2mQyq4-za}trZ^i0cR#* zsZ@4X(vR;^&m!4=D?Aucq+iOlqUHIsK|aRN`S|@yK6@#1uIZ2cWIR=@4rQq_%-5EN z);?QB-wVETsyN0(Qc^fYAK=$@vE$9exJT_$R284=|HgI6wgIKLgx|HPZ+1V(ZuZKFthMvhmsTJKf!-7d>GaGAf z%?na&`wk1ZCFR!%$Xd#_-spbMPN$tx(T9l=WEmj$R3?W#=0g5%cE?J><0Hqc&lLV2 zh^oTVmBp`^=0y;r=0~^_fx@|me(p75Y!;D}5dE?AItEdPy#PnCiu)oCk#xdfd;o7J9VVjPW-#kT8z4b>Xl^6`)?1C8^u5LM` zOioyN`#)4e*q-4L@SykggLyqAblQy~hOa%L{^>cHVpPL#-((uF+g?b3)L9ndo`NQl zerY|?TjKT9qI--Nf#k%Znbq{%j`#e^QBnVarna49lXXlV5#=m_Fi8FJGr3CDdJsvq z_WOuBum{7SpqBX=8u^XHKmcth!j<0qnA;K5AExgm{@ zyzXbU6)mXRqsb^~fP-?t+J+72Fhf9vFbL z+W-w_JB6O?q>n#RHj)VIng>$*uQ?yZfUP6Jti7_*lr>&doH3$vUi}X}->P{$VB4O? z7polqG48I6%~}cQ;Y)|lbKtlS{0b>Du(s=u>cWo2s0)mIL0`YgU>=<2!4VI|L~u~^ z_Bu1Go6w!wHp9Rue}eQhe(AI4v-OnOGS0b#jo7N4cp}dc2mtFiZ{Ygsg}+q)38=I> z3?GLU4G*U__uYnIrN6cz1gr&7vRjLbdxrM@(uKh!T?#dKowZ=h+`>H#&*I#nn2ngd z%aRcH!O3fC(?&weJv1f?RsC65L;}x})1NOkZmE4HITt`9KIicAuYeYnX~f{*2!*n; zs2%4mWRH}BRNffk4%XsTgF{?kZUkETw`Ti}_Tuqsgox2YF{OgrTPS*0 zXB(=+ayaG;@5Nj%z%<}f7$63W2&wDH;RKHf(Vv`D@@DI6i2k(GUCgfqbA-6Vl9zJ2 zN54B&%uUQK*6IGq%t?^DB}51<2rU6kPm9{fJt{f{meHD^%!mh~jDnOwdO|3Ibhe^M%5ZQlKq66k23m>F%^9rj|sPbRQ6Utn&p=N@>n{Ig-YY5$zZHY6()cqt6Nz<3-Ne3!kw z!t@W9=iHSzp2FQCyNMVuyWivA z5GC!7dHuh#K(VUXa5k;zXRmFB#(;PdTO5O!XG9mlxj9$gb>@B+f4JRbD{43m&RGNw z3AqP~FCJv3{d?#Y*2fQC8XT8TvO*S`J*XYSBC%`6r%av5!@>MARuRW8IHZV| z{>11T9sE%MiumxPFn2N-={I+vRKRKaZ=e7or!bs*{z2u*Po@VKgpF9{&6oWPZV`>1 zNE;5t*#on?wfQXSB}woCP0{mOoMUZFG_R4C@;l&@S5%89aV**D0X4GGVMi2zSo`&& z!G>~g&Ei8Ir#qsD#VS{ko6^&Mlt(52(un+tXbnhkY@a0V~auz$^hEh%)JpDX67?~ut zkv>32JgjaP;IR`!2xxuc?oGAkXI$Cny~V|frTb##d|B*dZui?j=f434a`m}_YvWxj zh>Y8;+i#v4GmpkOz7R>yK1=FG2WrP-i|&P9(XsNAM314Jf(c+EA3Ply8&3jGy5&A) z!jJPZQ4VUQ%fLs5Uli9bYHSb!P=c0&33eZq!zLXX=xqvzQGJ9q zqjl7;^x*GTdtdP`xp{g{g8@sj2Qug4z{It7rL1!`(LN`YdGXoo5X&L?{n~3TWzVfo z+)b{ro3XYADFE!P9j=*V&E$1Lj_*14O<(dwY7rGMM6jz~2X8*b4nf#QINUx_%SyP< zM9@6xF6#6NLoZI*H>r?r6?4wEb02Q8z9m|8yEJF)YEUYSW71!lxbZ4}X_UO*8o=LM z+2e=enhrx4yTX7Z<8L{(a^mbALO@f-9h1vHW;>$S6v8+DV9S~}?gaJ*AWkB3118CT zStgUXKJ*FyO~*PxzKYHmE1?*SEWj63)HP@?>V8~Ifh z3+chh75R4{I8%jn`H6X2E=cYy2(1-hz@89UFDXBbVYO_(9K(uw+Q$6k(%0o@!X0~r zT~D|Sdk9INfuB!yRZius#%T8$Qik7t#ua2+csn?z^%Xo(3lWc+UfgV4-RbA=C@Fn& z>Jrkkizb}b=B41HL1e+#8L<5QiH9y|5leT(>^Nm8L?6o8zm+$nS*~2~P(M~&jJYNG zmmjUW5Q*9>eSSvjpzE>ZMD=2Cp@!KQUN{^Nd~t3K-=t1{!ts5Czcb@EUIp-~E_x=4 z53LnBlaEEs<%3MDhmF9TIss#}?#O9%`#bN(Fr`LqYO%l3;juvFlQ>uEoTMpzv5Jww zJR7HlW7M1EyvP-VK9(?i>GJv(T>=a3Uro)ij>M0ZT@OoCsqo8mxFg&FL+}9gRnWgc zQ?=X?1Lyis3PQ2^g1mLnYd9&4l_gXjp_#o=?3wn+qXu0hjp^$6x{hYwgY$4M=v_5g^Xx~`HlT3dZ!V!+8`Vp3roWZ#9H*%peIP9*x33!Srz<7&Wxl#V z@GRpM0cUx{U>738{{tC-3Z$C-*wrr>FDmE~@e1*AnDM>G4neF7&22VqNQqSPIM6*s0FCdo}gz`sm8YX{7b{oOdMJ|#)OJXY=G zb47;eBXjPzPnAtFiYDB)tF?%Pdvg8u(3>7v$>D5iW4^P+mbX^Vi{MV=f?k4nsWwoc zpS&lk!s9ixbi4+kPfWHdO-DdLBJ2vn^skrq%gxnS$Ir$0IL}V~ftdhm(0E#vGRe^4 zpYNOZ7^jKq>bO1-NNZXYg&;NKx9w{dU3n>mS`~+-16-viw89`p(IykN{HKmKzqjsz z-{q(`MR4N+us~`8vE=0S%`auoXkFk-E}t|VNs7c1_w!Dj_qZwB-u<*#>e{FHl+Z(M za1UO1wBkVa>Fk8wtx(Ug*b6D)S!->^t3X7^X?cGXR{i}Vbk?k^4F(;R`$0Z!!P(H) zn8Ezw3-k7y0EvqI&03e`4wA9!hWA`<+KXepm>tZ32F8-j<5NWS>3fPPs3TZax%Lz3 zqT{h2v*HARt-;FZ>IBHprnTna#ZvH134Z;bmQh*}xGwqhD>XxY05m2&L>=wGcOr`f zH6{Q|7X5-cT2)n|Z>(7!A0w#iY3_i`>uL}M8^*8KQ`!j@`a?7sYvv)-P5X5W_;Z# z^=y5(douL?1N>doGu9pWRJ+95^*2`hDRN2pe5Gb~@|Uc^OII4U1Yfwl)qws?c1k zxA{hw^I}AQKJG*O$Pa2Xn0RGK!!L7K##a*vCb!90YXyj@V>|R=ogIWiOTG_IBN(CO z%wwh4e?>Q?jkR>=Q-7=QL`v-Z2>N{3K>0BT6Rt2=X$TR|_SpQphZ=j}&0NG#*M-n}bD|Fy+`y0lISWwA?y*#wFXp`EZ*iOBn@&78{cv$oD*@6}pbn zX*R79&9n?Kvzv#dkWA1w{dJqCr@e98F2)<{zR&|HfSW|JN+(xjrE-k6A3i& z9|eqdPEG~9S7>^DF&zrvki?FCkg^hurcel_mw2cK-b${9bnLd(LW}IFXd7N z2Q@GIryq6R5TU6}>JAcj*eLmn6$yFcqXK|C>JTsXFnSuVD9tNoPg$qu^1W{y+#j5K z(ck&r-!}#$Jwt5bnFWijrdNU*y$x$;JLSy)_m_g>Jyupjr6^Lp8- z*$v9jExq*WI1z}kVBCNw6*v7%v^uLvRBj^k>E*J^OQibOR1PIY3(wG?6{D7b8C=V^g7YOd>PuYg@m~+8 z4^iulrUSuC+k>ae&sq_FdfOG}$)D*Kq8hSj(tU5xbqke%eDDs+nt|Oa}I< zq-laD95+2om*fmK>1C5AE$bwt3tl{+7|OeCEUs*aG9NVg9am~i@p--}7hVOMsrYMS zb2+CY#vtPRl4h`~roU;Z+T-CTfhOq@S8A_~g@0E0gejev2JF)eTD1QfxZmxrQ?z%=z%i|8 z7E7)<8oaw`&|~{vh=CCFci;U#o0aSzKh<<~>_3oKBlHuONnE?nT=5uBCTtvzK=+^8 zlDPDz{Mm!u0UzbpeOUHl>TnElpd!fc&#RFyUD}&Udw?@E!zAPE)t1~8z0q!(QcRly z+mt*gf1%)Jk@L9q@z96Gz7-af5o6r$yNI1{>2>d^|AG2a?oT$|yke?+T>v_}G!lc3 zj0H86-IXE-gM92L32r2?5RS6ANDZ6MY}skak$toKIuVM3BBW)*MfOe7$t8Do9?&vY zOU#cZI2m4nf;4Sl%m=_H=U3T6qkm@O-LoRy71bc=02z1Gm;i_+_ec(qXg)rjq+gys zpr<(i`V6>J5V2W4^PTh8@xSgFHb-h|EKOm`2Q0d3U%Ht6n-;f}p#{N(*0SYosz{&f zeACCYD9=Hq*u7aMdK1VtxH^SLrKNOjl%(l>tX5<3J*J-|a?pY+>%dFx<0-Q6yedv| z(^vDTLa`BBJ@A7b*d#B<-|*<#mOM5=ku+|TguH^(GM_z|AoHI50hhWZw~m-^JYDdq zY3c}?LRDdHXZh>96PB$b*55wA=Vv5{yeu5{nm!gr5c=yXx9ib@R^iDW`rApnOn>Yd z;eB#e0mQf6K;Ph{43g5E(z6I>Te94lwLM4uJ2Cg+z9{lA1EV- z{jUa$UctsYq{DOtrFbClX}O0!Mg0+L^wKB!`QZ=r8XrD1!b_dIZZ5rzHOY79L<^16 z@Y3`p=EyF9j8sb>$Ev^HylMHDg9XObw+`rxO$}h|4$fI+c+=<3Y*!7+iph896x<%R z?S=ozRrkL1_P0E0dS*=l2#>wO>3%>Vy&U|EV}!J~LD2cjbR^eYUC<~ckg#i>D?~Gq zuKsrwQ>wKx7iZiT-MOEhr%Ca_;YAowkXT_GZG9ZLX{sZh;%!B0qK%u@7G2c)DDh2H zn;DzI@%4>d;UnSaj)ZhcXnwOBP2J};-!+#70Gyd#E%APQX}_1R6?$F!{@cLA7&TAs zs0o@M{rEaD>aXeMpj?j4km$D%JEpioY>&Hpu)LYEjtT^7^LMYj`AZ5W>QWPQL>iHU zr%p|!TbmxB(<=3i1TW@pjK_{FShBWmHQEjc{JoG&09v<@)nW_7l52E0+t}tJcn!X~ zVg}zErihFjIF{m=f4S?oB|J*jrZTs@=txd<%4ZHUSpssBLVxvnRkr_;w4^s0UPtbZoT&_s0s z^$hvq;C?$_AE#Pc@%GR=k?E4YPzj82s)0rP6D147Z?~A5N)!4-sgG5akTv6 z5Xa`10WeZ4=8@4j?QD5MZAE6Z+kx;3U-MwAli@2jwVo}Oc<_FvcgJ^4scWnfg)9*k z1>pRLZIrjxVEJ#kxhFM9!zIKPi8*dEYm0ctq0U#hHuDz_gbj7{#WxT)QGq^-JcZECy-D(d$ zRXiW36+mFL`i7Hgz_J-hw>6f3g-ndwq-X6uBIU$vveqka=C=9i%_B8sh22xz^g9S` zj8<7=Jbho~PBS)$};QbuTV&K!-^CSJN%GqltZ0gJoA7Q(}XShV4 ztk@s5-qJ#SGIw{Y-)_#lg>1zW<^6}i=*4!-FO|)itRrmREaF-RH0sA$d$-$Cl^zFb z?r-{-xKA*sTgcQsKEJLo*okeAD3p=AXD}n0QS|GcvC;{h>3~1iI>M`rD8TLyq%rlx zzY%dx>6qo3M>1w#emSRT%PHh#{+OlAA;f)^%T{`ph?a0F08@B7*n>=gVdb0`wD27f zY+3v`5Ei>&lylOb|6~0OH^(h1*JCV3^?R5#Z$k>9-~nd#9a0gON{pw>Q>eR+gRdjs z>{d(j-gUhrqTQtY4MS%`^cnc!N;exMk4CHv0Zdy)t&hjm?_$fJorwDy`%V=aGTZlu zI+4oQ?giNn1v$@JIlp|WgMNlMZY9M)W{KOhKxy#7!S;=JSFy7nzASY=S7pkEnJ@Ko zKl@&@QndZoFa`_ICIb?&qYp952cHGGxd)kS0SN!T>aXq`^X%5pN1_a#^MSoJB1HFp zfBB6CN<*m9NhhaVj(fVu9yV)}5!kjFiW8G%+FW{4Aa0QxuW&1r2iK*{8$7>a=Q{DB zx^(ZW3_=ugC;ittn_ihiUzR*Hw z#v8>F4^lc8&=LQxT$Mxvr%NzunM7saHNP>Q={u#9e^`+wT=p>kYQU z@x}}(B|&)-s!w|`6ZG@|=+t||?ha)y!;opqceKb)dP|dGZF1Yvn~lf+l_z&zhQ+|+ z(2_GmACo-O^dKo3#{dNp!qxjADOAggp}TvfmwwKYArN)z2%xJDB#5q(QkJV2l7B9` zLm>f77*k_0e#Lnuf8xC7YW`9S7Sto9XrBQfVFj*d`N)%Pign9?!>z~rz(9xi*c=aP ztx(BNj~4%pSulv?^Ayg4s=?H9+<$!e4|D`J;MP{71lWBR7_hqc1<0B+Vmt-*Qxl!mm zdFsjmJ>8Tmbph>A5`TaVzSqy7Oey~&Eh|5po!$oE5ki2r2=n?K-Demf{X6lZk1EVq zBbE0#YHbA<>o#rhx+UTlJY=dv1;+318$oHqb+fG|P6ML0f6>Ocw!Z)OX4bt=PpAD+ zo2j#vm^d&IDF)aI16pDD)C6`TK z*>WAKv7?;RDD=v_uFRV=87UJpx@H$1aL->*D7&1i#ry)u$##IpDwTHYQZ}{$wl1s7 zrfQ(xXXi5x97l77nenw}MJRou_!yfO?H>b$UwxInhm43^ks7tY=tpK1x1scz#$wRS zD%l=&Z`}<0q3E3b)(f=yYJ_s9{OrvID4bPEi zV_dfSB}qGUct;br6>ZbqxRq=+|IQfL6>jWxQy6t#HBVPytcm95RAfKbBi1O{rQLlx?M+$j8^Kt~1ww>zkhr z%g1jQDzD(`{p=rZP;sW3>I&mN0iVP44|Ni_NodH#}qL5R42I)d#Q$qS-|Y zb~<~7XC)r~tK=N`ZaM`?9VDA~eGbmpRI`Ozv^B_0+Ta~E*{X_wQ>a;7>z0A_=%qWh7nZtZ+m+15badl%J8W>DgQFh2 zN^fIijK{E3!gkfpC%?xUW=t&`c)-EH-zdu#DqZ<|C#C()hR^*|ZyBn#fuWK{fLP_9 zSYOdI^pNMku+<~)OnAp*?Di^g1`ZEm46%lrj(cC!)%KeNvt`4U_QQ5MHZ^C^C^&Hq z_+OnjgEy1N#WL8LTRqCpAG4q`7^aOq9UinFv}P>ql)=%~{5fY+OQY(sQPRfmj8PTe zDr7AZ+c-N>s2%%rpGUQ2qZ#CpwOuW6EaAc znfsfF7DinK&V9>2aa_4Q9qpV45$pEXwAAY7N&AeQkohGiNEMl&j09(K1dXCKZ$lCq z`)g4(`PY_5Y_yI!Kvi_kge*5eWs~%bd6rH!HSEq`8aQ`BblamUmht{fbI4cBxD2kV z52`G!tiPLR7;!6IKJXozSH9mT=ki_z-b@brdj9Cddvc9Yx#$QV0bG>@VOrpv{DQLm z7xtEB?IqP_EJV@2#CjOA(Fd<5;3Ac(K7v537$}D)kJdFPF~0+< zqL3;+T8ng|J{@_8Gy??c-d&((gd|uiVo8%LoD@!F9_e z9W7=HmD`5NCxxhLVai#Tdbs|9+FY&WNKW{A(T9YYz#lr|TKPdHt=ElhDr-T3n>(lf z_}zZjg?Ntkj$|OG+h8KILo4nXmdxUde6F1m&a;gn4JM0xNlfnF_ZN5t$h7XrJCG-}oiTP{y|9*dW8V;GIt z=~ggxU@Q|`Vg;zL_f?}$c6*(+8Eo~Ai37Q6vS@0H0Mag9@ja{#=w8H(#UPNw;hWa{ zQ&O(2IyY7NI+O&JDKsS;W3=|5Ty3~k3ghmd7dGmCLVsjR?3=OxFj7kNM^hCy8`(xs z^4t5yS?{)=bd#?GgZJrv-Z5{gVk`ge(oY~;#+-D}%^0z>)NuToq~rGMMER-Km#QKK VXZ1iTCO6V>faNk%1@hnb{{bLYY`BC~MUq$P%RKH4;{d9z7z6 zh-g8+KHu~Eo%8$mH}9Nx-@P+$?woht%-lOO_us<5bpW-#ww^Ws4-WvqySo7YmH`?7 zQet8t@jX%?5J*N!N=C^BJsg768;-scmP7KCt#t4m1BE2^ld z@QP{bX(;K+Dyt~|#{`d*jEs_k5=>1ERute8Q2hUff4u-2AVDY*fB=sRfKP)*K!f*h z5CFcDlL+rWasMw6;NcSz-2)H<@34B*06aoG0(?ROB0^$f0>V2|06qZ?ArUP^Lj4{c zmzktf06jM>E>{X()ke&~^Ej|?8YHb@9-p^iar}!{M$?%wC;`ovf5(dDzc>HidG5M* z%!%&Z;e==a`2PXH-6#7$!rUQ~yv|XyV9fMEOtf;Il#p2@^o){^c#WGBjcTP4Leuqp)>D!qI zi8#;J$cPyR6G)8qE~t6HnP{7ysMTJWI@|G@DnP9lT zrzu^pX%DL&Le$KpMk_&-ZR$#%c?A*@_(s5ghhhtXu_86hvFQ-0!qfB{r0&)9P%f|` zA=oes-=V3-(aH%d0zh?mdVk>$gcxC#s6%W)l>$n{k*tBbgKv)1(ZIYh{sF0Usplwn z{z7pX13f*)ekO|F=YcB$M7lHAz{Edky#|?-wDfeUi(pZq!9c`0k>}pD=L{5HXi1?; zV}!Zd37rE%^MW-SjYLi3@w_^5W^;;(p+FpMuvTsPSe74=0cQrZdRL~_S{4iXxuffd z0k_Kbniy@)i2nn482fF+_aoKDY=Mdxeq zF6pzusD=6w2u%{*t;EprN(Z2>egp|p;2De^9;X+YmxHu2MYd4x1dsq2$B{sA&lexI zA|KPL8rjl&`Qw{uqCSx z4xGw%oY?nj+-Hb)Cy)(nmddp>eNf`&43}b}wD(50gQORLKCM>(_nPZw$6wzS=57GY?gLJ<&LoC(3WVw=IvU@dDebHz@i#4+i>#M z3B55Km0Xq_DIRkDrPx#9>>>L2pn**gOfjVS*M6fniRKTPq5u8I{H4dIBA>rgC(T2d zJlIw&d2W^Gc`kUoh&$InK8uUA;vGM0|KiPQMOJVpsJEB24UtB$%BUW`Z(8V+|EwxD znsafkTo;@_x^*Q|S{Z3K&PPWAE8gP!3Iz4{dO+PpZJ zkNgdFzciWr3SR=^6EqJc5NSNEx173PjPDP$@z}!U$s#)tUP#eojfA`lHs2}X@Yc*W&wRY9r+Feqs5l6W+{)i_Z{@j z?&0>8XBq-gmKim(sRj-DyqS0*{P2Bvsx#uQb!apb@e#uuzUXYwY{T~CH-reIONlxE zzK#Yln);p9WtXh!s~p^bSd|`{-!`<);2Tc^(gb0VrQ@2X?w(1CjlnV0Mqw7aQR+}G zKJJlbnE|9uHr#6j*sBRwc9l<R3f2( zOEnk@&9$Y)C_t>UW1$uU-bGj|L4ZHWf1uC0kKIux7sd3?28!?%)>}^rz{A&hFpbZGWmc->0yA`g#)N@Y zgnNZJO7qV6#tFGV^Ijv&*>O`fL?X2`<$IM?G7RtN1;H@4*^{mUb?d1mdzhVJ&`=|98U?SkMT9#|x;k^G3N6hq z*FeqHD$YuDbQ5JK%1zrc;BKH=OB#ungDdAlkeZ1EfNf2?sMQ=Cg*n$tboU+*AZjeB z{UMavo%U}%R@SG!{SoZtjgt7lPxA>hEr4B7U1<6`fd5?;Yy4SUml=ZB$G2_c|2(ru zaRop-YCr!~t;D+a(f5Mn3k^p8B#i%#NFXZ$=DTK|U}?jID-PFQQmpMR>c?7=zgmPC zQ|MbaH4=?EbkMnvh0eJGmyfy!Yrvt#0AWr=UQvEf4W61d&IS1eSjnd=Comxg7pYOQMc>i__^-&45s2Jn0->XOjmGyuoi+ z?5+3l=NKKOB<<2xPZV8)mDOz=Oh%eWo0Nf}@2bm{ z+Rr}^&02OeicogTb=7r zfIh>6B*h~XT?owx+94%y+gU9wS{6NkI})n1R1l{*%ygBt&=5?%MX0VcO;Mx3{>k<7Br~>g)&goj5)3~aq4a{YU_8i{k?^>Rh{8cneIqb2FI?kqSYj_opnUFc`zWT?$`b3)&>x8!%kp*_INh)JED((guDfw zuLq8>k9F#`jpq9TDw{tQN~e)V2B=EYR< z*0^TY%$9Y-$T8T0z#hSPRP^GNh_?Uj?A-!w<$vv%u>6OmM}M@aZSYoo#H;1&wUi;W z2dsai&7V!g>yVK+U*vP~MQ6nf7H^+lBeFDy;{6r7bf@=8j@U7o?5#--B7ROiD_svy3)lnHwsrs%)Y$;-$u(k-WDn z5KpSXpC+J9I;np{X!jlFzhNMHfZX-30`>-`D2OfV^^rV=AL&>ecf~fvQ>J2gjqzw5 zTPd@~gY2+ehxT>{RT{Rs+8!>mqVY(Y3V{=TO-&=9cb3? zu_GWv9jS%nr!v#wAf*AnaHTNu*x{SimPPSq;l~M=Y#Q;#V0aR1hWpj8swnUza9==XH#1o`3$hp$`+ zBjF^|zmqN7mfm>2%*@|$6I`&FrZsfIG0Rh2RE6!m<}F&JxcK#E)8mFde8Ed1)4P|- z&fsZ7eq50lk6{4e#H?uW)lzRS`V!!Dx35)hzeF zA!Oit*GU7#ZO$Q3quHK>nHxrt7Ve$-j}OyJrU^Ko(0e}x*Sbpkw4!^J4cw$Eiu3s; zIF+$F)4Dm)xK!>Hd%TTRm4=K@1+S*0O>P&d&q$-5(Ku(~-b%dRaS>N?NUhV@-q!r> zutYB!Iox$g?lF)Alf@@nw$z?~NHMxN#^WIqL$|T+@>nsbWXr8=AQ;wgrz049Kh9Sm zuJd!T%|bHkdDq#%!6Qf4EEcfQ)5Z^<&pl+1o`Z!K8eFgM%P2=&&R-gg9`qeIBKWA< zn7IBzjnhmREM%-xPKg+QcM-o^vpgVA-M<;#I2))3g?A+G=F%%A`*fZH z-L49pG84F$6q5c{zcR>&Bp&#*wJe$bRu}O>&3Bz(nHA`p+&1sccV2*R7&MEk(2`F+ zyl(H19$lYiYkRXOe^>|aDy5cXr|z?R)>W@TF=ECvobp2Epe8}BHWoH|xpPQ)#s8iy zpQ+4S{O)I9G?FS0XG?B{tNm_|8V(eo`vafQO|w-bHS$NRq`A4=1Aps1YTicOf3<=+ z+!I5IrQ}6LMG9KW+b{*S>#o@DmXoUf30}nKn)mTa^*#EsXmb0aPF=t!ekp&SLAnGj zY&_kB`xD+l&NsSg$GNdtPaI~hUpZ4ET@;O3Omd6;Wls={<=<%aW*D2K6ghAj8^aG| zP2;}e%*)k|BV{`&H@D!dQleMH?4C5_Jh4C(sMQ~(7l|F91=AulB343?C+kG0`K+)= zG^}4i+>x+WJCc`YPE54Ai^wO3mzRXa+cxlCzuFb*Sl&q4d?~Ii#oyB(EXHtz`trEG zhdRD=m9AZX$1IqWWIeFE`RI9v&Akt3ryZJk1s*&bH8OKut#A!q2mHx)ePjC`i@*b| zu?GUvBLCeDXaX(AX+PZ=Rjx)6Q${f|6lAuiNX#@oSQmw{QqQ}c{Hm2U`HlAg3<*dz zT5&D_YJfoQFP145c*%V<#d&7v0Qk$Nsl`pupEY2S83plf(|hHWpr=Hb`36n1;qyLc zuC*m6Gxc`Nf$k=!gF^TFNv8x;bo%z3fcv1Y>aC*Ajh07tCSTLoeKCpPv7G)7ej8wt5kRZxg5x~p>>CVFBC|czr>`Fmd`KA#TVdAkt;x28Y=_Rn_kKbhi4mFLBP~RMnWML5y zTkYTIIy0?R$dlvm$l?tuRQX~0^R;8tg zJlh}Tk9*eY@M1AIo@6PKzwIyr1MRgJrO7E&xOmY1oJ}~I$nj(_=*O>Kdx9lBz`5Ob z;?;tbIfii$tdUg{X|c#cYS%Rso9y*8F9;#H(M=-qj8NNV40IipLhD!%03QWMcU zMt{i+b$o18 zibAjG|L|&u-FxslzVI~z&z5}4(%IoUUe^&;?*vLn?y^_;_*Y`> zu}Bgx0CAP__{@6vQ*d~g3I|mEi$|-fOhkI!dp@>>pHOc~Y`cl_chUS;J#mhjZ(%^oW3i z2+?+!i#_^G$Sk8UgE?E6=cgCtJYeR;Lvv^bBlg!0Pqg6H?%?EpdqsMQcpy2veIvZl z&$4Q;KY^9`fR=;LorIewGT7Fco4ndMV^<|*#BGA3p9KJp{0BI$E_NIo4R-D9T~-S1 zh%O@A%v}_{i1SLhj8AX)o*Ui6%ys$-l8FA?{{(48L2uhB>^hm{W_~?veb{e>XwDan zn>o>&X+sScMK7Nqst3u$M#0lO2Pf`Z35iEZ_ z)tU%4eftx?2GA8L7xE9l^Q?P|RyUS`b@@AE?|Z5fQz=QCqNFdcH=W~D*Q`u4N4+$D z)rJhRImQIvN&Hee;_akzY^eyV$P9#NwHq#_H-}I=(GVNLi@}!RQzyY~jT`mDL8*Yz6Ec62 zjko+Mf6tA{HHiq8%BRZg4!Vf&D<8D|S)?seE=`^cqBwqn6v1Xum;l7~Q0WHF)MbRb zRdRnw4ulA4!h)*{##7{L0zHgL$ElHT;MaNbHfoq37V$87P%(_t25Vms_#IruNL>(! zq%DHm-i1^39rPZAbpQi*#wMyBB9z>7QyH7(zi@D#?kNY+$*!XJ

U_~u{c|?@579T5FF6CIwH?Yl(GdqNy9;q2c-*$+u=35Sd7)Ao zJ02=OoU?1S*aaNv5riiJ&c7aSXBcb+dG>p3*zI?ri9uPb3~+%lJ?pnQ0m1sXXCKUx z)2qGoP_nuzY58hSq0w~xw=vne}Z8A4bQA_tuZe_eb{c7-R3nGKU5nZ)D{ zAcVBb&1YTY2(OHKG!cXX+T!UNK@smqj{qfxqBrzv3$(MVHB6njdt98oOS&)#*EGGI z{6z;8UjI}&LO&|f2+mqu1pw9N>b8(zQ>nB0NeL%83!DT%2o02fDdkMWy9zTbGRn6cqunlb@%`?gl1~0ycTYXq5bBn9=^W~mGCVU~xA-7KaD!0#_*Zbu z$NMIq`jTuUB<#OxU{-zxJ^Fj=*>>gZAf3hi3liaytO0h}8+(j^yLL&-^s;w$vX~@q z3^)d>wl`yl7Q?W@M;EHDn}+CE97e{9EiLFJH9`{^N3vePrly@O~3WrZA#t_4}S-EXM%Iraw|PlYUY~!4lwPjt2)z`J&*Vn zyOLQE)yr*WC%^e}o1CCTf6P7(zExf+K^K$ofu5nmIXTQ8JY?hTR)qrBRdMKp8i-0fY(kY+D`l!2e|>h} zVnT;-efi9YNFJy|okKAk|4kuzPMC=P*%-)U zehjQ6>X`P=st8SapFwb)k?*>?vfg1ZAY0+DjO_V~7@5Jq16D#AP4jr?!< z&y}Q_(_S)qyRg}T6sc{!FF5|iRkCV_XeH1L1Fk>eu;ho3J82^W>BB;_6IYNP_E{BY zsaarKo{kTw4$rMcf%A(S z%+0#P?Dgxs5~JFknRSW1{Gdu8`9HubArY?eBDwnUOahPE``g5eVxV&R+RmKE(pjYF zL~?$#lzJKoPnZke`y#iuuZ(iCAD1TD54shoKZ|&@tN$%)M~0WzA-Dm2?=bK9dwa*X z_Ju9?5gyL3Dr*z0+4PC%_&G$euXh;dk42}CbI%{K$wc^4i{*hnEJp)aZs@_ywd(=n*kNSW}!-vHk|XfK;m1Tl?m@kX1P#(0%i=~ zhU2v#NI!&&6sMg&e> zHtS^=A_UCR5rhR@)#561*2|NF%NRf-gxJUyKZ`$j&bqp!(R_zirp?>7!bG*wrY49Q zAVbq-P2*0GE(T*8n;<5por#e}L0`|)=T4bgkukSvjk<#cF$JvL8$vV;Qj~Uo>_p{! z`ZJ;mwf$vf_d71|+n7&n147+Dg+`XIJl-3r54LcI&o1ppve<%hH<$H!7Mdf4d#1U$ z1nTA_zfM;^)l+SfvhUlk5#}aB=5~D@3+15)a~vNh^`i++POgVX9U>$7W9+vTQ$>jU zhn?o#DV3LU$R+*+xfeY4ceG(E`)hNAX z!Bdmcbzw*;Pn&1gnx#!?*QIDw!qND!XI^oT#M(S#?)`p+g23Bp?(4RaAdEtx6Y40e z%x5*N!;h5mo_Qdqypjf_lJfJiq0jNZt-)Qkj2ivvcuK#R-mr6-f~RUQbh|Y~$GdQu zwAT2AUEPNEwYGf!m`Rq3uHi|5P*neu#K~fUQCq70JrkD^gjv2LVGIG|Elg0eS!}<; z$wpD%J+wB)Li)7rvMQXT@_l&0_r69AY7^4+Nw$E02#+*DF3ZY5yX+(X@z}8Hh<$gcY`fXqyQ6i&BKdq|Xxt*_8eYr8?Llf_ zuBpaOQ#=kAb~3gKf^owE_&;`M3X#f*#K<2ol68KqG_S{9jR%+P3z;uy<9K{>Yg$00 z4X0oh6Zia!a^{V)cj#gVCs@)0y@b|dSzpA%=k*tn918q{Kk9^LxON&a9xhQ(VTGoL#kI>FH7YL686y zcg~c)XHKeCExAJb2uFyP#zfXmu###(s}4_fg#rR;*7?1|h)u=IeB)4xgE^U7QhBCi z!Lt|Wo}Wg>&M5mn?K9N{i%4z6(yLXl8vYao3%uhIzQ?o7px}&m`PoUbJp=EpI>L*M zXWf2F#<+!hMFMKsghBkE%dp?DI$5krcs?y;1kb17(>_DRT{SY=J2f;_B-JRlf{7w`D`mE6 zg(7}HToMv5Fhq=;*UTBAke?tJ)Ma7Kh5I(8g=u2=+yk#caX*kF8f+o8p=9&mBoPU{V_l-&p?M~X^ABWR z$C;XeR2zR_mL0mSx#VhT3r0}<434k-3j!@?n<8c~7hQN;#$0lTqn2~y8H%gjj$$#^Wvf)`wz z*yg(PBQ5Awx-3jPF%ocgb=&Zf{y4X{=!WjuFJw1Gvdb~ua=+V8qZ;SLlU9>gFDO$* zz_y$)=lni>=R6=?PMV1k3^92jot1+#^4U|esAl8|T; z5tUWGTg3ybI6mvlS>W}YN^|3&b2oo06@?$%DublKCV4C`0D&I?@D=mY`G^C|N)TU% zKGkxQ(yo363ClZP8`zFry)X9D<9htNJh*Ff^%d?k(@Q@{ek?n|zMy7gR-y)=d6s)3 zJZML@DXad~!s8@JGr@U+MY&Mk`L)}{j-J^e?wdNXq>^-GLBX$kF3fQ8!DF=}5Ur89 z=w!oh9)C7G0iU_EoT!nCMgivlSC^7JWmUapPzm%;pm5pS6DlSHa--~k+B8zHs0Tb# zmpbvccs3_n`32bnd4gv3X;wRK3Z_qwxH~>btu!E)YI?^Lb4JM6bQ<1cUPwqq7UY>B zN~?LMH0JyTWeMx@Jv=0OF+uSfxSW-3-m1UJJqW?d7G4;cR}s-*y}G&}sakjr&xUsvwrDHb! z*HdkTp@#{nwa7PiAymXA0uEG1J+VYHz^{F-nhU9KKYc}y>Wf)rmwefbdGl(oW8>iS zHm!j-AIQI)iY#q@uGlA+BYx2yY_ERFSH?(SC1^-8?yq&?!nXkmZZWNh4LhRPvEen} z(h717lHfsLy~E2Ejn`{htSWQCtK>x~<6|zGE_1)Yin>Ok-d|s-YGn*h#y_GlxTl$w zCJ;waJ^L3$VLxS-XR2uAwfd~=y!BP^TY@=jyz%rKr-U0Z%h$ophLZZxIN!8n`+uKU%RL#A^^%SmdlEsM3r{i5(IUgcx)sKNt2RZf-N z*NvuU<@*&6B9W7IG+)rEAcL}f%CLQ`O>PPIc#ucq+XwHyrkvEuhD-_ZInaj27w;{> zoWzJXwb3w9ao;qXt-79^1aI6k@joB-@KG{ zA=3+P-~TM zv0Wtxt=f7rAM}k#QQH$c7O*sDhCSf{$(8 zqw22$SnoITip+~O6z;};yLTI0^FbKW+{PuaW1;8hQ^W&NY;1CC6_Gd(nJ+*}c6wIE z$as3%su{2*yR(`Fwr+h)oYog%PhK<*4u005LyLM*&D``D9LUc#qH{g}RF6>NGl9MG z$XBhzx!_a@g0lIyGmZW9d)`I7uE|JjN`-X(B->B+(lcA71?zEV z78Vr)EO7b8jKIj+&(#U4h)ve7$M1=jZ+4WfK{r_s`tJ_B#eV`tl8D5WgcXs7Id^l9{tu$|m#v z4z4A8msIf4=+*c)S4$xU>(wENfxL8!F2W!Dji%F8G_i!ebp7ZNg%?QGl$M+l`#$>u zpb}4*t*$+B@Q90MpKrLOVM1pOo_1(;*4j&sMzTK{Zs~+?_FksDU`;rYbMTvxme7Tz zaHG(d5Kc;ZQx~j*Y-6qzI@p_>eq*4}d%v3?_Nd-uF0l9?AcIw_549v6$DNp1e*0!L zt!({^VDZ)V{o2tl(7y#HtXe@@FF2yu8=lnnyXnhH^xn`^hg2e328_hVz@h?sId>%w zlJZ8_lTv+9P=p}ZqXx_qKm;q6-0t@go}?dPWt^tPE8UqW5^ES$_yXT|@QkMs(riro zU!Szz)gl~^lozz`nT6a@m?n$acf%7r2S@S6%lAV5L@Os0Xh>e9v*+=YKRt z%c0N`0~pTun#o41Syg#FT|wKJYVp_7^xq*fQuk4^)Ylx1PMi&o9xFfG#o~qPe~X~e zhDQIm`K*?Lma=8Lh`mC?*jSHV{?-tC-^_So|K-aQvlm>!kG4D|Kb`6D^cJQu4!ziO z9V{g}0VxJi$T8B54{DytET^Y%*9dk!X>-Y@YR4(u&`LV(Ojome9-M+n5;&c54*^kg z>F&_)9j6V7%KisGillEzIM!JD7oqA)DcggE1t1_IKMee;R)>`cWZ7HG;__zZi zoF@dC&*j?D%ED8Cog^O;motUiO3W!x5e=o+ zD@uav>|Ww_)698icr#zWt8qOE(3@<#Rne`V;i62j!Qa9>hO&eakve+|^GbVR$IWk# zzy1=PC-Y+dpp`;#JOBBY=$d%F-KkwGH+x{UwNr3BDk@63nea{iiIq(gWn{DVy;zb% z=6oLKR%oob_1eDlef(wvuad|HhIXicR~RKtCz9qD@`S+uVXcYA6Li5E(=G67*f%hp4-a3dbeY&npxp6J7%=@t8?%RHq z7oU3y_ShNz0RlNJ8J$=F4c9uA8ZQyM`~W_8iLNu1@pUm#O5ZPJWLknk1OBbUq0fGn~ILc&?y+ z^QY3C$Z9XVn$9S*6!B?ieDbXbbH!q5>puXH(-;_;pC0Q|4$wP@Q3t3O2{CEC*Ut8} z4E1ed4(LaW^i+?I^L~peeg4NV3pzBxrM0~@qj7ui=wtoMIk&w1W&cTqucutSxT`#OR^{rOs1F}G%U;tK9C{qk5js|z!pdzRhb20vg2NHc z+ns%yBS>HPM{lkaBD)OT_Q@R9yf2FLq=f^l)hjr*6a7^=!z;&ci;_n7xrpu5NdjML za0{voCH{sTPIbNBZf=!LNY+kfjvDrEXC6^DW}8Y*eG&E?-cNl>{Uo8oV(T-b2Luj^6q& z5od_awnvI~9o)l&i0Hr-zv9f3u$z216E})z1~u{Dlnh_I;pr6EaEGkmrqh(3aZS-~oF~LMCQN-J-J~@gw@)8OB^m?kzy3zEDMGX<0+>r<4kwuv`%df!k zZ%U`mMtFaOw5`aT{P1ADe8Kb1867F8e7vESfw4r!;xK5v%^%xr@g&ePdi8Kp;F6f1 zeMt{U{Y+BQmfavZ^1EKjJ?fo)^?Njz3~YzQg{Q`&L1E7`8BSr80%>&Uphq3OIaFgI zbTf?z#1R8^YnJW;Vb1fHXJoG2$p;XM;xAevQ3K{?e0gKnERMFQ`s?Ylk#W_?UI!{PzAGi^IV@!^-rn^MOKd2Gij)KS}dB)U@JQA0;8`2J`) z?ZAq^w4T}bIdUh(FAG*xvg4zZr5a^jpi}!P3IgU#uywj3Yqq&|B!w}az;~~nM#!L; zGF=0tMzhs;M;He2AQ6NO;wk!6J!4t4W6fk_r+%DZnh!aS7hq>wK(2(ZB%1KkdRrew z9^?Sd;e!DkSfHv_#YFFH)N1z1`V&yW0zV%KfqF<7ksnfy8{95m0;Q;8ZdVc@FM;(& zqB|qJ%IVMx&$z%dy}B`Pgt^09TXZ_xXH0NN2T(Gpx9%lujp@p<7cC6~vgh#1snbevXq^3!`V*s{~d z#kP{&cq$l`%K`o?@9aX+9gQF=*ZZQgC)8E`V(3zC1&uA=b^6X@I@`WQP-3ta<#@ z&Smmf#;7<#XgA>8)nYr12PJ;shpxJ@uX=qpWQ+>jAxZd|_BCUqxcu`%0o(BARfAge z7xr<%o00%j7BR#xitlhCxYZzRgX0|D3_`$6b9l)#wRBykbaLs?C_At~A{kq}xHU1w zx-i*>7SjJ)C_l1ndg0n+U%=#`Cy%8OTZEDE$$-?z#^#hr_uwwctHS7U+sInlB)HQs zw@V;RNK1s6V3nIs+nCuPACA|*cuSo?ofF=ZO#0F+&rO>zaj0D?2iE$$7y8-NMmouW zILB14q)mI2*2`u_S_TIY>LMu)$g}?zru~;yua&;ZgQZWCb9=D?w-;BxKEkc>0zK~J ztd-o9AmuH;O;vKrsEu2ysrVAyCL$IL!_e=3>9Un@sdf6Co%g|Y9&AmAwRfaDKB}d3ttusBS_*M3n=FzhW=Jw)sn@JH2Io2+i$Kj z;W{cqwSr~u^Z2err<%oOmRCz*Rt%xLzE4jA_-iT9?9sZ9US_8O-9LaNjSk`FkcqVG zbQWr6#`ehaQ`Lr%JM+*8#R=6vz@r8Wz06#^zk58{*G4tf=~9cr3|k=#yeq2PW>{tZ zLnoX<*Z1+F#_t0x&{3THX1slpMyo>P3r^uJ)`v^}gd%IgXQMO0*lFeL6i}&+`)VoV z9YaKq3*3R!;u%xmhGJBxO1k-dOLmWCB|b^{1B;B(>A*zqS9-(_H|T_7H_?;MdWsR9-b5m>9dt)RQc5S8g$3;7PCY#g?snq8X^m z+d@S7#kWS2w3{lzq3Z?bpZR1&*b7br2am`vex_AtdHp_^4o&vCm{$`%O`V+4-&U<6O zAa6EF9_ob&7X1M7P6b5rNp0Ad&^0(mKbH$;k+R5|8PEC@$B>LlJ@bfzH1v_vt8KSc z^WQvs7_YP6KM(zX0E)JOx$DBTJo*??;@y}e4gP_ES97hZ z+pl_BDsnTaR;4`7cAg}ZfCbVmZL`SSQ~R1#b75NpPFf9T+2pg_6Tz77mYO?f_l5JN z!CdPi+4GLVwkPQc4>#w{&LN8I2HH`@7wrvQC!-$HwLOd@zeug9KX>Bm5{=ZOffcqt3C@9V|%+9qoSj{WcuCDpN~zJ;H=R zFk$sGL&qJqW(#$@-ktj)gJPzvVEiz(61vz9Qg=%D;kkicq_BXeKgl~2O||;?!wqqy z`m}f=DGRBcKDXE&eM$iMr+K_UztJ9}blTf`mpm&y))E}mrgU~TPmT#VW?n+CdwyL< zOT|Z)5mMEjp!SuBg&fSp+$rLg{cPXr+BD!`ET1dKMn>db&vQj{W49vi@Df&KJ>lo+ zgqcfDuF=%0^{1PgTWS3!Ju`t%GyYI#JgvA0eEbj4#kIz~?xJ&r#H)4;9d_T#*(-_I z-fFY`(ChFt?`=j{wqaYvRXpKEK#wGOv*B(1fZqVnZ>m;NZ^*y7g+qq{-q}McUEv}q z?eQ>LD*a4|@I8~HQZBdNS%>Eh6}V^V9QzNDQl(dA=P5E~^9PzcbV~_;R1->>UqosC zI8rndYQLs#o5DYo_CTGrmpku%0W3K45yxC=!{S*`%n4?1a&ECfMd<>vWcSzV94^?B zR-o$i`#0pNm&8_hP-mV;m3Ws@VB&LfYWMg4lP~?zaA&=DH$F_S(fgn-EGyiW+L7N~ zU;_%YC~l^Q-FNAmQ#uuf(T|$2qf1~9IL!1x%>Mw|U8m&8aV`J$Vwj!!f+V#I@W@Z# zK8d*o*JysWy2Yh)UP~>szv1KxRUay&%s|DCu8g~>e8EgyUvEfocyIo|%^q{C^7F*> z`Eh}KS!*KEwRA;EMD89QSB8C)~1KCE{|Yqupzek$#^p+Mg@n0!zkphg^Zx zti6FA_RfYtRvwlYzg!7>WDkSJwktv!duJReylY}}aU)t2fupNzzD!Q6BAoXNLGSw0 z6LBHb<^2HsymC4m#^sG;X4N}}k@6H@P`sfuur^LN5nDQCYrupQ@C&0a`_6iV{wx4E zi5qp{T;_HgQ(LUTs~tZWI}b4&Va;2Hs>6A;C$yafgT0sVgSw=VoqZLll-j<0BS1`G ze)$Hi;}sERGb5ZYzRT;JYSLI7UyBe-aMS$pV7Fld+Y{~@Aopx**vTWKMm5%q zFcc2xs8m}o99N&u!*L~I(YFm%0zxx_=?}lF31wPx)! zMLMHDJf&GoTEuz9TB!dS6ISl}ss2KQQpq&(^YO5+L0DU?T;#dM!o>;kSh{!}CGcUj ze6>@=x0GjMpm)2sBt}c}o9l5&z9z0#&!t*_S7h84_2aaE0Gf_oG9@U03!}uEXIp;p zcr6H=S-0yfz5&0ZV}zTH+UJa9`kz)&rqi7kgNNjG>a4 zyp8`W!hcNowO!+H99!Ufnrr^C`#9Bw^_#&DkCV^Mu3F5uk~d;_Qoi2x9z>^ctO^;m zbUXsbkerNWo-vs?U$w~5M9t0^BJ!J@)3eYXa;Z@!tm;l-0u;ppCD z(kiuTXrH{9ddDip$?qqhDrsW!)5burWKhFKCL_50m0*6$=9b|eW(7Q>W$F0@Wz&QY zt!OaoC`@=^5?zLVjRU#UmnR2$BQ(NK(d?bbZQWX68mNN$HS)`~;KKDN4Md7V81bVs z5Z~rjW^kH_0e~OSaT>28o+%*~jp7(4B?+cid6M*`)VRvnVBJS7&Bq3|g721K!t@BYJ$bNPNWRo^0yVJ`L z0427GIFU;KV#H2Ej6^j!A$hHvd!wE`cm+cTV*HCve|%_l*VZ4)UM`)%`wpr+S-hFW z6&CkffVyS@PgqvmYr~Zm+BJszg;yY2tP?k|&nI>j)ZbqYN50=3aqe)vCxSC%nLpXm z`yfR9i#_#*!?~~adxZQO-w0*$58GG`t$e}Zs6_{<6~C8wRu@LOP6&>rACCS!xzk>c zCq{~?`2Gj|Kmxy3y|u*@q?So-n!ebUk(<@@X6NYn8hqe5v8C`hjzJ$afY6KK%zQwN zuRT4hh3oUg9@l)q3(R!*nCV{qpgFQQSnh&x;;6VaCuQS40F`HuoV^68!$-r83TG81$IOtQD-Mrd!V{$WE0&(FrMGJDU zZD}1scxYX{zU#L%_e7ln$88BVh1-DcyLu}?oLOn6K6)qG;#E3j+XP{?-djQ~B&0Np zO@T3sUC2ZsCfiiec1E8P9Gdf32_4i{=}d}U@i>9(thS`26j(Sz;}m&PLK0TJ!4z~0 z4$;ba_(~flXMPGHEiE){I@JrOWFyOpT1e7Mji;<{vrKv#Qyz%mnBl?}S_V*_I-?XR z5~tAEkmetDRX$kctC^3ag-w=uDG}^y=&OIkR0{sk;;bG$N*NV1mds{+y%ORiG|}v$ z%F@;lebM9Sg+Ic6t3i#Cfu*wWX#1zEXbWZG1NUxFhO8w>3Ubp9fMO*HQzVs(n>j!>mE2uqZ-92Us0lnZfH`B@+WNkz(+XmM0oSq4H{4+(AAt}&rZ-fWaQD?CPk z0;rY@L09NJ1M2bW2bHsUOilvK#s+L2#Y3QG|Z=kKnCH+Gwh5d;YM- z{{R{OMO{hpE|-n`oS!jPK>{O8y|#olgjVpi7{^=t`oF@L%w=-mKB+Ag^T#9p(YucbFGYN{ELSH{Evj`>r8%D=1y!x~{Z@1KD=adn+hi%dXQ5 zV2TcK`V@|9!$51nBlm|@LgPqF8bxT%(7eW@;?Li+h12{4E{Ptei~z z8+1*`&W8#;@}9p4?n(rDgp)UWoY>lb4|S8v%$f3irgORf0D+yFrs?{AMqm?XWI3!o z8+B^FX*WoE@#3R$G@~mVk5ra^sI8VV&|2Y3FP?OaCYG}#89OzvCe+OqQzL6^jsE~2 z{!zyy?wGk@g<3EA^jt-XT*0-e4+}%+%j~Vxbg1&!;OgXiEcAXEiag!MtKOE$#3+x5 z`L+iOG}E(GBy@Ug4Z~~|Osb%Iu7^y9CYf;@SmukbbtSI0fQcIeTR{{etX$^k8|C|_ zzE4ip7dU$_DA4s7&SpdpHF6gf{Iv4m3UwBju-A+Uz+NwoVXq*PeVtAI|s zNL2dcX&hmLwAEk4Nw4uv6-l@&}~uJ%c^`y>+rYn1KkXqynT+%6)5agZdi zdMhBxgUl1Q#LN}71!VSI*%^I5%1CVaDH)WCRX z?46g9KH}#B;-EV>f2GX={gUUAy#}I@3oPwrD=ZwnHaHqXSRL#~Ay(!$a|u-QvwLf} zStS_;2%AtPELlWB>!Vy4z`*afyJrWRshf9T&ky z$?W7O7NQ92vTNuIDmb*ZW=`17iWX)-jgBdD^P3Q>S)E5y-0~Vy8?#&?TViKt?j@}% z6hyt=uBtdC&)j;e95^@8rA-d9Rx}Qw!k-is$>nrWfj}uOZ507*Ygj<#JTP}e0U=jF z*f)SWAdrmyh(*+>BsKy60Ms%5r2hZ~buYxIvE^^|#xpPXzmmV4dV=YA-^t1H{{XR# zPA7{@0TR6=e3p|S_MQ{M3}@1c3N%wVgu)SfCJ>=Q0-lG_C~}rT=|X5quF4byhl05Y z(hb#WG6b}R$YsDKYl5pRQcxb?*YrhkP$rY_I74I#@*na~j(J+luhy0rt^lKtEz?H|9(Vsx!At7XDq%Tx5pLCFp>d_hKYnLuw zsPd;ST)9zaE?l`n2)T0QWs13SI%IkrpSV28eVLqU(0L92Yq{sHI ziPN7_M|4Id_D6TbkbFsAIZXnJ8FV)v=`n-Qy1q$S@CC<(hFzUVbTy$FhLFM|QlvH^ zLU=+J6T(v*hsb{Hs8NquQyzZog%Tm_Oou|}**h4Pyb!OToCXUkEtKh7icBV+6}p3z*dKaVFqCI{Idb+gfLd^@NOOHO2@+qxBMH>Lx8 zc8bir7csAP-i<3Un~|HSJ@7|6;bcHJXdD&kuZ52sg-<_+p)waU(n-4t{wEEE9MQb}iXT0!E8O0VlDKK%^dmNg#J29yue95b)-f)!U7P41xD&=t9Uz7NE?N zjpsk?_ibq?9!CeEu*R}>M)Cez^(+JAlIWs6dpNH$gni&%&h083jW$Rts9sH~>F?9E z8FAbwwDeBJH!j5I$Hm$<-XF?j_>q7BEfq@XVEiwWBXdJ9f;uhY$(AWd(}qpQXIey~ z_^v$?M~IPkbgC92r_?2sWqEAB$z0N^mDQ|7D~BFaaV?0<-x2z0k=MVnv85gw`&^)O zQWa(Xi^Be>8-+HlGuztaO9jcl%`nKW7aElrgk+LpxjYO^i^fTQ&^wur9AI zl+X6>1)vWqLRJKn(oB$-y3j{@-HvVO)HB ziT?m7{;SU^aSHh|xE_Q4-eI4>LVR8}!F#F1kI8w}E&z54awikhM~yVU-g0|izyOd3p#Pwn0O)K}E`YvycG{exjc}Xb&rFO~19pRy3~CLlbLKBW+Nj|h*C_^d9y6JXV)WHcjbrht1Yyp7I{ z&S@ZoQOMc`Sdu+Kz9GVQb!I9*#rI|{ZjqDf8Q$h zRU_D$sbLeu?fpV0+p+73T7Na;f7Y2hK=V%uL>l&7EiK#~V!2haQax|&xaa;Oe^ho& z85Y-q7mNP@S>;`coD`__+}PX1uKxhJU9xdUv2Sm>Qs&jKA8(1Z2K1G~{-j~z-AS$V z%H#Dab7XM*Jz|5p6~(l?svjI`On44?znD{^@#dx<%b4NqN^&cS=*x%)s=$vP=J$d( zBgNzA+4C_-_S#hBy^%qiDKT3hu8ONON14`R-oGG?*4tk?!iT*d3jPm-!_;}VblbtqHzfbrA#yl?X?3h4YD_LKo0pU7a+aBbyN{X z;C4BW9EDRj0ptawo&e{U1JzLHKv^NBMUr%nEJWuH9eq9NX|Xe-k$`XIVd2SkG@G0G zq8&-mNMwkX6VzJ4ILb1#bn(hE$4uWD*n6t{?B+(&cPy*?O6c2iOSF8-sm$>gp3)lf z?`l<3k#z`e%Y8#rFD8#FmH9F5^~f*ktL4d>a7OYi3Kj=gak7cwq*wV0PLXv4tuGv_ zyeR{P3jCI09nsRaz{+b#qxA_AiLMUOrHFvk@Z)!CzAT{X{nOBf16B@>hNv zL?!kG{{RwY(sTYK%eMf6T@8Ubr_d60O5fSiWzkq=+0=(Y8Z8l_356A}k3aeGdW-vK%n%W60_g2j4nUMr}4B05Q`zyL- zG}_UR`$nOV_PN2bwaq?*d|%7mdKZBAL5n6lr`9Of>Zrz;#^!E>dPw1DygeV4oZ+|P zWq%aTX|+QBDvNB@&`5exee?7CXlN9vM-6z9w7a z;!5s4*4?eJg^>$ph4HvpaH11Zp)I*-o=u_Qx(vG`Y3x?g{UhkA^-VeWnuh3((ezCb zWd8upY6&h+V_^8A)S63ns)QLwq^&=i}tEL`QuQU#NyyBc{V9SV%D zbu5_7WtU}Bgsi=c!>FCM)_+~Z$ZU<45plFp0ce7AgF^{@27zY!QW!d8C(-ApB0%!e zPaf-p?;nc(g7CY{ce{pCmWidbQW|MZ^~(QIsBw zgOo-+yQ`nk8fKXG`ne+hil~Y~OUH7T%xFXsbHON|X?#>9BeELjD$uDl*o|co<$= ze91>Api_ijIu zveb3gW$EpLGT}AyN3v#*p~&ePKraEHf>iv?4Z_~m0zJnmN;9iSDM}oYZ1ef?* zfl8SNhY+3~hB-<&R9HZ4(r_H1T_-jCs%Rw8LdLjq6H6s$EaWFPKsu)hJ(U+?vnU@+ zhSz-2!7d$CckPgRfaAJlzAjqr!`TZC(JZu%damomaD>c&TV*^>)6k)&7u0spK1mIM z!-)LTgW`Cn8c5&)px}OrZ5L4=27YEUgPD^1A2nwOi#0Y79`?%LXAV^(oQC-XV#+kw zxhR_4PY}RnX~~CcLB2U#TwJJf;B1gQIfQXb$3{!vLI&?~HB`Mf!gzCIX`82EW8|Z> z_D+PGGfpeCU67dJ!Yb+oFj*LmP-TcX5~N8$*5H_H-qjXYQ`>EKWnY~DaI&u-7$(S7 zne9|rO8jP0hm!+qfUW$X?y4lw^#mcZTQXY2HRX}+qsH0*D_v$Ux^MWxt#GAfHo~-8 zkTIU-?_l+Nd!}QsxxWjiB&&aOypl43TM_d=paW1X4>M4mPL5F?Dj7AZhHBLgu(oNM_W@ zt$9!0X+|5G68VR^630k=Dm0ED5D}d1!jOv#-NLe&JHssw)px$Bj6F)zJlns|vdG5+ zh8}GWPCI}LEsL$|8a$)y*$ymkSmfj`o(J_fepmK-xC#9hLrn4h1kGzR+WcvIxQl68 zY+T%I*uRX+p9OJfx(7C{|F{1j->5 zG`7`I28721^3n=xhX_jq;mRAF0Ob(40)-)N+dUN!6J`c#AG(>9%V|e^yD}^a03u{Q z;|?7PmO(Kc$!eBbt8rukVMSQHlG|#80U@JE40qlTPd$^wo1R0uf`>5?$j6U$3Mza> zrZYXPAOSN^2i$uu(=o(x4l0$NXfj69&Y|5?VTWr;?6P?gZCW;X(n-@ei%q0$sRLF6 zpa`)yZFNU2pqg7@S|c}Wmo8qU^5-sGxlv~>T)9FBxpGx@5zCM=^B}^3^W;b)V@28S zu=)Q0(i@DsFry7;ySkLAWKkI$Zbtob!Ql9#D<#0mkyq4RE2uR`$UQTM{DE1Ymm8`y zuM$;ei6W|xIz|z0yB*Y)XSK$hDKb7pBrbR*5@n{prKDtxc=Wg*=9Gl)Nv#T|ndf@= z{{ZUqeN}BMEqs6ViN312XOh^&1-S49~e)1V@IeZ$aD(^3ydZf@`%sbgq>Cyc68&=fFcCYoD!JmglJDq zZ^E5PY-$@J^c5B}$qGz^&{RnJl-R8bo7pvogyK+IcnG&>WP*zck05LLR{Ctw#gn$rx?{TFLH__^E)-M9+2#>X9{taj)xI`ooit)81&&t9{v6U?f81doMx=+s z+Fm@OSg{z#dy7=y*&{mapq4p6^JO=F$$@Jhg^cL-y^Y#Bc38c4UeWaT%LX(ql6Kez z_#7ll3vAIG$toF_spI0iYu+yEfmw}rSvjrQ344Tg9$C`LsLanZ0_hw}kHRjHo1R+( zKx^t6hAH`3LSd$(SS;L$t3*@TonV%uv^L$ty$(Uy6Yo0d& z_i@jb_Yua29CxcN_-NqUzN*XW=}nG;c+P?9i_? ze1~d2bKdHbd%Eb>_M|NrXGehu#EIuDi({Qzi99H{IXUiiwV>nOk1^c`%cI~E=q*80aC*aSKj`p%x znpi&!k&jaCQ#5G#u7QJia1M>fn+g=VzE(@Trn}2*g2v;)Qj6tAzXWL6mF8nc*Sn{r zbM*Nu2Y7!-KmH73=qY)=F0C#+qA86q5J*4k*=zLA5qWa`n<4xVHaXnT`uikggqG0Q zNj}Rdd?}+#f7t_X*~Lb8gY=WYjqL;3%JMlw*F*NS0YX!T933DDiX&;xbO{q>dUrkm1p? z%=?_t$?R=uTf|Nl3P?>kRGp&Y=(N%zbT~nd>J;h)n@Wp|BTQgglsR3D99}v(S-Eqz zRO(m_k|}6cpsehAOrKz-aK%k0)ID@7%L;iq{nO2VpFuV_R_Q2vddwiF<{fig>08bbFfjzjmd zE<@3d{{Xb5^5!4#-Twe-UhDQ~f8yf;Z~p+ar#3mO z_D}x+w6AmfJUya}eHs%Tj{yGwgwOjz7ZwtlXN8!h^${Dd+i6aY9D*hmC0EZG&`7UmmsF?`zwu9J}yO4UyuABDMiVu?p zZKO~`;rz)@u0TG8Xf&S!L6ryEaH^e9z2+LLQHbEmbtxcRq6VUOc@_$$u%Q*+gv~9K5A7G z?9r6RNEp&h@$8uvLuDLTBd8*&Jkz+PWCrgpXtxeiTHZKK1+e9aZks6d{ZU)NEh-Rc zYOKzT+O{D=%VqFYGRn3@Hs3`PDVD7aRKh7mni0365*dAF8^td6a6iRX9AZ|RRK*X( zaQTnss5qxAZwaP*IFny^`2kuQ?b6lc}=kFu%C$Ck^P(OE?S`%_;j;$yU*nw)Vq z4nndfR6=JOacPmwVCd0(RrZssJ1MM-CF9O$4Q!vk@+!2m?6Pe(V|O6?6e%&zJN(VI z$8`Y&qNKJv9!D2w*+l)$+C?7WOlv{v6;_<~R@+$Cc4IcWG7!1fI!1t6qAiS)94iJWHu>Y&iw9kKQ~Lvc{XvX6?Iv zS8D}>gCue^fVSFmzUXkS$XJ4$m3mN~2HA4u%haA=<;#*P2?~)ahnZ=)+Lc&Rid~Y4tXcyuYFR ze}o-3B2O{2$({ZNlC-$a9ZQ`Pzjf@d=CX{BFCJjeFpv7kT8$$cB3Qh}gI3{{Utf_4ZEdi zJAV)zKO`y99?5aa3APtC!?6@pm~{s;iH_m!I;!Uw-UpmbpMqBPY8jeHWD#TwYrYA4 zJM&GBX+&JH#!F={h$1IamR9o8Raa%J%*PWng3#c9P_vm><_Fhf(P_tS90v<{806yOT1%hQLMxL6+Js-WW~dk2K*F=c5jGPwJ#u8#xW;WkH6@H4YQ&S?5< zPm<`kj->S~X@`m-galAc$UONM8br>eC~9kdX(gUG+hnaylG(~h$&H?7Lc-@70c5gr zWYu$v7;Yd_b!p3mMua?OhI#>b`7sy@h+nLEjjLEqaCcf zpV4^6eBWuve7pi2Yyg4(07EP5Wn|>KQV(Q+nx!IW2_enynD|U>4m}SaLYrb*1YPK) z#zEmOf+Q(}P&;rS0mfyq6Z;bViNj#zE-T@P>;< zmrB&UoOZ+P(chs&)1@wgEYSCQ@=R}S@m-c?ET;z3k2XmtxEaO_AlH5e?gR3rO&4aL zRL;eAm6anKvQb5jZ(Hg7mU|F?SY^c|g`!Yx$EN=PpVy+T`&5OlYmJ8+O^+e)%*j}2 zw5#G*BTcMgKQWNKr+<@MTnEI`Yxp1Lpz1D}{#4A5V}k&cbf>q2{3$aZRrJ0$y2D9m z`Gfxe!i}AsB+ho@!-uQpebnMpV++PZi3ipE)vW&jcY%!~+#cqD&_@Ta{#7=gk};k^ zsy)cMD!@s-&M$Rt7SZi}Ka!?`Oy788Qu|gEaR&xa@6D_7yr)gnU#Gq|wZvP6k9Fyq zesp?PbtfSw|3<@Q70!6*AEh ze}z-#inVnx;HqrmvCp$yIw|CLsH*wT-zo3-ih(!nf@Uto_J+Yl@l~gc0B(8?9t6 z%O4<*#1XJE+m!%yQ^55F3m=&od?n5J&YxIo#T~-k;H~_cfkGoI$Dp=Ue>|$!1I4$-n988}_&2C;evN&^lJSAj;k~HDW z;^~{A8hcsFW(Hh3jw5m*K9_dx53y2qESxEuK19W91uk%=^eOEeQVg#Q1d@1HLfII^ zGA5D7px`Q;{FXNt`np)$*M|bv9*+M2%DdAUyBw3&`6{ni&BdNk4mc7$ri_)qTVlSZ z8Ex5A*erAi?861NKvE)%o+(U@I&CWi4mKD7SXP+q44?uWET9yo4(O2rwJJuGsEBe) zPARGsI26~&8Z54J!&*sDavdbc%a7tc{el@vk#Sbajb~GrBPF<4zNrYOQjw-;8-rxZ z+~@Zf!nD)0%xpIAb8YW7=N_&<=EHFl>HQD-p>d^Ur*B{%Cz(_j>i+dor_|+zyiCq}2M&s-T7FD!E{?kJTIHOV zSjxXC?sR~qu1s}B7kJW%ay*7)uvxLa+y$V58KY&$Jw2S>L0FwWX$Dgs*$W(a0FDau zoi)vLAM9Y;ge}5#1rb;F%uC%b#>d0c17Rlvy|~%gK53Hpb4UrJm|$ zhd0@tSQ;G}6iHIzgYD7?m=BWP!@9A9OoJWajB#`S0Dx6wYAC4Iv`D0r%wuRcUjcTX zj|Ks28yC=p&Nvr$sCaBkQu6C8?g2P-13acV99Ri-X7m} z8zD0*M`>@QQTZxqFy_FQ&4JF1!`r%Bwb*Jgm-5SLVv+(}2KJIZhyMU5V{ z!r7X4H=f}22j;sPXr_zolbQ#i_CD#pX<>9TpY06jPy9yz0II%CbQ6ktC^BGlFXy4? zfUfdb$yw6L?5X9C%YAlT3^{qKIoa?yJ3!y?C5Nb7{{V#~UlP+36xM>sc|v!>i7BH< zcWA@_e^jycA63#2TuSB|C?(M7J(i6Yz)}?G{{Ut_i3;b*?CZy*Gz8$0at1L3YI++= zcqkae4q@mj6A9j@$}NRJX!Rq9LZ{g!u0>;z8jQh1l~N8p1x^JtbX*VyI@27M&~j&N zEF|*o!BIq<2_weJ-scbr90j9pqR5A<;rCv9_KBS^k^Q?V&CZ$8Z4PiA)}^@g9Ac%} zvB}o4{urnnHa#!8G6i%fAtd8A&gLw_Qbv0x=W zlqRCcJt#~Zq|38JdL%_HP`*@#Jm0#C#sGLy;%^C%wkIM%S`k_}OkhR>g|i%enPkKQ zkY77Pi1rJzX7bxW@}aShn0j7XPjS>CmQS}76k)48_s99~%g^#-bBt^rs}u=XcLE={ z8e15^&MnKI2I**7C|uGT5;+)*S1**Xs@Pea{Xx)nG2y4$yh3ns#arDDmIJ7bTV zJy)UO=uh%m+5)~wGs(r!>{z)gW(C@D58GU%ZkX~2+tqq=JT()=mI8i?OkNy?zk-iy zLb6HpGvb2wdAl@$798!{>U%vW=6fpWw5PT?`1P;@UnT33_<4pG4TIju=Y>O=pvjGu z=drXT1P})wnkAB6zNJl<>x87B-P*}swUv@EPYDh9ctw+>eOR>X*Xm&u3rjBUEQ z5!5JhX(DYpcs2rB35<8=vNe^0@E(7)?R8RKgcJF#CPt3Z*d%D+&_5*}Z70f}d}%l! zZfUNmvB;R2VrZczoPK<+E+?r*$%(Pb-MyR2j^LXendGUQ$JCW-Yo~vd7#+o`_WWT= zi*ueDI;hcUhBBR&{>y#f{Xj4~73P>gdpYQ9kg%C#PGZHzVRx(6@zuxu70xDWu`}Ug zWVXOSb$=C`G!u!V44RgYQ7J-;i7B2RH<7!Yr>c_EOOnylOm!5FX#&c4a0wpZMJgb` zh!a9ktb>9_Leg!%gYFW9;ni79h*=KBWe6_m-zfJxT^ar>0{ECqtXc zzR8@A0?#5SnLjOBGfG1CJe}nUeHf#9TezDaIWDOYM{)ls!ii&c$}lBxk9I z*sDU+*D~6oD2D@^nTE;ODa278$GRKg2HH|#yX=~S@sANqH#g*ask24+fKY~OGa5`B zpS40Qr}m8<{%To@EbM*EAggyk$>Jic_a5qv@X4iS6CIdbc^=A(BjDu8plAB5<4MEY z?ekkkOB{@A<9K^q0R${Ip{cfiIGk`|jO{Kbl72y2cyCbh&)D4SZElXwLF|z@`yY;8 zjXPXOB-aWyL#?j*BUvDe9H>uwsDgTMN=n?Q(*FR9D7C#-TzF&C;davdbfk5zfGD_K zlsx%9*Q&_&^3ZmV$ys1T0Of2jGTR&twx&kg3Op_JfTl*;3eiK@5w4KhIZs4E;HQFw z3UDeE5SvUqB;81IKef`k2?;BYWayg6W8Ch2{%SK_x=pvh?t_z=vL{U8ZE2>q`jyYi zn$38zH`!qKzGn^3EokgGHU3DmWX zNl}!aLuCl3v9frT@XkOCdq-o}^-li3ifH`C7c%;nb6=95jp6Ke$LeS*P|`74&>Fx$ zB=wIZkhhZ>bY*75lRT3i&`-*OiaaF3{{Xa2L*&)CZWK)b29MEk!)a*+ycIqPq*KiX zVe>TL_A(!`IyN+d*B&|gtL-$oxQ%3;KvJ?WOD?@lJwZ2W6QGkBq3!#~iRO<)mub@- z9xZ5??1?ey=a}pQM^^mOc85n5noZyi5%?yh?TjL=?1db17Z(LCdw<01WJXNK&L!$XAX5Dh- z%heuKVE+I$pU9sWn*3NPPheW|#@D}9 zW*xu)aH&JVmNtWZ)q|#NamjxO6c-V@J7lvU5f|Sl`6}rp6GU3iQG2-gglXqvBH4Ad zl}H+ETFj95^kjSg0QdT#Y$&42IZO?1Bme?FHxGYhX^97vz)vpjPjywKuuA7l;bq3j zSEHglYS^5w(025+^d_DY!CRxzjhyD%i<5@gT0tFDw6vt)q>GH)S&`4uog9VC6ncv6 zRE!M&062Z0CcMGGC!>e5&`k?oJwn!VSixim%?}J9*!rv)F}R%!b6F!y2BU;=<@4hN zu=O6wG_w7rjpn9dwwvU9l-vzQJw`K+E821z&VRl=)n;}#*=7<(DTj*oNf?mF%T5Fx ztas?wA>=ep-Uio>p$=l#wvWLlQS5!wAbEQWPsYv<%^W7-D@9HUai$5)^r6ORqffxx zIv%J|(OrCU{tIw%(MN$Z~=xj0AR1 zV;m1fHcWRns6z}krG}z`c|i5(q+_r#)CC32j?=4Sfl|w&$_DOgJ7e3?0}$}1wYC9K z6(R9FfTzOyXet9(iq{s3OpBv7MP-Km7ZM0jStSlif0`3ijP4XG`2{tjl)aD5D+Qo? zVRVA9DN*!Mn8#hxkr+KGJ_?NUb{&B|#4uS*;eyFgGO~K|v`TzpA~151A0|U2v=pp% z>;XiCZj*6ST4++uk8aHp(xb|Mq->cb@f+iDrm=uDdn|KBx|Xl{LJ~W~lR3>T1*2{E zS-e;sEX`=@wQ@-roLh8kycedm@`($5RJ|fN*uVfC7H7h^#~&PS6n&PZs~;{-&62pr zhp`wA5JD>)v}0*AEYRf1qHL|A&_#48mbjGX#i4O+GLJh(hGGF|6mNi|4I!~M+wl&E zn(Ht8R=s9?c;$?-z)@Mv zOGjXd&I97@Nlm!1$*H5swJ2TYxa|NQlod&7vItw9TT8vcqmZ+CST2pEZKAg0$eJ-_ z!qc*(Gu3I{VQYv9@-VZi2^ODrWonpwdEFGkLCGACs=ClxGc|}=FCov|@1My~w%Qff zhTXGP#`($Hs!ng^j>G*Pvk+iwLqz~M3D-phuiz(#TH`aXL01IOQjV5{DjpMpU`pOf zvWJ95rU0JRU@(C?(?>}^tYqo$^7A3w!T$gh1$&K`i=Q6oWNXK`Dg;-_j_i31(0nK2XJslWn=1pG`GeUV z@VUJ?P~Q<@+`(SqMnV+8Y5JJRZxK)FdwU0VD%q|C0u^4M*5u+kH*os&lh~o?+5U7M zTaT_j9E63@DGA{Zaa>%ifHRNwXD7w`CjAg|-B_;r(lb5*^j1MgNLrkgLW=D|0_cQ{ z{i6+qHW#xd2FTuyZT%9tp~8xdf;_2Tj!zeDP=dR5JfYR;{7Ly3@#R2A1+G#gh)C5E zCw-n%6rCN>Qz4q4MtpO+J=hI z+mJqGUg+3k69tVw8^Cjq%!SX!xih1ZvBN~nTsUI&Yz4=XPgOCXRRKwj>SBUN zCnVcvbX-?1TD=KlN^6R9iWy0p4k%;e-qi+3TNxs~E)+ts2ssQ7VdIdp<$`L>IOfqu z2{_Wa1M$c3pLVX!$Mf;G#rsJ8P5LKl5t@%BzqF0pTz;syZY9RgQA-E9H!iG=49%Yz zj&ZHykc8(p9HzPd0I#|sg|Ow#jPCxneGs!+JdjT$cU09d(z4;87J@nyu5St!m67J+ z?LQL@eoAieI-^fQ%b>lf6OX^QYBc=wO|kVrU} znp1YgO4M?yw8wqWR&6P`nV&agfzT%aQyO>);o)tIRAghqLh#bmS$!^>mAdF&0SSh(%Tf7&xWPdyvh1xzr@vkTwqaratWOjfo&M^%B! zSsBvd9C0Z%7C{W+XaJ5z8w3P#J2gCF@CNb3gZULJR?{0S4t#dg@>!iacjDz69-F6x zrkZ18B-VtUGaH=~lz80cO4kF+ct0?$^YPmz*RX{%IjXF8rW-DBTka80p#V5an!dFb<1DE0n2T+mc)VYU{ zh4eBdvp-}LN%W zWL0wozqjO$8x=mogjm9;)^#ZG@m$6{8Qs7GvZK;<$HSc$+9iA8-ES6|@wTjA%9Eqe zv9U~pd%hp$r^gM`S`&1+@$>MblM+VA%Bvl|s@5n22ToRYozbaHDA^sDew(C^#q|6t z#iNDKXQfY!5165w3C8I{lLg&CT5l*GsfQhhvKIz6IgG%@kQ=0~$8i)w(tVyk-CXPl z9aZ1S7Kz!>Ca~gDlZ#2mv8&se=@b%Z@#EOi^NfNRYr! z3QJ(V$=_%BE8@y|A_bhOSnUMzn%E0LG>aDnG7;XzPD!l?Z~$-qcoU+rCmXCI-mq8rNWmv3Fd{Ml$s7G=g6XD0V6p@HcDfH%{OL-7+v7a`v85{S`@(ZU!h?JB@y$4g351m$2HoDu+@2MCZX?x>6w5RnvwkA+oLD$b$HW2IA+#kA>Hh$g6C=_ua{OHuosc}|`M9or(tNTU!lUPZ zNV;Y%Hy$@+NNKe9Ae9}of%bfFPl^!gIJJRq=ef^VSn5QIqMpyKoB#k2< zA7i`Qtb_h&+Gq5OB&E*JikccZVdL~G%Z&SZy`c0i;?Yc`N9pS1R8^kIjr}6%Qpa+> zSRMPWVL!=Q0J%U$zhn4|NX=n(KA{7vs4k=W72xxUp^2`NCosIw-PEYwd&hNLNy#JV zcVt66d!U**TkgkNtj*|Gk?CG1&A^f{G91FeOmMC~qqtkm6U7i~c%`$tII^1UyGH^+ z?iO5-c4@~oK_>XsZdb;vrXIClmOV=Gg+7MI@T>m-4Sv#9Lm$GgJTz))hskL&6SDEX z*#xolk&Zi0vSy#F2RLG8`ez1%yFD&OTd<6i?Ji?q_keXROP8l(>X_pq5(sxJb4n1A zVKyvtwulZ2iz7fVP3GZB=pXLh>Ck89X%F)AT4aE5*N(0FtLSEfG9c*O90;&NffNyH zdfuD^XN9?K{o%n`?l4ttQSfQxZ6quq~_ z6T#_4X7cefbZtmxHaEK+{5+0p=C3C3&Y3X|isK`@O%(?x!`ZOoy|8D<;NeAt^$18? z<75foYsVmjTUmV%I!s)rY5884j+gATo0K38N#VG>o~{V-y5n!rSL+U}W)F9TE*D%) z`YRzQB|;9Q@aqZ?>O=DO~FQ1bEo=>0uHQfQ~LN<64jWL!LgL5f4_ z9h8Y94hR{TwtVQgc=lb1nAw_I<4w z)9}2Q?Zc97RcwK=@!H0NNWrvHxy@raKpC)??G6X%Q5RvzO(AfZt~3f;wF)>c{L&Db zN}|UTNsoOrl+xr0Wv22~SqSpv67bS`l*f~~)OqL-Uf}76%amX^C-Yc*nff{&ByV6L zi|rZlN67`ipP>H$*jmWN1)0&9U#Lpz;wZpBQnbxWz`cj$%EPe~9uQhlL0u?49N8hu zl3MFdv0^z4q7!MPCCg!Mf^exU^W83NM-G8kbFk>R7}q(8(M5xZ+<4l63iWzUuIxx_&k+sAb! zx@-&^S_-Jiu8829wp>f%h(orpIG>W6iLFJD(SDQjR1DFc@wuEXehm2H?2nZr=Q6%1 zHAc<}n;_t>$&Yko5!GjOeL>Ba%9EkCzlqCo?NGypmZ;aLb8(NvA&azIBSgENxhkp|1Jz77ZP#u>7oCUP|8XIOG+H6p^1-cX*?!3l;C-!sSHBN`zI=#td`;8zGKPkK5E)e z*_D&lXD1{uJJAud^-aR9ne$4KNt)-&DRDcbCft5%Lo|6O^?9+!O|aJ<-szZ;9K7a& zIdQiwE|HGua@^KLBqWxHo`Gqc_@g#BbL^snCsxp;Z1KJEwcNGMcciV3ll>zHG&54i zqCetC{$VCgkrVKxZs1`B;0m+3qpGRO@Yd`MY@8b=R@sl==$FY$vF{wBw0cgHtKsVH zciChFx2sQ8U|PIeOxAP!IjQ-O?v6(A_B?P$vh^Pic$*uN!YL?tq>p$ZOGHVLasjQuLUUZ=tXym% zZ0DlQINLPBN+=dSJ#$KHTSJ7_4iQHQkcg?u*yi+2l=@c}Ak8aS%W{|pqt|X| zV#jFaX#hV?>IS_8j>cp#xUsQ--W9fU878>Kw0_1t)%E`X*-g#GGQ{G>-^pfe-5aA$ ztjS`^om2-pQsbP4JA&qJ738hhz{G2%+=^%61J6&*qH4Gf~Y!S-IK;%1= zabV3t&qTu3v2t2HU=plbBVH}81TQI$F$066dz<;KR)?!de&R=1t}Lc3)GA&-C1}@f z1$C(Lzi|lW;X|6UC{->G|bX|B&J5!R1%V5D6}xO4g572J*7v;G}MW7 zItkfLsbpam&miFAh3M=#oXCrQ+l zj0MgBbt|fIp4nxmM(LOZi)Dj>@y=X;fx@W+Rpk{gjb0EmOvx$XXI zX#@iv7R1s>Xs%Z?$eM3QOUHvs*yF-hxZN&1uG>o~tm%VCEh&w8T<)uy6d+j1B}tF1 zsLbI=0;s4{M1jhCdZ4x6B84RfhacJBE6=PrHG!vsN^E07+^h_M7Fci~`yuW0IqfzY zIa3A`Sp<%q><$i~z;BVkDZ&Y1h{-0`Ku@W|kIK_5U0DUw$mqih$pfYKS2}!n+HN?@ z%6nv;!|tN?`IQ$-W+SD1vbE0J@UV3J%Iy5OrCz+0G zLnHGCLf)YhE-0M<4QrU-EdKy`SH~Np`@z8-1*>k#sx~-YCz-IYA6m#`A!P3!RdDj#w5F0{c{Zt8JCW~1ho z!StJHG-#;ao(y~6soi-VLf_F2rq82_Poy^2#c6d_o zGCasZzQIy>qa=+mzuDl|=95Fz1dI*7XedKcT|&~wAi63$U%i}nOGFD+LU3I70))u{ zXel1>PgMvx$B?^qA>F51vWXGC{Ut=q#Hj@E@Zr=B=z-LZ*)6m}geh{ffya^LfabK7 zQx}W;xWh|N9m=)W^us{QuU?lNCnN0M`oLh!;8dn7}yNjvG7 zv_0HuPHfpPZS9N?@fBN-8)9G%>ZFN-c?DE*O{-z#gcH#z(jUan(ApSqCxkX+Z#8J8 zpqm1fxmdKCB5H7%Fk}tt1**5n=3&PxhgO61AzwYA%q=|%rSc1K-5C}dToz2qnXePo z5+!!*IU8NS$x~rS;KmYv7SgQaH-hi*Dx6Q*k^TEgyF;R=k(A2GY4@tRxVC50QoLIlK#hI#$QAd6ZdZvg#II8?YIV->8{~M7{akua(QCXrq{FAO;cdM2cd~j`sLOk^hBVRRvm$7O zbN)J74KpXqgjuqq=Ck`bRr+Q@haj+;1uZuTQ0A24Xryf&!E+tiJ|ZL(P-Oe52(_uY zR$=!% z*#I92uzD5O@#k?o{{WW?$VPv}p2WxS~ai9SsaCeOYU{y z`~ovO*>h#*kVn-cI;Xk46ljUC%#o!Kd#H_R2iZ$+!V+evd>PWXHWxX@fEG&g?8*G> ziKJ+t_uVb7wJD28oPm6E&t-!3JBwO8b*nOYGTj$?9@a%PuQW?`&>pYJUuby_ju{@! z!a{y0c2qd7iY#JVV1P&@cdA+(X1%au4v%@Rdy+4Yq8zVu7ml=A<-wJSrZRY)8S+}^ zzWFXL>OYE~qT)Tc7|)VQ-xzM)qtc?}V9AfB$u3;M<>zcH2E$x`&06C;zXmTYj$i`Z zUB@7Qno+2s*Zehwp4sQ~Dt7+>#Htlmu^1Vdo*&da=-lSHy}iQp%&dt{IBAGf63Jz@QFX5gG8YC9S6f2U@v!hWIvf`7e-1mZ{{V%4 zVr#__Xd_LH?k15W{T1>>_GdD*hi1;>j~gRDx|2-PW`ilA!jH1nM}-?j7N`B0yM-(G z+b8)7Jq?AWv4E;IolxQe(0xauyp_9SD=n&EOPekJ8%2@0ssjZ|R#N0^Gwr5i(~nP5 zNPI)7#?lrN6kzwre1irh{nCXs#CO$IOS%sj~;qDbscz8wFxmMk+|^8*rQ`Xl%9@qh{ws7F^W52-BwLsx9Fy7 zdJCG!;lYUHxxC2e#ih0yMO>fRBlHHk{#+FhNXaC(#tA0);Y-wmgp7^RJ|NLVNx^sI zhYaj{zVj81j2fmktMf#GqU#qM4XgxAAP#RLM}zt(^1+W2o@ATNW12v(;6e+Xfh{=s zfYp8Ay8P2ynJi6oUSkYS6+xq)^Fkd73)>u{9%suYC5!o3?fRw4(w!dJqj`2bocX7t zPwt;&TxNNa2@cjV-EWY7p;|_9aqL4gW8Qg*{KoI|{Z-jqNIFy!G4f*1By4f25_|Tq zlADquf>-0@L?d&6E@|n0;Y*Je379FIr?O~) z@jrZgALfVsf2I%k-~RxKPHw-aIMZdZ??neC`ZwaA;b#n++v*hV;S?&7tioJ8sAiMq z))gu}Me@~QPyYaFzHukTB6TJ|q8OTIbj5J`xCG)dOAp*L^N=adC46j$m9~g2C+MWab&vJP@a$Xe>O|^=s{V% zaglwZDF`L3cIP#s$sZ+mAh?`8#VBKBur6+W{x8}u86jVHn)|1r+X0fcX!Bq3)5c=GrA$_OI=43nQ ztn;1yhFa)jD?6e{Uo@2Nlopy+d6>p9d2j)9Gr#u^wgp(zD)99ogN+n&NElDzJp!~o zD$%jx^<_&up3M{!v-~TMkpOPaf|MLz2}KlxbT0hLW;nFAE_B|BBU;DQ3w*p>osV@` zAgxB97>)+CcJJLp#KDgmAR8EJu!DhK$=Kq#Se&!^(g^n0P_kfumghp&x=Qr!JOwq* zNZPd7MM;Q^oJ?H#`u+sl8I6wd@)!J2-LLEOxJGoCoGytV&|631M)z(bl9=2!HP!$^ zu|9@8sjD-ZPA0J?L7N~$j^5FNO400dThA!MHpVRqM|{+H_^V|soSh&g+^YG7M=19s zsS?Sx}t<;$0*JkgQy!#78cZ=nklH~Yg+$$AHjW8H$&v^#BeSP6wrK8ug! z{{Tm4#r_cQ!r|@;jsF1Ru>SyXe>E zP%%ZZzu^jgQQM=LI{+``PD1;kvFKy~J5YE(yj9%#WO-1x)6FdOk1*#0(6|RJPMeh1 zM$$@%r?f5(g&aYp%^WM3apQ%w(MgfY(v7)jgO9Tu`B*8~9T5a9-a}m!?srP%X`Xiq zR2taw*yjYSt9EI?{Sq;C_Usnne=>ugt^n7{+k2WgXzo@?t;=?44U_KA;jXJwqiN6H zA1iq5mYklA5{5YLiwzGuBQ_%Ji2S!#LKV3Mz0+cik&jDhGb1t>LGv6M2fEU!M`u2F zIek#)I>jh?QTdH?Zm+r=dagY47~*(w9cZa87A-1ok`5`s?9a&3VB7D)pq?_v5J$px z{%cX1!5ojSmtjz6GiFQoatPcORi{TqZCMqZ(f8pti%DthQ%NDhz0sa8p6jLKOVP>m zq3nwKsFS3)1leR6zq!Gv-=yGk?SagjH`KLF;alsp1_IQQWcRl{ANcUV4GFYDG z?evY+Rr#t93}CsW%`0wM332&a*?B<3=8!4kjf9g+(U|*7U$nsOu4oMb&f&evn;RpW zPL>Bs9`^%$dxEQHwvmo0rL82;?mNskn(PdPCc37`Xk z>^iKzCRW2v9f<4EdO3DXd!j9DymIs1dETcJF*O&o4WPUEtyo>@n0$yRyGN(^Ggumi zpXEIL>^_svQSP-3F6ft{luH>)ttmXxW8`FQFMESpIW9c{ zlvR#Vv-NBpDkCOlLn9r9@_!|h*Zg?M44B$j-y=se9)sw->pN7*)N(h^Bjj_>R}|Pm z_9|2SHrlU`b2IWj$)d(%YmYJ?iNoLIsH4;$gPLW2Op@ht3yI(r(Bq9KMf08M$dvMH zmW4)KT|VM$l8wPQff+tWu<4}BhYOw6%>`UU+Gtd|W5Cnk1G5M6R}sw82P>YbIy#fK zgS1j0;YEH^BNkK{JVlQiw(>~!O;boh#U@?uq_Ohwp=0HFt!Z#A+$;j8LOPV_K1@W@ zk6^Og0NNC00C*rHWmBA^wZK1vbd{B^R5A(i&d+v-_p>@PjX=jgq%5DwB4m(PA7#$f`3HDj!_(j zI;$XN8Yt~P$}3cc9uz1$N+S<6f;dlUr2%L;O3+gQPTZ&p7nJs)Zuuv%RBOh1OSr|Ovxdxb{8MHQ--!|gGMz-VvNs*&L>JYs0EdTG*niTbPY56vQTlV;c` zMms#qSMcP`kg<*0MUnGV4$~#ab&x}cayVYqCIm9ObD9ZN8D15RSDmc}`X<9HlA%+@ zj$1t24^Cr1mCX)$AkiN+J32^lo*U*kY!p1dNcsI%h29g&^BuR*%}`S@JS&R#pS9cH z{6F{krhKel!i*%C(dNqOBDb0V2XzS~{&_CO{{W8`VIj|(1*Qi^(;4`<aqDB$-BgVdM*rbxc<$*q9j3q zzy>saN;@5V+AL?(3g)RZuH&M@H*r)4(HJ|08Hb8SYHV4ONH8gFHK|kL#IZLO8gp%O zka$3mw`gS9aXjZ$i^<5!hzbTm;6AFV2Nq5MT2B>1AkJgMYs_tZNLjKr&I;Ly+)No& zOweM_vC%dwG6S|@xhm`@ZYhNrxa1P*pzx*lcwd4%yJsi*Epdz@A$_7kLlFf3gC>0)9 z$t6)`L41)qn&ejMGq80fB+Mb^&>hOMiAPnC4naSf6SX3G+K%SgPHYV=wMBx+%&sH@)=jdhw2Ij{=*mYRb=D|V#Ji5T_0bfv(s}+8U?KHm}KzY zJm30xOHarj{uIm!?TvM&$~pra{?yIBHdjM-6_X|;0t(6DwJDCMaEdLbzr|E+anvMn(Q3%BI!zi1g^d zZ8}rYt0-TctIS^a7X#dtA*W`p4JB7?4 zqJW^B;c9v?N>7nXshTc7-C6vX2^kyjowQZ%uHeqS!C9y!^R)Qn9Swz4hKMyyeq9XFy`4q zCdT86QL=uYjw7lRtw7-i9xwo)q_}ayD6I*c-y;j3E8CSbgPUQ-wvLEUhs6`0U=k=2 zRi3yRkCPz{1W3>bDz9&q5M;~)aoXGGgb%Utc7vH^IF2$qit4ah+{}KUHjqPG&>o9v zE#)=Pmk=9N2X%+m@yr^OjRVpaj2)Rgu84cy&KTkW_A77T-x;$^A7ai2$#bob2jEy! z`#sBp*4aYNd}h-=hr-Ur&VWseGbLf}(`rHJyf;AcE?$Qw=wEFI)fwpEy&FmK=9#Dg z=M#-7{3ggNJfP90GfkS3keW?n+am+m;O4kkAwI1xtYF(+X-K4nQ$(>sM>?8HtkreA zJt>9R6S1Uz5N!U73E~eOWMnhT!6r6?@t&kB;@i+JQA=juQ}G@ioYUq=41@4A*+P%=m%uSup)?Bz8j~~ zo$=(O&IjfKDgRH8-BYAT5k?2)YUPdeeq+i`j=RDNATJUhZjDNhGky9O1z$<6HQSB^;KYq(wv4q zsEts%81ij2bx(VFOaql=(BOHbXviE|2x=o+UF}tpi2(7{JRky|(`J;gS`HJ3C}7fa z9m=Z#p~r-*>YQkbNH{72!UX2^LkZy$V%iE5iA-ssNmF9Qv=OdZZymA3V z)Hjty;%s3yMgaq)hy0P=fsAdFFrg7a8!D&;IB=suz-UsyRF#gH_`vo?3~#a<0xMRS zbZ3ysAui-7@5A0hs-EA3g*+738ccCODKaQ!1dr)Rq*eUT$V!%jP1zmo4yyx#qstQu zjfEytv~Z)BbIDny*|H6k`tB4mVs3M6j*HE8EJGWf`1uVyh3Q({+hTV-c0TLPHCbFI zaK5E#@!z92lNZ}5pS<%(eMKIq^E$_;vWn+=t#nb#n%L#(o(_-5ILtg9oUc66;W-+F zEUm+EBzy9`FGQy5EDaPYkj!H?DqTqZFb4-}3%s+~4)=s4;XvpR*wYMmaAJC7nY4|veh1pt&JfK&9aP`c~VHE%%6o zGAG+r6EZhP8Qb=RRbf)!1T1Zv=uuy#F+Sb1}4Y4x|bT|1)B6SkR^mV`qAZ6 zRyP`HbPo>}EUbd(z#dOmIFfB?aCGQlsYGF}9XM32*5PLu*k=C#!?>cq#Tg8PciCJT zc(N#3ZZwnFys@16G;irhF5zY+@kVHoz()|G2TLaYif)^gtmi$lWMeW20q$we{F7xQ z){Nf_qqbYU-h!*9d9^ZAwld{YEcWxt%Qia?)gV+FMGmgR9!Q;?9m9vsNz=0SfC)s*j7-RkV?pC4MG?tTBl)NCySY2lybDV`J4BoEt3EwCM$s32mC93Qa0ww`;f~f|}|6 z!Qz(}oveI?uKBctH#FjB%G1MI>OUo}tr)pfzxZjfr0L4I!=9)Wo5h=et+A%)Ryih_ z(S($dq=r${DNQ!1pvel#3EDvUsF)ce?HT=7LCDL@c0`W2&qj_dGCWL-a0F271E(uo z17vSJrkrLJbW}5ORLtynIa!VeB3D8-Qb5XjIJ9Nfl75jL4FDH-CMW?RJhRb8Ns;EW0p%-$BfKu8t{krF zyCO zdUiN2DFc@iXhJx<(o}k)q&Qnjj1MT{1c!xtrH?>V4m2%jw1IH7-sol6aC)Nd4}>Gt zpvE`~NE|H~){L1QGMib`*^>jUypC2sDo-k#LDWXj^VF|I%8Pt1uImArr%K%SydCsy zp~C2toROwz$18}~o*e4hLH8>y;%sWkW8))Xu|wpv%?^uvFE(z+%~N=pkeqm=jluE< zQLo~U1N%@OLbw?>ngys^sXkG*O9O-_o&jA%ahOQoQiA?kRLG}0>4K|}LauYDx9E=q z+g>@PB^x4>N1^zC#_q?IHz9{;XlZLl2D|-M*`6oS9UEW$V*m~pMcjqrA;geDqLyPZ z0mqh(_t_=mL)K=`S=2wI9UBxMv$^>)4x2?c^;rE|$NIK*_T%lv_G<;7)U2CD)6rsM z=5;ZIzuYLGy_DwI$#Z4Pe(B_M-g~&(Y;pP59@64^v@4i21~t3peg6P;s%s+h7#jpF zXV1DdOQ0RT%3N;_*Fod6poDiJRZM8wBaVpnF%kri2oOpTT>ZqlZvFF)4A1R^t zy$qtHgN(SccZvtubttlHhmEBDKlw|GBQjzlxgx@Du0O0aK=;v-6VLjndImr)F~6wb zE_CBc&Za3-Cr6I#Ckf#mrt(L)_E)-ouZyV0V`IZ6?-@LTq0ZiKs6V2n$_c zAJkG(W|>7v78=$7d2_(0U4p2FT+p3?>4WO3cXWBwE+pdiw4aYj(0~&fPi_;6t0fL;J<20ZA%RI+>r%>SlGDOgo>N-kwQwp}wu6F{ zAqOW1aG)&(3E=R84=MYR0MI~D0YPa*v}ucIAW*ePyx$f zGQ5cLMs@Av{S;RYRpgii#k_*j(O2%F#ivb|k|D;3%J*~)3#A;fqnA7~y%M}L0Dfbn zCX8+4^ILr_`!nM-s5G4$FG-S9n*ob>0k_>;V?45UxOP>`le8_t$4s`!$Zz$V+^RJR zgQPXx8d*=;i9OT|ms_2F>L6J&Oq8@x_gW|%T+mia22ja1p6gG9`)FK`COl@@=zK}@ z#Fyb|7bGc7Z$%a++La%~mkxo-94FTajYJDvdNHx3G^do(t$;(%h)Ig}5qp6P%bwk@ zBiOH1$>t&#m}NGz6C68d{8~JMszP3(n<0 zbgnKuqQkky)e_4bc`fSu72pA3XYs*n`BrgG-~jeiS#TfC1f|L}GY1P#bI$G*EGd1c z*=;U>*KSckT=s{swDciWkdKiwBg8Xy6=4StJRHg`sL1rV3J2W>A{iyXEF6b6zsV+( zi0#d8LjVzz&DnSU6l5+$?VEr&L7E!qrTJ}W0iXbyTWZk?S>WnvRc2!n4+}>$V{r-$ zu?rztMkhBOMv|+X96K$RRy1YDg-w@>80ZusKf+EsC8O2BYjH;XLCie}x>+9zw`AE3 z9R|`rRjkE*Yfa#g;Ce1!k^cZ8*zx}W;xihS?K50CEaAOR(Qfp8N-W%F^UZs#w}~-) z*E!vO?D6?3Zx8EF!+T(n{C*W_Tx|mBN}0IUbZlI=2_%RY1e!xI<9*kyy;~G=K6DC|KeGx_`Bfnr(JbGNtcGo$@ zzSgbrboa#&09td%+N6Xv7;liwTt)})F|<466^JPr32Q~C7SJU~r|d-Xb7T!hZISI9 zTBdvUw3RnK{$$6V0;SY4+m9Ku{{WJ+P1`o&RT8sZ%`xIVr1I_pfAoGn>r<1kUFIUUYDN7Y1eaFiSBs3b?5nF_1bAmOvHdYU;N;aSRR zR}Y$w`f#F|7eGl_>noN6{i4*r=YIf`{h-v3{D0uRCo|2_u-66Y83Wy=d0s%a0<>~# zS+m6GrI&MDDQ9vxjD1%#$!*N)c%R7loD3{C@=zX2bsG07WF#C>U5bmAHsuF=#r+mD zd+Nzt9M7v%>{o5dZ_TuzTU#___u)#5hllqBgc2JAH{$G4%|uQI#KxbkCTj1L;bLaA zSe`J~AMXwo--&S!Odentvf6(>RSphQvh-Y?9DpW>dC;GF>OV!d6H#<$z<%a<${JTC6?NM$)f7HQ9bPSzQ_^bH&xE`1+U*t<Z@oOK}g+s?Qe9+ zGb0V4<&iqkKZvN)>k{odZB9}L;zpY%R%Bm^W%ZqT(=pLTc|FHvUnJQXE+x(&6yLLh z)fN7i#V&|&u*D1Bem8Iyj~${cQ5X~e0aXYaxtH#);)Y3L0ya7B>rEHJ8SkL6{avya zS^J^&Da`}ym+q!VqUY)x8xA|@UA&5K>a_ZIgyF`FeX-4yj*V|XnS&JhEeP^5!;4mC zbgvI)YR?6u%f~%saN%mD@Rpq>Byg}6J%kf4S2<3fP>Tis0B2-8x3J-=B$~cc!E;~` z@&GP2Z|J&?NgT*voVHEE(y?^*feQxi?{_Z!Q*&RZ?%gSivWXNQry?1X@`%!k^D|r_^~EqHitFbEcL6;5EmRQ0q)l-ASq+X*!XEs zq4|Xl>FysjESgYUZdZL##9YE%tuBIhVmIZ&%z(6B9C$HFA9kDlRBFmh z(6geD-hoGFM0WHGL^NiY=K$uAf^i`{`EA|rNWiYN#*-GCT@)IIgvlptvA6hBeS+&iObMC!fMS}j4@d45qHEL||M?>z$3W8q`rFgN2P z*dSq~M#0hphu)I!lSd0fg9auuz%ev5_5oJAE?_pr6M*?3KO-P==C~jY8plI0Zs^E! zI|h!Ql7TKnFio>IHncmV#{pI0>$Bp#2N!MmtET5*YOolx8ZF(&WeX1mG!Glv1IKDS zD4Ld@$HZJ30qsf-Mw_YVq|c|x_Kbd|t>o9yO2OB$bruL^K1|243J?a5ka4n1GJG!K zTsgZWa|hHa%*+QyeAbZR*p7;1GyS6-um1pv7Y_O;OBpb?^V7PCG-5NoroKvMOiz*_ zBz?MtQ0&dFEqEWAgtE_0)V4|FOUzFc;F*rcVd{Z^RUQwxRc>%~y`^)fcrBFmWe>?` z%Z}BW@MWh=-T>*b>Aix56y_B{N6|6{OhDbx7NqK0Aj=mSApDjJX`MxpdkW`a zXUDfDHkScgx*yd;ev6Fg+{m)!ji;-3aZ0XCEn5VZhB@sWE0iOsXR^VB-^?jtt}mha zS|&VBsN{3V?|l$4@SqZq-fO8(Xv)oS-UuGe3Ve8;Om^W&Sj$LO?TNhw1y!G@`G?Do zhL7T(sby8h9aYs)x z&_VY@cAo>AO=)HO6!uy>O3eeha+!i6q}EnIF6_6t0)O&TGdEU6(V3Pjjb!|}#I z_fC%=b`-OI=>UHslHnxwJx(v8FySe8x=<5b)Bzp8ltvpsu2b0hDiD-9B_8RFcM0~a z8W(y{^d~yHBx{r^i7j_Fi)u3+%8_7%NCt;*BcgjrC@JlAE3r)n1yOjJxh!lsP)O#r zo|pF=tDxl*R%e~3zB;|hkzmDrjJ7Urp$oj=@gN54qS9daiV3#IF)Wh1@UpKN*v>vg zJHRwTZ`*v*23{1fAK$JmH8zJe7U=Xy@*3n{Fn3u^2RY9MH$1w!A9a0`DUKpSWMsrk z8s$XqHJ<54OkcdQ8Tr{V$XOijV7|yvKRM3?OiA}w^0Zs=&F7yRjRz)3=8?k5G-{#y zj#y~x$~!XiL&$K6Mk$h>m#?i~;w+cuy@lOvt#JgWilSxRoksPQZFm<((epC(;WZI$W7f{JHYmBWD7GON9?*T-=C6gYR4V ztp;W|!o`QeGhFS>A;aXNO8X^dS&@^9 z{mpxa$g7P%SB^p(l+D-Nc3M=9bHjZSnEG%ds9KFWQsy_6M(5z3LF3(8=^I?Zu-LvA zKg-**tKcS+i!^W(wM>k3DkeBPRK^McXT~00!vx?^$pfiLynC%GRA#2a+CotL*88sW z8}6qhR~9mJ=qt=Ky*iBl04J5{SugZBk7eZg##5Q9Yov^wo!za5!_XTEdW?hB5(>zXWA$z(N<1t_VSV0KzF4D*%j`inY~1w>Zq1z z@bh<2D&4XNFcp{6O_hHeseua$$wAh5L~W3w#{U3Pk|eK^poqMr`8 zMxT*VBX?y8Opb0T$koDux|E3JvDI22*`u#guAYHb?%MXMthmbw1zANlQ~4^REcI4d zmMp4_m+);sOD_$#Z1SIQ7LExv>ao7M1)T7~-8;|z`W1OAjCn!Bf&g5 z)uCF-khx%)X8IhJTc4cR*jhTMd3wm&TFbRfK1|ad4JFSl^g9=h`(v~94WNb%&ibkx zvgZO`Y^xVV&68zU=89=chxBTa;*9R6A!`jSUxFdq;f(1z2_70xk~`DtJs7PP%DJ^jnIoFuNxrCG)=@j~xki|eJ^XiE&Fm_1E*btem!5QCP& zTVuEStSRj1{{YlkTpf(pv~m>K&9`{?cp*T92V=Z;3Pu}=X2Zy;RW61@vdUNnP9xYw zk}MB(=ea&+m#W8+5!zUHU->Ud!}SIaWs>n;ov@h$IKE16jWnf9N0$w9MtfVsY;w0V z9k-2=H?WVwPf__RKM&33;_W8O6n!j={0X$l52>KO8~0A|_%UTk6NM4gY|H#KVZy3u zqe94uMe;!$sS(0YG>PQ6_FUH^w4#V79iyN`WCGNJ!rrMH)mI?6iRCnPL-N6Q0UxS! zA}Xwu39$e=C4&xpmzLwi=^gCQv|0{^{H&Pf$${Ty>Pv-M(oLHNp8o(Q9B{%qHNKFw zW5DFDS~5>PI)b)l^xp?$zCk8i#4H@`9~b@>zZVA^3NaiJ27&pM$g;`7`%HkifNT$O z*;M4}IXQ#NjowpT@X+eELOAjCV1Fi8P3XCvcDEi!!r{4{cvXqUY-GreSriSF~lT&}3=9Uh;sQGO;^R%_i^?VH- zNlwaaug;b118{!?i?v;;%_he_K3`2>9sYIv5@h|GF-GW``5fp&yv^hHh&ykmU#fFw z^D!9TDu^UFH?<*ZEqwYmF6QiWh;)v36~bgr`>Wl!(6ij|sAF2PKE3|$g2Tlyo<6FU zmEVX@`=I{-^;)G#$=HaT5~K-IMxh*Oq^ND>N! zs&z9FK%@Q{C+ z*1b@8wjVpgxq`YzN*{I->7&9NIZOz$ig5@_e0Gj&(;N+}zYb`P)G~ybM6v+DKtI0* zbN(ajs`UIvX67;x(4SHE3uhcnhh$N3)`|rTq#R@HyBL_DHavJkSkXbCBDV%Tz-?<( z7^RVb0BugkoQ9C*StqGMV<<4ejCLQQ=U_zdOV|_HHs=P_S~D5uHthAKERUxV9*KiJC8~BVOpwUgBQ!^Fs-QlA zq{R0Jj#FB(3Qaplqv#sDbtp)8?N|oyn!k*K0`ko}IoLUjoxgYeBxNQg!YsWQCfIWFj!60oE(^yF)?jeP7?9i4(TrBe1V}|TS;&P0cApX zj%mg_ndp=k5IusMxOd@KG2xSW&*j5#33IQ((B%3VE`-bbiAcY~?o=ss%$UjaZUgsw ztJtP9H*f>;N?ZqC5?%;PV-{)0Ov*kf8fnqESGY{*wbUQjAiDz^K~9OkkV==0_%=RD z_GcLX0Ce*pJr&dRY*N}_a}T&GB)SvFFw406IVs?h8neNb#M)N%MVC&^i{gdO1G{-Z z+U9WfmY-sl;U(G_rx(*CFoa-uwG2HI%=FPivY97xP~f9A_t>AJlNLPkAA@Us%Dyf1 z1EImmBx#kqLYE#3K=rtvq7$~aB)6a+=$xR^wghCG(G|EaVcfyW>EM=DY?3hMp32%V zD}!j8SUQCD4FfE$`ZG9MSK0L;BO?rH2L5XAA`S5nRFcM*3JLCLJR^)WDp^~0V>2{~ zOs;!7{FHC%tyRP}JhsF?!nX$UihY;dtt(idY@jW{DNXuE>mgJGG08@n#>rmVtqbhUh4hZ;bJi4CEi_d zdHN~7Bg{GZ@1BhlKzk2m0t2;+To=^CIX{q_=y0Rz3Jj3CIlk|qRuIK)yF_eF9hGyZ zMxTYvSQw^}tfSRyyfYw^9i^tlth=LHuM5N*jM6)-zC*N)7+~P`Yhe^AO9P^h0N^P@ zl(-{4SFw*A6c-v&NI{XkQ8X?uWPdPPBTb=sZoY_&Yn3E2T@0Vp3s;kPqCd0vgCVul z+V%ecEFP=Ozoa}jW9v+u4@}Y6`h&{RgZeUO+)U(d;?bjc-PJ;5gQ4LNJoa4^npn0# z-i2|o}>J@BRWtDEFC}i$$TUJ7YQ9B&#R5>y=YqcCP zlNob5`z)4r9E~JxR)H-1BPRVv$gA85{tHQy9_){9RR@7_q#Bf&E)^RXTW99ACNDMp zYr5q5KiS#wKaps^5VW2{2nz?1hWX_nI-7p4n%@shWPV@8QsZEK=fl+6sAS@Y%Nm>5 z-6Ks6V6k7Czh;=-sn}S552af+Dhiu&c2k!PBCKg`_ao?1eS>MDO1CVagy5;7mR8Es zgwJF*V(sV^i?~3M-pEGAO_fu^E2k=lRX$q?T1iIYR$E_?FwsoJu0>^)M9WGHxnvX3 zdM}3~+2LT@_?>s{%JZC0z07d@L>1~f9A+;L0Pf=d0E*M(I!PStTa|&-rrC-)t0h9i zeL{X|+N_OmV+U0lCv9kNvd2d9OW$Rpxw}6#(?5p~bQU_^N^VobVkY@fEs?zy5*^YK zIuezocf?be05(E+lH@%ub#L!Y~sfZid-E`EUMsnBtl3sZLTdmiwf@uM=Y(#0-jFSeo8h*8w9U( zWYBjbxGHvv!dUTNiF7i}aM91hAGI1>VQdOeh*t_eDEL(17dFnyS|Q69UKD3WLa>x_ zn~mkOE+h%M6`F&SP7@-B$&Rd+aZM_m7sFN&Bjetf^0{O3^ z2CeAS8h6&_*y8!@qhuGu8{Z|gH}+<^DrTkTIhfM7uS4_sCbw}ZMMhSMIF4pSPKk}C zxDo|bp6at6Q;j3XsGfv7;YGob&}T8_?ksWJRds2alx7^alkgA;L)>h*)MZcEFAivq zbU+4yBM3A)*YixmiOkdhce{`AQLtLpWx^UL2XycM0K%|^t{SY3BoHi)ISSU$GgR6j z%y(o+STA8e%&1uyry>&Q!4G7BiZ$3P4W4790FWHwIQK(q3riT@Y;t|jwXyJ*61XyK zj9hj~-NqvA&OHIX>PMD+TSc_DgYH#W z>mVz*&jA!Ax(6cm9CS`hZz=0iGO>^7t2KDM?K2`ez0tT=id7Q>Uv`V14&V%Y1C;UWo8kWe z3bSGL0-HRI1Ivt4M*t4Ual3J(w(X6oMU)fMxB!#V)QGYiG8?+Dz0R(RQr%Y;5Bwr2Zx3KZHl4EE}v@xdJye=kkcbXmOIISG%br3$lT z9~m?~C)kQdX`m>qrU#1~Ek&Oe*AKAfwucI$ z3S?xtyU66Cg+Up)qZ%e~do1G4cptcZm5$LXcd&vAE~SLbyk|t_*mv+Mt4YarG_TY0 zPp&V7pTr7;J39^Kw$II0yBa_&g{M5IIWd521p#Q!$ifsi7e^-cnpYVtZIS}2ouida zCPds_lOU8$7@W^b2qitD%MPpr=z2bDr;wXN2ygBrlJ1; z;=t}t#N{_DFuU&9ex*`Q-ML2lreeo#*ctNbkRZxuy&~hckWWR#DHy;8^$s1v)^pnp z6tIU^mTE2q z9+;hrlsKcO+}It(Djb=leYLLIOWxhxhaq3(pSgF?tiD!2iIVI*?|(m-{{Tc8FQNWD zJr?>#PnU!ukb@*-wZt116^ZryK~`xvk8%5CjVuy3(!x3qb!|%VU2Il&9(o1k5z)jU z`Ho}Av{$=nP@4D4l4w{ePE9&M#wn|0u{k}{#GyrT5uaJFs!=R|zCTqA+BM*Vy`GxPrnFc? zeq*GSu`pS2t5q>&+)Xa&+^H;{Hq+YcBc2iz+tB%9OJ&?n^^xtuGo4B%G^~4znrt~1 zQ*IzFQI?D{jj`|C_7KxWK*iMB`AjmMuW2Bz)HO)3*w|R@(z~$ifhHqo#}ZHyb+PWF zpWtxDs+n-f8b=1gYt5<*ZB6jI%9Ql)?yQDZ=7VC2k0PpMcv@ke?p1zVgk2&}lUA!T za%^7Yi8~*Q8%zw}60DX$*+4zbDN{{ty~>YK$UFA8l9rLFx;4<}X;|31q?$0{)RzT? z@ehj*tC#i+H*Ldd9InF5zmNpz3(zGf$oe3lcE3GBTzvapf93B)X9sB1z*h%H|%eaRo9l z>ZQ_;M=h#!NDj1CFuS7YVBN~K!@|1bg&QaqHXGhSt5$8iST&b9`Wooj= zjfxKEfn@Xp-BW2IqMLMRF(ms|N09}%{Le)yZ96k-hQ_|Xb>h{Yk)byR0Kq2Ed3hfj z&&;bY>fAo?hkuKdu5Zz+f{NLMpAR|-NH}>G0VD{?s!-z9;%m!1_LmN==vSu1*W&;p zB(Q!0dVLl{#{Lk4P{)3&fZe$b^-96`$8%k6H9HX`R)1N1zlxg{jXtOY*^cG{IeWzg zoAAGho1)6-^6;a|VRib4t-nH7s%e_07PE==oEL)8!e0`Eyx41uLfoU7ZM#hniS3L)p;7KS-^6n&|0+tCR6@IR|R2*)&s_LyeQgtxh~3 zMlY(*6>Ql#@m4knwu+@FHkUD#&>{e|M;V5B8(^H@Nl~2MX-zFcdpm_C5Tha#f`W+d zl&4BA!U2dRv}%LV0qv&QSf3O;hqwZ_StDx}D^_GOWRo{6JrUy6ip#jsP2pWWZ9`d& zkb-N68n6NPUZIdDx;@3qV#;#k40F!Rk98;@MG}Ou*-9 zZ(|=cZ1uxV2jrE_1V<}J4+~iyFPS{i7W!PuD?a>xCmGPVa})SKBrUXPi&AAqN1}E- za6_q0dq(#I-9yf9))G4QQ&{6BJTjle-m1U!p6IVF0z>c6DI7@`&?ZXFvUAiF_&^OK z*#7`NQCTQ{BkG!Zw5=u+!{8wFaHX09%gAf5hZ-vX07^UB<{qr&2fHoqG-UNW24iY- z06h*iera^LLnd=T>&m~@A#Ay15YlK8(xPDFv}Hu<;I%Qz)e6Oqoswc^&*yw=v3!8(Wx$Zk5$CD!fByc!*iKLQ8 zx`E;Rud(V)1=PuXC;XMJb~uA3Sr{vD+|m5kN)u9oXEsq$pBL-~Os>eE8bZ&-MAdx) zmmA*w1_zP4Mi3knDMs!G1Oc@BS4BS+-foW}a{~)akUjgR!QO$%q=+vfJ+5qqgNFrA z)IpmPDdOryI91=tMr4g-M}2@SxKf#p_GM|(M&FJ;-u zvX|(`j)Ox-uu&z=jyomczf=;Ei`X%9mXS6#G8n^H&?~wO@&>Tlq{{IgG%h2|1P=E> zQRn!!IT%DvCjS6;l$qwWQ5_E+P1|O#?NN@UaLtGw3dF&ksAW5Bc-aoV`%NuAk)-6i zWVue--n(y;#aaK`wK)}8`@l-d3pk0Hdw ze3?4}Em8?JUk~M5n&QFUy(Mq>m9-!Qj_7k^#XLqiSRT{Zt07mW>)85)V`GCRKNAV! z)wDCY#I?=!1IWJKQ^UKCIU!rz!*B%rht=t@`^{qV1 zwpaie3^yB(f9~3`f^joLfUY_x%+^f_jr;@9_X>+EaI+hg2sB#p!i5oSIMuXEL$&iweE+z9#TU z7OyjaH`$}9RFf9Ez~=fQq{yV#LSsz#WX99bo>ykO`)wq~6_C%Wersz|BiUC@g0|vu z782t~>I^-5rv|1(J!JcGj8hwvDUx>=d(w1R?{x70hrmC4}y4D{{SW25<4IM5$5pzJFLMhke{up&kaqpIq`qYXY&65 zrVdwno(ocjsDQ3 z{;tCR0Mj%0rn^tXs`45>grMXdFTzW8>J(g0=AJx36?&wvs-(}y)3G8hd)~)(0Ps3*;f{DWP;e_Vi;EixsiQrE;yGgh@HqKbL9XnLk*(@E zUjz1!a8hB%g^Fdv&0uVEJjooVqffWVUPs~FIiwC_kC$9ErvCsnKHh<<>*M%=SMzr~3l>$f7q=P^*WDI92ndHdwuT3Kn9QHN>s0Ok0C*o&zY@4n$=2)iGX;)9elvH1dv`+37}JWT zI;o_sFNU%_+!)RLmQyf*&nckpd8K>dr-)nR-wogtoT}nqY}-QamQ;qg1qK)NQX1u* zGd4(UmL3w5YCBwt*P5c7q-Jp*LT%Dr$)(nc!J!;&3RCxP`XV4oZKbNY1fqDpw+N3~ z%V6jwC|LORM+n|2E{nuDKym9(pv~Gvnq63KDCA_+*>{ZtMOao*J(0GpQp23bGyv{V z{LhXi&ube&)krX${Z0N}9z2p0+ztokgQeiVRMcX{2je{ahjr^%n3(!@GjXwF z3}_sY-20@tQKAsFvmK-ON$^VCjZ}v?bc7oN>Q=fr*v1Bm0B`{46fD_Dy5UsGl0=4{ zu*)mtbg}r?6ImRMe?pTZ77Vyu4n%E|H+5@*$3?Dvo_g~-trixq9z#aw3r&Vq{{Ufm zJa)g6FXBH0M-(R~O9T*oQFY_wuY5hCL!@A}paV09t^Vq6qng&^lFy5>CJf^z6_37Z zkI1U|6s1THg~mLYAR+*o8lDr96DA=Eg4%DlbV^NkvOAy;D)Hxs29=-o>`3i^Zpb_|v-DT3SeReTpTp z9-W@oq-yxu-UD*+o!5uAyHB!_BmzN2c|V4=>2w_NI|+U}_?AAzd#_%`o-C|*=Y_${ zk-M5lvRvS#hC?G=5WlOKWfB&GLY~ODPXQ1hjueA=WY)om*Ey7nNsdP2Kq&*HH=-0W zlO#GMNf>up8<=j?$21f-um+W##M2qBid{+jBPC{K$7Vp;BW~~n*L*$Pj<-^~V7fn7+RQTtkhTs); zhrLLCOE&`GIixsF=Cu2%&t)@{%TC%=ts6{{x3?qesTD0US&Y6H068I8X*mJ1wa)5C zDhx7*k=QtK@+wRpcam$lwM;KW-C__Yj#l(?98olezPr+qo%fhcaq8E8h)rp1B9B9A z+bSj2JVDImB)DMm0wx=`Mm~yIYGh!VGfN|kii3#c330vJue_$7$Wr5qx>WK02OQ>j zz*=l@v~MF&(<7XX&ySP&C=+7=$WpXZ0UsZbXb|1?_PSB-iAL_Gx2&K3H%P#Qy+SJUDgXMc8hh zF}YE{8h4B1ap%~7qC548aN=x*rSLtX$m-IUTZ44$oO}{CkK}14-`QAT4=@N{LuT=$t>>`J?XM$_@gEX8GxmK5nSSk~WFSDC8_ZRhm0 zZ;VAJIlsc*GR6wwqu3@tDXcq3K(mKj$jE6J*z!s9Xe56me0(h2*@T8b%O187MTgqG z)aLyI@g@B-=w+95D0vyeCX(wl?2QJV$eFisaqdbxuwi>>wJ|BUiB1YeV=SE3yDMo1 z=mYGtPyL}=nQ@sEeo$`>HA~LCL8zT4RgwonO^XKjAp{oaZbqunIi}G7u(LnyP#qux z{-oFVvEPOU{$!NzjzSh#n;Z@&rK`i}77xODoApemhq0|K0DwK0p<}me2MHWnnD;c` zN^e9!X)(PLlS^D)jB?u=^U94kAfmkTg6=^-BolTV5#}BuAO8TcWc^3-Rn9c5JV@X? zLzRBx`6|ac(<9Kib|7;Lspf*801-qRy6=@(cDU2Kt2VH01FZzqCP7+kqp`#azKS4s zWhOER;Tiy)6sEN zBh&|-8QGBDj_g(9VuewP$IZ;gl;TTmm8ZXTqr}T|*c&0gWX)eni&15hvR3>r1ES5r zsAcJyUu4X_Iy>Lyp$nZ}7e`sq^=A?R_?nxiXEF(X%;$aEy-~a5dwxn@HdJ|0(V_^Y zN0kfWblQE}nfJKo+;<8P)SjJ5`lxfT0$e(G`6lSu&D1p3zV1lNCGMVlZfldVEL&z-~G+sMHdN$*|C3! zDS4y+0IE2AkU!{R{zoysl#FK&KH`y@-@CM}jEIHxaj=M48Mxl+&l(XNAbgV}j1Fl^ z0;6})Q)EXlQ&CzFm}!9(y%3B<{TfdzSI6h#cGa~7dFJyI*(-Q+92^$@IYg1Q?daeN z=J_g}oi7$vs3=JOZjuAIUki!hV>Y1rSNr$mueU7j9G+Hd2{a9bd%l*uE}~@57Uf}g zE-tjzkl|q^@>Yc_GtlIYazbq}?o{PSB!nlDRd!^B?kztGnIni{P$#!EkUK1yC1}-# zD)vH?C9%d>1#aO0C{j3_;14uag)Hpa(nCtA)HP!r#{dpLyrgRxgB}4BPpSQWOEmYm zn+dRus~HOIgq7w?l4ovrxl!FO6v0UilgYI9M`F{Ki?=68is-#oc_l`fyG^S}8BMxS zGKUGNne$?6un@GmPy(Nm`vde)@WsldW;<*JTXxIE8phdAk0YbVYuaeE*grMunkG@y zw5GbbBa!S^mg7X}3!Xa_zy6PB4#t}ppHxSI@<043m0B`mZVt&gIAFMk3mwAjdxYexcEgJqvzQ#eNwpi+HlJVGW{{U5KjfIPd(d5Fw{{Y`2 z$_xyVjiN0~V;n~zIT>cvoNV**V^+u#$-U*p zS7qgG1T^xCm5|mnv>sJNt}Z=LQ0YnZgD0K^L5rBIthW^+UWtp26WNmXS5!4k12JV~%(Z-sN&R>w!rkXD_ zsl;#E;qi(J-R;~JCIfnV+O~A<|v*W|J{`BYtNo?D5E_YeuYqzp*B z$xP1tmu5T8otWdNS0Nk9<7Yt*^Y)jHNc0b7KTDI#%Ij8u=Ww5a&QL)=Vz2 zRMx)LPARC==wD%CObJHOFgZPr=an2iIj{95CTDOZ?oB3;!|gaZ9g1-j-?|i^2}LCW zXHY6x5d$dJ@cKS!x}`gX5@jvq8HE(f3%0Qa!BMck(YYTh*^K&+CCxfpk5Nw~)_ za~wLg-By!Gdp~B*8%kDYmx-D_`af6i1Il(520jBe!Vf)5jgprf4l^5*$c*7jvQ1j* zQW(||VJV1G-m$ihW682LCOIZV!aRteY4yowzq&v9P9Z7wGth&#)pel_jIi@!$AQ(Qo_(;vXr)N6B}k#^7;1 zIQUi*E)OZ=A~w@OtqLxCNUicXJr3E@$ATf{MI`g0uPSuwOWM*E+2 zdZ=ZJnnF-himI{^-U<=wq&!(dEaf6m*!VpS0?_5*r5rT|PA!K&M~^51B&!*Uq_Ep#V=#LshjY)4sY16I?sbQ8!|{TWOH86msORfjj5)z zdd;SjX}gzNOJO7p=haFEpwCY4lCpDqsM&Gugo;a&9gWj7Q#aJ0&G$L*&2$`gpUqm& z83U2fs5*`}pM$x-6Agq2)h+Bat#jJqJ+JdnGCdQAfz(-3u%U*XrbI6QdyBuAQE>+AR9snQf$#zBtXkDuiqg_Ps?~#qqaQ|0ztEdfIkePJ5)s)n zMUdo<&?9G;HHAIQq!&lZUme;T8ETmAMXi?|nI*f1(i}cY4intmsF=@FL9*jq4nniX z0r5Tu@*Fr-Fo6zGiQod)Z2%hJcUrHeNIOm;Gn&?FPid->hy>6F>XSDj2_rP%$lL+i z;y*PrH%@kR;q8&EZ4OVm=4m*1%?^>ibH{S7o!jWXacL*nE(V$LVROT13vT2*siVi` z&f@CTWV*lEV=%TdMcWH{5VP8@shaW_K@M@C4`jLJjT0A-DN5f(=3cFh1FXCo`Ko#R zM>b4_n31`|-l_egw_=Y2Rul~? z!qNTi6^uGAM3n4|z(2ay+H6~W2%I4v**op`!&4>7ltx{;ngx|78&Af^Zw)VZ?>O3A z#x_iH!Z=K+QJ&$;MSM?oL_$}dUHq04`bN{qiytyJ`kHnUy$ZOXC@L=$;C;J8$%qSh zZsz?$L?0Pg>25T5!^paklzqbHxq$F37FLevTR`Z#iQ2Q7CAv3X(Y7<6m6JIhouDsG zjC{H*Z}fQsVbM#r^CQW>lG`u}Smn8!E}(}1xy34JDXdZidZw283UT<7pN5bziP7ZV zDmCJKmi<4Hsw+w3EC)MRbnN)cM;_*uWV-r_BdAS}LT9EcOLq<4>f;=>?Eor0)Kr*q zT?2>Dl+-Dg6Jj{Ga|a;-k8>SIs8g`=TRR6Uvam~r_{S>20>|Gd&5#hG#{U2=+Wr)n zz;kRBWF|!+1xt!RcvaCn#^4++y~tCV=-%66vWWntv?1`_mD|6(sIY{lk_U9cN@JXR zt0-AFAB9ru8gyE=IgW#8Z!AAGK4wkU7n}Af1k*@(oBR5^t|UifuyShsx#zZ=Uz0fiaDvo zwEL!N`ec}Mwelzu6{(;NhCJUblh$9 z4n_4Y7~^yi6GJwR2n)OO(Q8^TvDAAYJ;XYX3GRJ&qzRq7r?On$gM@ZAS6`;pcBPUa z#&BsH$mpgQdN&nAt4a&F=Kw{US6&p<*{5sFY>wL;zLKjj;taxQ9m0#4z{dwR!5r8`)yj1xRkvdoL%^yk{mm8x~2jKNYPuH;ggf;6%;+P&DH9CY1J>whd?< zkmQlEw#iwO;;6%H8~oLNZ;BrvEsXQ>=&O-FKhp11)SAegFO$(_vU6_8>Qp(h<;i~M zJeyq{Z+WB*nj)!aYm4P|qD6>aXoVsuKs`Dsuts+SNLvX-vMi8@aa?PVI9Sa~C(QF+ zQG@j-MP0)L2}I`baBh@wSYB{19YpPE}tp# z4(F;o@|bkp$AX|^7R^~Q#Wag@C?jd2^4dMsZs{fB{T<4grb-5DK)MNY zS{$WjvKt)~xSi6JTw)vonAQ-mdoA=x1vnHYqO};76{Qdn*z$pX#XN9s)uBxU+=D-| zaWqq3$V62hW#jmEYH>ckCUy5&8eW0@A!CCMG{ABRZ}M11Mqc)?4qRw1$B!@e&L@)> z@)ERtE?rYmj}|80^U3T7y7sLvNQWC1ELfZ9jkSK~xm8{f@WeVUo-$`>`%JCe?{<%G zs=vg@V_xRp7fUuwoTWyrINT!ITO^Ejux$V#&kUu9XH<5|*K|bOrx>-Oxk){ltcbdRXB(GWrlbBv?M{yDAL|Q)`vU64=Dfq$wMAo{*qw!%T`{8|^%|ghCP!l;Dug zc2?%bT^XfSufXHse6jxk=~@Yz90>U+nuG#P4<(1ZF8)gKFR?O9>qmsk5e_Ij3bn~- z4B#kE94?w?F`yt&S`P#l0j1uc zvVJVmTQ)!1nIGQA@qEIU;H_Kw*F<9^bQb;!nRKkmeQTfd5{mS{RmV`)fE0;mn)!m z2KoH@6p+YZBv3qGAxzXU%yPDN^zZT?_)(`8cYFH3RB70!qfe$x$>MZi@LRgOgxna* zC3_u4iR3E1Cnw3sh`98x(OyErGh}I0(G#Ln1C#P9#v%(su7uN_^;6;aQ?Z${1xQk^ zr11dCW08nWEkY6k*A~1H!X9>*a`GE2MXe4N>qUEMG|26{Z-h~rT4kiuv^H5H(_r;J zOqm!cHN{m=sAOd^rN?7Py^ZXq%ldlhQR}#UJVRLdlYO&zTtl zx`I?0F=j7mns~*Fl9}Nz{M2i8L z4SP4d9lnEo)hL<@$8c?*;E80D z0$6dy8-UUpFRdtX{hbe7Oj<1-AEXXtK0^ zImYsQM=O}#C1`il_gVUq22m8}au0C2SoaiR%DBy*pWqp`>0&34NO9=4>^v_m@CH+& zmGHZ%q5|~@9vsj@%KrefPjErGOmXIsXjLG%b4jx3S_I?DTeQdUxvsR7#?h1Ub7N*~ z4u45ou>E^1Zf*|ZT*0sT{sBjl@#CB~BDC8T>OQL)L>;>h(k(&bMq85qyxnjL~}pW-mkBFP+&#ud|NgDx*g zY>hp^ag!-fX6S8ni2KaqV?mLAPG#(r&SS7ALwTkjX?VnX4(&Nr5 zIT~-ca-}$Ic;yA!KJH_c%|76$U6;OGfO;gqs&AO~ns+LQ=^0=8$v;%lqfg%@=jv1} zz4O59w10`gN642VMt#qe@2r7W#ibTH%gOxI*l`%cb!9?|ZA%+2NSrcp+W6i704?Fg zr`=R((-@puPfix-;lnFz2QlNLnt#i>pwzrOBl6vmi!5Hgv635S+$$)Ng*cs?JA|1y zPsWj%*zMqPBYnYC?~^x7n`7X1;qtNityY(r7G@xJ;4E?qq7d_OA=D#l#||ReRUEi- zLgLpBLcg8uWZPNMsU~AGV;9%mSq#aGY>j`hQsn126*5dNOGy0GCo$1w20Ne}DrmIn zP+5za3*Ft`mj3{nZaZ(16LTcFn+V`AbM;2Y6wnWKV3GjgGJk;?ql6rzQ56Vue*i^l zj}(Bk1Z~_Q2uGcyEmwwR^K_xj?Qshkl{UcEgGI)GT0aSAMm*d;j^WMaX7VEC9U6RD zB`un8O6NH$49@@>H9>Od>mndB&7NUr#X)PaAQWmf3gd5C?gM%0hwUr??C zfa+F^arS4+E7CdEeoLI{XdlHU@qJSq;9GW@-h?D1j{&w+a`!u+q_VsQ-%u1O^$4Kn zas1L7vrafV8=aKco3i;Tnm2u~B+1o`>GLRAnNH8kWKj|sbY1R)tLDk4V?`b;ZQUUt z6VbGSt=MTHZb=lYsBXL42&X%1dPq?eaGl2V-MzR+8d!95SUl_X7_mI&NC zg!sY08gds6j9^o4)qXRG1Rkw4rg@^3GkzULhY`i5?zW$jLm?)BNwm=yR;X_M0g$=> z05mTsmjG18MNYHO1kf$}m8LDi-ofk*912u9q)(|9x89ZhOPa`B@@NH}#sXZ@UGHhw z{{T!rSE!dPZrH<6@-T8TV=aa!J>T6Ht#r%}wC#MKvuWgepJkzewM=7Ze|LbjV8JQ< zj(?fwM-uqbwt1dLo12VJosBC#tSONfY@lg+w7AyVfALul5@>P7dAO|&4gI8TAH;l? zte7=uXspgpVE9(HvU`R8i3ib4*JgMMkxd?;wSU%5z&O-N?J8 zuhv~qm5#{OFEM)p#2cG(xhoogPq7z2{Zr=Xhp_gj&_iS%%;lV0Tz2F2N5$!?rADlTQ>b_ z(W%0J0b52l4pj~lhy&=Z@tz$^1JeccN!S2L0(dv{OI#}w*wEA2K8Q3|1h$A4A{)f|g5V?pw=R>h@IFc@>lx<)M-w_R$KaY-nJdNnF~_`?E|M<4Ct_ zEtEJ>GV*e9f8m#paE{FAo&ag(J*2#PsE=Zf^`TY8+eK4#*0kH0;H)9lp^$LyLIzF_ zG>$hIvZ*sLj5g@WY4->@N&}Q3k!c#1=CQ_uf;(jn?y%5iW=46C8utogb)2RS#W81o zz0Z{jZK zi70l3$>d(i&UFML>r8v;3(jY9q^5+dY?2CxtgsCaE{9mjMv7+1AY)CG&3O5G9#O0N zvJ-JD*u0-z9&42cosLNB)Go!8Pl`7VdN?Ue7SOBz0NpbSPweD97PMl0g_{^Z3Gt4t zc36Xs^@ab{f=e!YO$WUd(a6Ktn?x8 z58_ujqDEiIX-vq>?6~e>x=+LnWPrI&$Y3CfP*^HTM_^IA@P??}J5z<>+ai>Cau0uE zy+&4-Kw3JHYs9p{yfk+U*L**y{{UF&5J=!ek+);-+#wjd6g50G49yt)VQ`g)p#^gE zbv6@fM>dkRz^9&ys>-%kWU|RUl{Rd9n&%Fqr`NL3)xSdBv z^BeJwNdExe%|yhL?DI8}niADtKvT3yj2W_HI9zi2hxw!CVHd{ufu}c?lmVdReWE>* z^%f7zDr~5ZI~^0bEj%BRHU^;b;|$|$t?1%@B|9P(WyVWIK92{eKFE+V*;5s6Y3xNU zE)Np7b5>V0-az_Vje}HO>1_jOaJod-@Xkg9Cu;zF zG(~>zf766bDXfv!UC8UlP_1Q+pw)U@+Hm&?kyfnDIkhxkNe&iJ%q9}J)+HS}i8U-RwfpO(#%=A%mIu!g# zeC$>mvIP{${uIe>CprqHN1Ax`plTTNG;(7i{njj(I!*32SE2amJ+Q*&wXWPtO{__o z>~mVk7z0~NW(j>v{zN|IuY%=p)*LUZ7p`GD?t=0k4NoI=NLX3`=Igm$v4Z=EB~8@F z!Co@d8wrmbTIL=XN${rKp%qMzCp@9F(M3HFl3tkg(M{s`{NE1b@q1WG@`yJ^1K4PV z>wYLT;q1Tv0H#-qGbQcdEf|d1w9Q5?pmQR2G{(5#sQI{ZvNA)w!S1P}$^qblK?>s+ zS1bTLZfWkc8HiX~o3LaN$SyP6*;~sLc~N<=5cZ#BIk0dwIL^wAb;&*)oMt)0t%@jvR>F73iGN2GWmtGTO_>D= zTG>G8YmlXXw0Kkg+ZpUXyb6gHW|a5au^c{*DpLlI_g9if)yfbnHGMR;#Ild5QexD! z_t*AJ~J%XL8J096iga4ndkf;YT0$i5w|XxzWZN$vXR#CdBC)3&BVJkOvzERmW*Orw_PCxv;S)&Bem+>3I*8>$)DG#J@=FJ# zhkK!txP=DO(dtaiY`CnOe-3S;X;42eB;>q(+fSzY6<^_;DYXnZBa{|L7^fd`?6#1` z$RiA30ibXK=5YHRZr#y6DNIBG7{9%r?Kl7d|a9kMoCo#l<6 zn#yXKZZ{KM>L!)WrK(31G5~1w1!l0}lR9$Z0BQJ&QL-zJiMmu~ywW%y3Hke~KNjk; z42I#wL6K9U;P6bDLPb*#_!jaw!CN0>nRCg6&ct%=V!6`@&`7Hf7%OqchG z;HfxMy_W=>J*uiV20F_@Z*W4I*161VusFM6vJX(TP9WgQ*=r5}wm?b0$2fw0MDmL9 zZ2)_!bCBlL@pTEp{6qEKxofS3;|Mm8+@l8Eu*bdL5NlFb&9 zwle9Yd!cP7hKoMSOON3Umk@GhY-77y$ybagL_&+6Qmx&H+UR=$w?mC4A9Eo&-=w1WZ?pjZOn(5=o9y}4o%Zgmw z*)KjkCSV`9+Iov=2L4MQn8v>zSllc)8~s1Jx2?5twPGz&bD-DNfW=HO|P&DHK3 zSljAK)wK1vbiQ}j3k|w&`Jm#q{w)qN)#KScGJ-s zS6fL-A8w59vooynsGyH_L3!*Iwy^EQs<7b}F(ZpxG4x@Qxf8H%PcmETX%w)>k0CwN zG{OClA99VD?YNKm@T>mRbYj2RvWt-Nerm%I?scflU^wzPk7`md4d2Nd=);M9#_9)l zQ$9f!2sdI#=L$E%jhJ_3AEJ{Hb1{A*Z{1g*?Q>^gf+nJ-n`?n1p|ukWoQwA=enIM! zGiE))%j_|6waU*HLf2I)T^3(E6`b90u48W?g@Q|C7SUkI9OPZpqs8osPaG&It&ZPm zciEtV9Guq;_Ms?0L^%x$NxYLulN)LvD9?DPdDziG`|~t@rE6o^j~qMu#VdKbH zDaE~Zi{(^L{UC1K83yD1?iLZ!InK8dN%u+}YjW|U?B`F*mFU*T;|#p4rbpz)(DwjO zE705F{COG+=8)LuqVcUbZqy(j-wWO`jlkcKq>Q-Z7f60A(~@q=_IPVg4hE$E0J%MfuH~Y01kqXCrMkja`oaoX5>h~=gc(1}R#O=b}ubii{`JD<%L z77sTZP~jU}hV$}(=p}W2rFNd}tPNHzl=)C>k-&vm_{(LrrPSfCP#sk>qOz=_c8onj z*PwVmD`T>;_j*M?^XRbJV>Y#EydfjZ*>VHHA-|GbrN^+G>SNi7{Hqh)9W@{;W_ z?g^_eq^B_VRkC0|EyM%0t>*pI<0U{{b@D@xC^Ku1pm#3e1E<+hwb7Q&WAQUXx@~tV z+B}xz#v~51MvEMH1 z4rf9X*&5$1uQFFRPAV3W8467W!n{Jq|oO`Kgl&3Ze&=0rFOinX^MSAD^>@iK4ol^rM$(dLgD+%)^yiyh%X<-kTWhae|Rrf(jHxo$6o|0 z%c&QS`7fAkCpe+TcuyrVFG3`?FoXx1bt96a%0MMcy3s~UEdY`;Yi;?6St`Wq`8Btf2Be@>R zL{k}IvDJEBwWVTb>C)p%6Fo!HK;$08FE4Cw!peR$zY`rrNM%xV4oqAXgmydGZh7hy zDO>Ad{_rY%^0~m0cpa1{wazSex&0H&<(3(^$IK~vKv1A*YZ?@Q^GX(i6dT_E{uuDKMyV?$m8Lv?_uVIld@Su-G|evI z06e<7k6^u178r3c+XNAYF{6MMY?&`e)sG!*or{YGCOct;p^a$Z1oxUKfigivJF-I@ z4p)}7r-IUGrERoK=6Nb5Gs3l6}>mhb9tYme>w;K7+1-SuBHYViW zBjmJtT==>^iZaVUY>ueg_?$1l>YqGmMv$1~a+!Z4#Bjat=+=_F%0~yt=YI2vR+^T% zo0MH1?=Clf7I3NB*ZU*G4l39==gHC?wMfQ}NZcOZ(RMT@M_C*NV;ci{CQ3uRd`|2f z*v%xqHr4z?-9e|rCz}=V(5r@;QuJ*mJwsZ8H+%)w_SaCC%k;0r?i1t5 zg^wJEi?ujo0n{wMgP3EGD6Ni8aTj2_Ol~faXNPQjD@T^?JSbC; zBOv=IihUT}UNRW>dn$~BSRq~OeB;0TRH*XBVYlcO+U;6#ln}_=39umqz58F_?{?!it(7(@JF&3Ss4E4q_+#$==mx!;*T-W;>g1EWJM$)$I{of zmW~l`9Po?cIEf-d!D-<~!F{w^!ISzn<98b@86P|%xtu3LJvNW!+N7*hrA&b4k<~S} z9l#|^mOBJ{AnYv)nhG*a3=XFz$nFYrxIvuMWkSj+B?H9R0RHh>Z1K96p6hw;#nv%p zYrY3^w^;KGoOVffxLvIcG?9@s4dF`8xtMsr1} zwWz-@Df^u6gRmaTEE9Qh0=lq*ia8UVvr^bzF1)v>kA0hNk3Dh3 z>Nu>-#|6>9hYsv_a8`VY_Ki5?x@6Y!QJ5_PA_*L+Z4|E>vSf596ql-6K+AuVhcvgt z7+ilswAC4pDael;G! zP`qAIV^k=!)0j4`SB7A0Sb@zPypmRFn{n}Xekxl301q>6odN4?1!d3CtHqnJl(mHZ!nL@&R}uy>U8PR^}7tt8rOBzbTa(nx4=vmt@;J8Z4>0qlE(_qWcK*)ffes*#o7-A0fM9MdUnMIqpxHkC2*Y}-6%)A;N0 zeAN_9(B4}k_#_cxyDPsl`>qGwP-DHYO5BLuZE@rdFQCT!gr;rSzgjLX?3JL+6d z)|11Oea?;607YrG?g{Cc2e|N~$WdH)QKUQ-QhFH$vNO-EDC8kM-n90+g_XUVIMOO} zj>93kB_^AU8IBxB#H8oM*R&eyRG4FEji3$yK}L>gK#4m;ZO$~HNm9|S2STN4(w4c9 zjz1AXjyi{P&d?PWo~(e=<;wRDh}|D#d=?I%ReuynBVm#5Jq^;6gN*k`b~L((JS#+$ zl11hm4T46<@lSp9=oBqtRzv2ATv+1G!NBvyt60Nnk1YhZrL4b=XOaw79<6xVK1*a{ z^*Nlr<$r}8|OhUZ5h9~*1*NRrvQK8YB_ zI*OS<1zU+Apr^6+0s*7Jr7jojKO@yeq*ggt5>{9EvmedSrz4shmzTNg*fODRRt(S) z@vwlrdnz|UJK}itFwt8)cX}{+8WE2B)_;k5=7%UaQGx6ik1^kR-;uTJ9v?s1Bl;uq z6)rwgOl3up#ynsCh0w+lrZISr|3DEtq*%dF&>2VKav+J z7^286AN(skO%FFP0vY8n{wMML7Lx->!_(S4xP#yO&*Z73*I(ancx!q0QRt+s z6vQ#qIw)CF5DGR_gLodwyEb4Wb&x)*Jeji`KS;S*?T!KqyDTQNocZS<9u?NBoLdbZ zH{C4BcbSmgqR1;o7_aGz@+Gb)u+lUMGq%r=K#iy1?pJt9WW2U#*p1Uw#U=72%gF}tx?3y5TyRNYBkw8pItu<=BjV?37_4{_mX?ck4xZgm+8vJV%{T6! zCPdkJ1@b&w&AfrZT{nd{$@Fp|o^g)_*ey-&cAq4!adfY6fVkW`E|++*aQGd)SLI6&`_OLDX}IQUM<(GwHe_V8L( zp93t)*7M5D#OBB>6=9}KSvQvR^J>jFn~|wxrN*7n3sLmI2=`5fQL&{abfd}^l8cu{ zS6Vd*9_3Q%18zKH+$&9W*DE6IO0Cpe_bdx;KSm6XOn!|yVJ#=pRQW#sVC%3uDtrM> zA60J`q}r2P9plN$2{0Oqs~Ck-j^iAF^j4Y2b14(U8e?@mZWtWfXgl5X2;%A@e1&-t zweW9*;_}<6>I~lZ`l5;4f$UGZ-HPc{I|11SHiob@qMFe_A_OQy?0I)739)GxD+Hz2 zV&9HUTBF31Z=|hOp%9Z8g0d_-CvZKA=VpyFuj9(#Xt7=$7*iR_tiye<1!D`jq%aki zL!@JR(u(%qK&O#mMv;`_J0p}u!c;(b{S!=KK9ru|G*p~(2T2OePK%X@?+mpKjJ z7?HmaL6wckhjn_uMp zNY{En`Saae!=H}~jAj-KB6GTKXtDVzm|0T2lFyMKb0Y-RaF*na9|WSTl-zcQg40QS zdCK_kvDVQ zP511gY6JSmN}e1!Sm(&X8tdSFRaSmaoc7|v^{$W$f z96VcF?9JuqI*tvQv7fj1n$kf~3=jR&`YrZ8qnyT#;7H1$=J)xhPm`wQ#v#nb*a^Q& zdVXOPW|*n?^NTRSfIw^6Rpa9q<`)pRb9iG9A~J9@+t1;5DxWjMS-NICnFXzqHj8tZ zdJm#26DYX$XZ1XWv7SqMmFRk0K297=stjNs!Fg+*X4K+qx^HjuUbz!Cvb~mE-H*Z1 z=I-Uzrs)wx{N{;9;5iNVP;EJ{E%;3;mqTNwdIT+FV3tNdeVwKC!1*UZiex`{*St7> zGr?4vPFB$yXK`~#4m@(S(d5SHx5fs+-uXzS?0vMf3Opl(cSgYA=JX??kO>lPc-q&F zTh_lc*ydv+9-{6@;Mx;J(@5=wq>z0s=%Z`U8-0+qXYY}$jzR-#;dgbK%{4vz*1`BM zFy6*_oq;!BpG8BLh+6kd@w;y&B1zqv@wHTnsiFoUBL_tiIgT5I;><*rxxczp!2Por z&%qV-OG&NmYBLQgF>T|#qQ-aL+{{Kh%QsNi>1ekq8*!})JMt-s_}=&cw(?qR$=HAAGDn$&x=_})GyKCkMr zm@^nNW0LBM+sZ`xM6J6!HxH;;@+xOS4&qkgJEF9R*a1>uy<20t(wOzpI1UnmhSw(( zXi8{#kdK7XUTxz1KeKCZc=%=;$N8^DS??EVqc=o2ghf)62DY5AN0pSL@9(?OopO6*~aBj zu4%t-z?LA}ac`&UuUybU1aO37;UcNn^(56Z#bt@`O6cTaYno_+6PqC18s1l-c%Q=Y z=frYxnj4ZiKi*kAE5jMOiKv)Z0jIg*scVi^Mj7FJis-m`9hJ@phjaA`ER3=<_}(Zj zZj<3G4K;z%{{U!|_jhG_#)h;ty$3*odA|lj0$GMr>1-1bv)rEZ&}vmKTv$Ts3THE&DnM>Wm4+vqO6 z;s<6IVd0W7#}0M!@BAuM&D5vkW7|ZI@6aPkIMH!WBOi|djBa->Kfy?A2H;OApdvG< z2~FA4#{{Agyr;A-0CoxBaF)$cMaPCP+m)=sEpX)kxJdE{;Gl9D2(J5X z0CWpG;(0*Q+`@T~fDlDojZ)MbD6#Wo*~5c}u?wZhmHb!@JwOVt5_25BTaEnG_j5&U zbCOge4lGjpC9x?e2`M-wn*hrm;c7dWK;=&AnD*GE6BQ^~0j_*c+{ahA_fsOy`^Gp5 zdrkG~fg}gFDl^$d7MYp3L7QAGp(9%6^gNHPw0dhNlDp$(ZX^I za^d$sqIjA&i{1hx%=v3gbZq=Y;pU0q*4#I`mCRVwPOam98VxJ zapjOtTmJyzYxM{OInpp5Tz75uw4933(D3EA5;jYj1jNMRY;P_-8V}2=v1{Dj0Bs-{ z`#AGoHCp%%MB+C#gT}*sxv;IZ2u!(9VZ-WVYydadpZq038*;RoLv&~#B%XB-EOZVX zN|CB(1`o3_u5obn7WVlgPdr+7D`R5-byGl8;Jxn~opK&W$sFGp(V7wYC&`go>e}Eb z{ew+^KFTT2lP5AbUgx+y)#x!0L{{RU&4LB}jFPVYv=-ua%n~v9Ik2TKPBNXsQQa!$k3!r?nHhh@=@y@=d`4uUE zfYuU8F0yaGxcRF^Px;tKW5X^>V#Y3W-e?ae?Xdt64|Yu#F70{BDS)bg=j7MZ!aFvxV^yK{`vJ^ug+ z_FC*mN#-4-IftiD{nF0j;^~fUINB@=q&rz0ZF5}Hd?nlw31bEI=z zNIcsOg!Vcz>Nan>Cb=L~oL!j>PXUmd-F*9h?}ZD~kj<~*?G)qg-+#$#HC;5$&{*Kp zRYY}I%~v8E4ABg7wbQex9^LIJL8D5VXpfY_+l{~x+WR5l<~vQwKY4MuQ=8bUHu-sQ z)p9$id3X_wSqp1}c1h-S?xEXyv z-b#|#^z9lLGNpS2V6=Sp`jp?Z679f}NC4WRi&DkKYYf>;Cvc~?kUqZ3&OC_oWo-D9 zw2(Tr-w);Nn-9Y-T`;k-PdjS~Xm2C~!X`{u*+jz|*e7du2*a(-A2ddj6N9Oy{wI5W zOCjPW;ponORz5_}*7Ark?KQ>w4%{awCbnn!99^P&qmh{g2R5D$MSG2pTx=kQB$(Ofa#R$O_mO<|3N}P#;I=sn zWCH7)d#b+(_={GXD|>f(UmutX#*48VeZHLvtC>D*Z!S({!9~?YT{j_rnLM z{-5|+-X`Tp(er&mPRSlwyP-8oLs|=4Q~?`pM2}d~@^Mb39&-*XeLD946F%dTxe#bJgj!V;$RzY>!}=|YpwHiyqGS7p>ZejS#KG5=Mx0v zX&9L1UCk_e-Nx5^zKUjx<1I5&@X`LT%Z40=##r`WE*+?MD_6wOh~!R3pOjP*4C05G#Y6_?7@+SA7F7WF=O&U1$hr>tYV5ES;C z0IIw*YzoDW;*#;Q@}REdQiqwuF8Kv4D0$zpdVIPO4KvBSZ!vakaPHxtnpt6Y!KHuW z7hbgS`=AA$-OAg6eM}xhyn#at`n?gj?eEGP9*Mm;NLGeN+mzQj_z9b>NoGAqxypz} zE#VAEW0J>Y>1DIBFofoj*Q$kCeT$yh@yyTY(4s}JPVC_{+{f9SfK`rrjDB7EZqs@p zaZLvqG|x}c@?wxR%yoh-X|b{!vaNX@hpNk_yl!zZ6Vvxr`%lzcJ6iU*7M_K3GUJq8 zoxB+%k~%cakdfDfX3Q02a_$0(ksO4YDHb|VEL$P8X1zjT;?bJ=2-KPpD3codPT;8Q zb%ans3GsG}t~Aa)X(DwbAx2snLTPUaTth)6Ab2B>WVRY3{(4@p;V}Y$`p-7Sq zz=hGbYXC|1HvXqMGjSaei)tr#H&3lvcW0m`&f6okQH-1bW6?HAcK z(zT_a^>LuBvXTk&O)?iS*99PPd&Fb94olj}TF^dSRJ{>LbPh+3t~{!IseqBf_y>hA zE@rXE)k>Cpn7+|ZdxK9>(aj+2(-lZ=RPd4-=HJfM9-weUZhptRZ*Bho_*VH+XeF-_ z&703nyHt0<;q16Ps2!MQ+rS`G&-o|fhaIy%Y>DX^+*q+*UzF@^kwiBVU)SZ)Ga=Y| zr1DJhkr_N~us~Oj(K2U&nDFAXMBaT)pnugPG(ATV*Y+4T*}pH;e@ji|gs3*?t;O)` zCjv+%E)5o1=Jfo+3(Ht3qlKx!nb72eC5CjO2O(5y`c%+r5*D)JE;}4LQeQUvH$xm? zv{$jV&`}!7DAD3gA=<_geS*8wyd$5M=DJ`YVg2#Ss~)7HwovVNVQTA3@ZNr+1H(L+ z&*PJYt<$_cfv135ADJNhPv`h6C%CnnTfkJszajM#IfsGv37-RA9wRge6>8c5=lTi! z&@tK^_q_EkMU}4K>FM1ml-p}$OxO8OEd{b4c5qcj`6QQn$pAX4)y78codT;Z+fDZ< z80hp#nin>A7+mI%EC6^*jjIrRxyS^2qe4r-H+)h|j4WAN9QMd4b{S{b9T6e zvefiEycmI*ptarG&3#oQdJdtTk+T;W@{{|mS~2BGQ#n3HG~J>;18N{vhr<5=@7Xc} z0bm@HM!DcC4LkZh)Lj^C?v4@O&7aX(JHi7&h~zgV(z;g$kXuPPB%RRAN|HdO(_qZT zk~cRc&U5U%4a9tch5pOPT0-3TBl(k`h7bFk6dg=teU4YTv9xU? zfy%Z4R_l%})7$~-K>jEuv@;y;RYCBXvjzs)G{7wPMj~wHK(c2J~N5&f6{J0NwrO*Ak5V6)+FaDy%U0Jb9qpP&Y@8VB-KJ_E-7sPJUDWK@|aa5dC)3T7@)f#kV? z_hH9^0r~b>CzYp1N5{d=HpWTep9@X6jCt|g4H_qcqs`!53SswJmPA1Idw5f4%Ey)0 z0dW_0Ko|UJcb(JHNG7NYOZl0l_-d@KXY_o?C1ddQxVJFa4sTE5wECnkbTCZkHO_4@ z<-HHhLTiCxbAh_5-P7|^aAX;peAwV_p}1L7pCv%7KNI9PPKZmDy`zvUbM4Vi!ileZ zxsGjuYBAou({y-4u-X64&^KWJ0Oe}IYlmWoG*LafT-MjI92HLz86PY48IZ``6&?YFjz7WYUzKJ|TA!N4x4m^Rpwp*01_HkdG9@Ux}^<^eA#iMdN!WW97$|3)p$Si!b6C9Q{qr zap8>sC*$P58c_Bc_fWN5p_iyhD}EEeL5dW|<&~l$<;#|nDJvg8D;f!5hIg_#YkNW9 z($QdlNE)^t2iV$J@*A}YL9Hj))3J^uhSsN($%AE`DrIF45ER^C?G*BecH}#y2qA zQFHZp#snfKyu8SF5;_n4l|Lv%=)rpp4z2^1toB)j#z7p-lr&qLw~_Nnf>L90NynmG zI)pDiROO=jJS$HO`OMcMWN&e4Ci$yaY2kb%%M+{tiCZ)JIis;unpc4) zi#8m*yvIGQ^*xQh($&r;vx}8JR-c^6;F>29GiNj&&u~>yJ1yBO9UF3k+U>w?a~*9x zxct*`qI5HF5?dX2xca|OWl^C+CIn76`DY_fk^4J zhbvB<*!gXVvd2xGr-s<;YO*b2Uk_+TeRgKcC^Z?2lOXNSx<0^V?4*ndMC7!2ZZ30r ziWgw70nf~me5oDgIo5tB8zpQ!LH!_SYZ$J?z{Pen4j#Ii=WNF#dqd_TxX1sf#Um%X+*Ar`6!8p0*{&pkmK@F8OTD*VSYQn>q}R0GObAQFBgi|<@wT}S|1sT*5C60 ztnmwOFXZQD{{WGS*HV!bZjz}A2%RIv1$B>(*x9&_iHuk*d^WIedInUknf_FK0o18E zGj1D40YQFDa5S}^qwc7)n+$L;mwZJ>d%-*uIV60>$w^e9LX*mTOx|qt2_lHd`W-u| zG#J_)m5~TdDcVk}CIp}oOh>5pRrZ^?1mL8G!y|*VdWM^+GI-kNy1`daNFB|uCen3T zH2j8=NsqW&?K@PDCMLa);QZGsE-68stU1R*`<`NNb5T zj-+-uL}9de_@u<>&p3w*ozl`>uIih1gbaTolTQQa6Ua?Gnn1%sG;S808%vrg5b&u* z5wW{d9NwQYh)*PTLvf*MOQIo+Jdy0V#_T2sQ}5k5#8Dun*vcAR$3+`1Z!L{?u|;%* zsB#l4!(GrDRKrNI#l5bT+)&{{nfBuA`YDcomxjjsi~N-qepqWBepC^9Bv$ON&dNKF zDxyjEJnl3AT_pD6UR5?uP?}Q<4PR1@5wf!7NoXYUHeAtrhzIbkE{}r7L}VhK=GbZL zN~cD{hDn_>s0jLBa;}**NH&z|JsI)EIa>@%-0ho)`YSCz5=XVbz1)gXAYgpfRsJJG z0HmJTt-2s(XpNbcTpIhmz;*hg;$bkuAw>P(W2ydJ8NvPq3Am^xnw{{U%wn?)+kDkO=dvsR$WEyUGQkZ)$<6g-LB z8ysK29njT>sI8JM2NvQ_`fX$kVqBfe8AyT z#F=j+MzS_RIUZDzKK@}QMvoh#sc_>h`2ec%d>O0AIyNi+0QM^wye+N3;^yihr{+mZ z_@ugIS=X`?^bI^6!Usn0lZ`0P&>(liJK0^x1T7;pjcaf+X5+i^>ZG$v&2y?(LVc(z ztc%#ing%X!3rx~Wa+-dvDlzchfA2ZRz-(qsPsi0kg^d2wAQS#B-g%H>RFS5DI%JSMq z>sVhEX9B_j>%tiQq>-jojtz$JZdiQtz)vN>gYLJu=c4lu2R*FRX#OVB^z44fGes$t zhE7=RmJBGZC@kw}%_yMgM8-}7m~B_g(inJFjut6F$Zpn^Sr@SJOVQ{4HjbcaO|7FcOHJ?usIGakA>&nILt1ExZ{%N zS^SpoGC>#%*~4)KZ;j|kEv13b}M838tH#*@f&g+E-ZHMKVHhD z=@yl<(R0LlcAtl)MomJ&bT6RcK#}dXM&rRBt@cmP$ZkffBa61M5YhC%{2|QT7DDzh z@;TRSc>KTBbEfT{hsR1VR5nO-sht~Nm}8l}Lj|_Kk`!-f$lV4@Wn-QVHN21YL-HA9 zou$q;T;2&kGyB{K0 zNa;qvKpHN$2dW&_O5fdof6XQ*iK*f|xL*^#V}*GJd^0o_I2%p|C=&52g1puA z(}9rL0XrZ36(r;DO1L!o4#$t5^;8o(AC*CHugwBa2($t z{M8nu;c%O~0>R)AmI))sQZQg6IUZ0xKYpv3=v{-PNp9U5&nW8cW#qVD) zny`u-Oz$dT1XkYeZISLd=)B+hK#S~}%PTC*_cw86P>6PD1E&f@?#hzlk4(bB!_%yoYe+ z*8}*hh;rAC4LzCiO*Npo1+8#vdju`kn)78Pr=WQ$8d4~txX2}yqDN`+@G;Kb5yS z3QHxRv$J9+gJ^E*gvpUNhZH4&nEF*#r4gSBSnI2QmnzO~d8VM$|83A(<2n15o9*nQE#Qb#^m#rV0 zLd^z}Xf5~jn}OwOIP;FVYfCW+3L1pe^Ul!_p)XySrb8VU6ZJQHniHVenXs4 z?6{_i2>G8O>S-X1xTTG@;G_o7P=G{xQ=1u)+gsHd3?gNda-O4Vf3rVg@W?$ubF3K>O7Qw|ewm7~)%?PffPTO@Aa z{MFt*P#_y#NvG;E;Z7b6wERJCwCz?rm|E!G2<|(D%gcqu+B=vttcssz${E0I+Ls)p ziwiZ4naJmlWoZsmPePEL4wMru+bwlQYk?dp=1aT1sZqX@V4fbxkh`J==sFzdp_h~0GDlw)m|ab@4ptmuIFKJlx*O)Ep2pBipERD4 zK^f3fK`2I~kRao+5nof*cbS23~J2M&CZg%Fe)$X9;G4Gm( zB%|$P*>%b4tTb#-GblfArK0U=r5Kp4%0S26ovXs;4El0G(qE4r;@ zuHR(!OKQ=gGErui3E+@b`BC%b+Y6)} zSm5FGL60b8VKt5QNgdzKG?wJT<{!q*syCoib}O>@BKo$}DJR~-F2ajHn+wYw*#pgY zx?3L<9nx()8cFApD7i*1_e^wvDOMe%8cBh5p1$c@lEAAn^Vt(=RAg#WNNO{(`jOol z#Mp`XFoB}W)*^&$bH)1u%An5FWXyG03>^Z1UgsNgi7L}e(KB^74=z2C{{YN)MWQf{ zHM5_SK1|M+L>9#P&y^cXp5ee9R-Z@kX84;fd&>#y8+!g~??&+CI&H`rUm^Ttenp8M zM^Z{lxh1GeJ7x7syK-*j3l%5EGzF5#$#m~`%_>sSs|-D{xtT@aka{dGxi^`T8FmL%u$iThxz6YZ zRe{W#&&hlH6T*Lw3wCDnr%|Hs!c8yMp=jyNuULtUU;qW=9vI3P+RP7kOQq{j%-I?o z({?QflB#6!UE(YnLVn^u2|q;`Oou*eq1)G=WR${`N%rsgZvF~BMV6mIO^$axwn_a{ z$)VEzsNT>E>daS*F`qsuWKp@s`ZQTsxpds<+8o?D$qpaz&kNdMK3lgjtsjzws%2`p z@fYGd9l-t3!0v}LrZ+;L-cfQMBZ9o57y8`UH}D9y{wc0OJ%J4hW^&g$bI zB00LSH|VoUG|fZ@84xce6njkMST^|}cv!CV5bTHXBNdUj9GhJPjh+h`wxUg6@ z7PeqP@q9U}<+M5s8C(xbZCbj={*8P=lL(W`hCA%}06)cEX&x`nIHo=OS`7lx)7fwF zc4gtRY`h@y8)SlPpi*~3Wd&AvhJS>$ojJ}D;+JjeSVM>KL((*j_x~Um9>6GH4tkgyQC1#rY zR-K1A_bjVYqyCVz*&X-#BU$r`Vh`w61tC=N#g?1`AbXSUVTxeosTMKQXRkd3)9Ix;=_6uPmB z{W~e=%hhn)1hF~bcWRS?;wBeun!)yW6s^4IvY05e-)m8)(Xp~kxs-jvul@w-s*)$g zsl@hz9d?Y&mcP2A8Vr#-;>d7su^a^^JWQBt*J#wHg-RIx7Y%z}DR_U5bnoil5YG@L z%zKQDC)lr7cBJfQ`Eo|@f+4mz+8WTY{uZrM+|P+QH|%NuN81ca^6JpC|>(mn{Z!mo8kP4o+`W)aLb2 zpqsXfv^P6(w5}3_XUNB$w|MqJ+3pJR2a0tr z4|6$Vi%+;nemq*Ct30mR>^irMbj=bNn%NnXZXhxjf=A4i<$BJj?ORiuEP?~vXcKfj zloDwoJa|+9o>ws!bJ=p_(Pu7PyPst(1;w1CVL|8QGRA<@jtzQTb?{gZ8V@ShVgjsB9ceC-93w0hx__z=8)OL63{eb;pV0P8I- zd|I<32p?X{!g8^s$C>d+Da>(ehs|ij{TVaIc8Ii!z?cUpj0;JWENuYVAvA;?N^UGI zBh8zDJ`kY-K?se$Y@_H9XUQ*+j?1$1H@jmx1PEKX*X*GJG!w~4@x>!;1EK_`+@S!! zge$XXk3+QzIVeb!DQ9ZpgZV79&993#a7@$bv~pE`J`P;4vS&Gwhcp_yQaq^`05iA#(wwf0Q{#FF z=GnBHdwV7a^G0TI`6r(=3)^k?1yz27V4V@NLU4o@@|Ci*+EDA{9u-m!+02QoZBlHF zPILB^8f=}7Dw%7O8Ib0&v`=tUEKH$3swm#ZlA!APme%?m*;e>>G|#L^&BEOifKoAS zjFU-Fe-dWUj9*e!e!Udg{!C0DM;t6^B=zF|0L@L+8rML{Tr7uGBKVI9t-+F5q_Wc) zJAI2*ylS>#%`4H3ixNh=W4bLCl))Y&o;tbT!BT?uGocmkjRv7CY}m#)fSDy?qbfZI z!@3lCSh8g03ywyR#)Cu~M96s!wm1qL z{FKM)+J;7jD_NuD8H-4JHjSj7zcl#5JVnZG%nVN20S>fw$m88tI`g?ZXE7tDz0W2$3-76RCE$FIo50VT8ELZ?rk-I z{ZR32YRHleHc*c2bor{B%})4_uYOQ-Cv?Pmjge$~D9nlSJ8N28eS&^GX>FJ@=WWzM z8DAl{n<~c(L(R+q!J8U?6P3P`;nE}$&sWqjYVokx!q&Ek9e`4KD@ZJUI+o;8>3$K% z$1Rs6`L66Mg{j8FYZ?G(Ye(S%f-De#ZOE>8Wm;bSgwjr;jwO)+d?CLsCbsuhOSSwAx^vHI)^ zwA@Uo<;Y`P_cevoN#RP9DeyJtAP(t{&0|IGP%%0Tg&4)`u#-`Zt~TTYs>TlwR9cQ6WD&^czhP)5oO;sFe_A}cw{=Aq$yzD6#nI`Q za($+Yi<;MbF85Pi1Da`!bH~2rTche2ufmPdx!VWA9nF0epwuz{0C@h2)Z)7lH74yL zq9fiT`jjmEaVD9P2`#A2S?@@aYH_x!cjl@!T-mZCc!UtpERcC4=&j_BqN547(SXR$ z5>EK%oxrqh4HrcZA2TK}85oMa%yxfLt92hnp)bgVWf9rxOmU=`+)-1LOtgnu&4(1m z$1;h!^2hoq^J@66F}iT_=SI@&j`^iQG{L)Q)r(KeoxX$Z8-J1-wmwjdS#ot<8bRyB zbe{Chr2_*|g_&`;77s2L$kKNkJS@xdoar{O@>Z8bYjQL3qH{nY-0-SVXsFYAE;8qz zK37)}4&LYufZs}1*{zNi(?;7>IT>w+BI0OOrPaC{$s|(vt1-CPCI+5gz*tuvRQ+pE zc7AJ}ev!cXD)72^akxik1Io+tWDkf)$YC51MK4~{qmaWL-vhB&e+YP9T~8sIQqwWo zLAMU2dViG2BBq6x$!b#3x5Q2`*w)&EtjPFr*&|I5Ri->v(&OD$_=%tWJpEQ`G`U+O z=^0MQ!DNy(rN_N15*p^!DqS7Lnq)QHDy)l^#Hv`F%;AWved3V?44>wQ75x>9tnV&j^p4v7D6>1+y{Z zjLM2QLFMkU79BFM*y$e6>kz)pzG%=iu;IA6+wp6UtwilAeG26NMFHrEA ztf-q^BS`-Mxu>`k-YBemomJrNYw9xY#FgiH7!t9jQ4w=HkXGNvIl?J&qi`Xw$)i+y ze2-O&Cmv>&vTeTX-dI0F!Zo2%c0(BLkZz727dL65LHa8br;q(Kt{&}pKgl7& zYk&MXN7SPhS1uN&yBfM;k@=xM7X$ke71;m+;n05--nS>a(tZj_=2u{$2JL@#l%sQ8 z4<$U@H?5(ta5asDI zgB#14-K6ld&mXjDhFjA;s$C)wOYo-hAN!z^(xbon#|if|MdSCQ=l=jIi$U>>S@D49 z0O8bH*5hiCNYE@0dli+X{{ZQ>GId>`c-osB&`IE{24uqK*`yyM8dJDN%Ra$Y>XChx zA2JzS!c770i<624K~2z1$+2e6h_kDBC)q~T@T1Mf-N2cj1CR1hah!a>TuDCVS#IHH za<^mLIOwOsX^r8o6jp{G*@a&wGh}#?r)&NF)Yu$DHl9$TrP1a1S@GsJ!2$iiSlRyo zZ2ti96)p+ii924>XmuXyE=$`kL*!uE*Bb$Kaif_qOP41n31e3$hLhQL+EA+)lqIB; zsD~7ZX>x^#xpL(Qa^=gEA<5u?6B4LF+lR8?>NiQNlq!XLi8fLsN)#+rCr`l0)U#v6 z#$kN28UQHD@4@aY@g_5x?W7-iLpIcH2Lzm`v&ry|nWRPzt*Mt}5q?fE-Cy-|O=ENh z;yO%S8d?07jn9@se}Gro=9Pn}Ww<+hPjR5;o&i)c;Nt1fyB0jx$1|O8-Y7VGS2nUo zBa$@B9~V?uMT-oPwdYR5$7_X#xwdIYn?4OZ0sT*>%+fD&pg-z{+`+V5vA=Ie6G6XJ z%`YEY&dSJ-54D!l@WYER5eDRQyj3zXws$rH>uIYk-I3H_dM&s39}Q&}8em@X3oLEs6oKmrUNb z?P;2E*ejBfqaFQbIy({<4{fxK7G9l@;K%9v3y2$|kdNS=be6f!jF{t>X(7!v3HC`2 zkYJSks(&r*s%r)F*OIcn2;0g;muR?>>*pD16$B6tTrt5Gy<~G5U z+i;nU>+&ILoT%ND>9ZXRPd7+qCl{cj1vKpOZBI;>Ow5xKb{0z+q7)VEUOMoI)$k5p zBY(BR-e`PnUQ-?~knQstBk--5=*(oIBs$U+AOlnv^gbEP1DGJlAzs;m-l;TJ{LeW<(G`Nez3QWY@@YwVHQ> zX3}z5FZHWmBu>9fB$N8A8DP6dPZn8L&6YRzXvA$hqXK{^&XPXtXXI39XMWmy*hueH zXr;zh9gztSvt3`!Ep$iy1D1GOXUk#z6;7qCJ~;fSOBm-G6yS@MjOV%6id*$?S&dRN zi!dRCxLwy|x3RER_Fl!P0_qOFDM)6b%iFzT;mFCFO^~+SetngUSUHn5r_YFAVC%1~ zDI8OmL+6_mT{8M@LYjG1S^BUb)2h^Y^lY~Jou3#VCX%YMbX@m?<>tiW?L;D2U$7o{ zrD%nz>P~qqW2}@d3n%QltWPGa(~2HWg{ne4(7`(hCv;B^{tBGsJ&&s`b5BAjg{C-Z z7^j<*jn=D>StFt*gSiK_s;6gU)1oeU4gsV$xCy`3kmcjUGxqM=womT3cTN=Hxvm5r z;RLQMWNK*VL6YW)9@-s)jZ$E9S$?SZ9^T3CX>)4O`5;B&Jj_QJupq|A z9gf>0^G6(wKEReF)f>%sQ2RWvK4-TS@)};1m{Q1cpC6pvt&l|L3ilrANd{&$ zom4+llt%Dc!?aQMRZ?d>n_(dP+R}fr+FP1m_Pn`2yddlRRE$3Z!JJ6P$;n`7yO$oD z`r38D3Hy{da+kz+TZryYDbmg5xHuBhdQnz6-Wbi&OUNzAj5O|ie}n2fDj96Nl@m{) zt3<}<&K>)C2hrtC$JA#4e`%Ng@~DTIXt6oti$dUnQ)Z4mS1b=sRKNF>c=a5YA6)Vi z?p{>{b2v7XnCEg^gMAEBOKiG15=bfUbH1e)%Z65h_O--&fK@TcHC&>zDqz}ZZ`7;! zCdmA(XtMhzKm3+|+7~+uABu&8{*?imhDPAqU@kNVa;~x3;}|lx)O#Y2i`<&;@%1eH;&zA1X5H>s`H*JxzYnIqnErmxccTrWt>z{lA?FHhj34 zak#u}aIQO$tMT=c{D2IgmpZ`O5whiMI~gQRd~UHs^iZ*|Ad#`;!5f=SupH~U_gEf9 z7sZ_z;g(g(CFJ_tc*aJ%9?YDVbU}k$k0Lik7Bhptd(5y9Gj(YuZ`p(qFpziy*;C=_ z?8S4O+(tR>70ZnjrwC2h&NIfgXmLOKhI68of<^$~TK;e9tF`|C4&Y$Vi;;-ev>8X6 z8FjP|l9l1ijI7ML@_25*13(-p+KxGrH#;UrQ+ea5KOnKoB%zX!)fF{tdnDUDn;ID% z@fhgeqL#@3>&N7O(N^j5z47%9Y3NnFavp9VE8Hye{*52ZKu<4CgdeL)sMIpD8v$^V znm-5>t|rKyR+8*;&ueMqDqQ%CkvvLh0b`E;0Fpd^(MjA)CanJe{-H4b^01A;*v%l_ z1zoCR%yXuf%XZD*5F8|icd|W&q^{naRT!~k;WuRbr+gnoT(<6G2Tjp5e+3Rlxjh2lZN=7bIinGE!(X1wi=2ytcRl>l~|GY)Nxm z_~2oCg>X8m%jmBjPi>Z(kBFl4ZSMw$VzWA?t&yG#aIws1a(k`JK?elF$mJ!YCUIr<3Vw~D1pHwMfXYr0tUMH2Acv7@%u*vNqNK0Gc3wog=o8S`7p4mp?7Iz_g3L z$#9^&a2zOh9?KVI<*3^UG`>t+8l_p8llF}`Pg||_jjqe~d^sLX0HNWZKT2gf+U|NP z_dz78$uY>*;Wg|OHx377KO}9#4)*0#G?rq>%HfT$tfrUD(hIKr1pfd9X%#0#NcAYB z%#o0|I1mWsSc3OR*VWKoYoTfeEmh)28heNqSEfQ*=88XrCM3|eB-NgIuI9ciN@7V4 z4n0-Ak(AjquQlChsy`J*TdB#rxmKEE3|<@#Jt*>xMNp?Ufi>muz1@OLDT6Uve&sST zdV9|B(nWxKs93Yq4Q2F8n$URXY`6PMP~VmFRnC~-B{$Fh@)Z%B%MY~k)hNgw>bJ}X zx>m``z9n-l8!*1A2C=COY&jecAaI&yEgOlT7H7m6zI1{RZ@EmxkCcSw$;Krtk1|N- z6J(oB3d=&%nW}2=;z&qrhKU_Q^#=a{Mw%&eO-Vp22QM%}_VbES-f=rkpGL}RGTGPvw zPDg+=_+$@-rGOh8tIrF=<;yErIAciuB~)^$&q2!@gm!tpe0ds-xgTs{1=BgydWB1o zqDa>6i0%v4bZr9{REr{fxV*>t?-zC5Ow@cOrPN+lKFS0gr1G5Q#aW#$Qb_R8jgWd?elFNkLj1Umh}G^NX*CS5u12iOC^SzS6<@}O(I!nVizx?JflIy$)I zp3AIb(N1fL>Z)Lxf}F{L?vyq}*7X5MiNm4cL5@yEqqaazC@G`E%R`z}NdN_3>llA# z$==cElb@kfc}xv(Bf9HBoVl$GjhoFuBjbuP8mp#)sHa)cBsj|;{m z*5b2UT1e;EDsZiQIBQss{4V}Q22bUT#r-3Bn+cX~8tB`@uKJ2ujZ@K(WPjr19>r-L zJKq!zG8Y#&VZUlo=F)uqFny(z=JLmXb#vo1yE-lnl`Ug3vDp+&x5@Cg-5W*Hv+?s~ z4uV#=G2E~oqqhjZ)tOTm*^d_C5G0;}`+loc;mm3Aq4M(^AD1DvTdB-F(fpC2Zybcc z(b(x9Hfv^%qG{gZK@L1QXIr6X!6cHHBy@7yqjlZ19-(RVIkGadS*PGe1KaD7;P5?x zOp)5GGnVBR$rFbKm2Ce2$0|IFiExADWkt37OGW&`pNWS)OpPw|v>pixWSESD8Iv)e z+F0MbY2=f2{)kY&Qh}^<;{^XznO4IZa;Rk}*26DoUq4!Dt~|?h3rh#_Gm5 zAB~&@GhHz8zR6P)J^`6fSiTeZcNY7bp5oG5j+AQ1%H7V0H^N z^d70FL#%1jVouQD_WDnDyRlhKANo0gmoBFg4YEhMTjSv!0g*Z;>Cu3B1d>QrSduWp#zxv~U^EYqQRHOd8nT8x zE?)}bMHUeP38@K39`;ZKJ%FCsB1!Uc!%Zy)9r%c;z#1r5*P%wxSk@)9PiV_?d; zHE7u*nEWscO;K|%_>?c}w@OTKv5X*J#tr_9GvfU-H!E0lu#Jp(0J!wOf1>O-XTip9 zCPvwOzK&_X(5%@c($TX76yD3`Heg(4o>JoCcy$1xW@&>s0rri6brd=MP)1Hu8R!mk zM@vI?t&q=$4tIZrn}W=iNpy`;hB)>`$?)9Uw_@fouWxeFv%0n}v!EZe%y&ZfAH8dd z7PRtfI*D)HY56}oj+J4|&dSK!sA>5Qhq00(T0bSy@gto|n$gVi{udre?5V`@Z0v8Y zSxBy0PY33cC&rVw(?iGPKhbGnW}X4x3wh*mxA}xeVCd2`hsP6%H(+1-uAHFL+Bpff zuFQ5fh%$5KFy!hF#*V!%YeKEmu_MLE8#5V~zn#rIkE++@Xu3O`?=mP@-p*^of6Zkx zbnIMwvdlb>IxpV7eu!tJ7A?pGE+WH87wn`AocwSd8~3z(j#FccZ7H#zKv^WyIx&a? zt>yvh3_tXz!QxDqTsJ`z$M=C!4lGkN63_~3G?q&6!6O@Hw>)q@r3z5?6uB;gj}+xi z7<(`=9kg=VB>svF-XqGEM!aJ|323iFD%O`5`aaa#x78agUk(&hmVZWBa=p%*A|@~k zCc?Uhp?5!Q%SYl}UBosSn;*@r789SVYZ)%vCUnj&{_z+3Bgv!VV`NDaC-Z|%ZXF6U zSjb1Apdgig4vKAThaM(QJdMkFZbO*h?=AkI@2b~fe@HHlHpM=X8$(5X*`Plqo-ZX5 zIV-C{`h*FD;%nmZ)+Ckvgf%xa#nIcC);Iy|7JnWLnOa>I9FJ)nIkBFp@@V?B-v*yI z=&6*Dn!dg##CAL^*d+MP*>}}t9@|{u!6XS)> zeKcCVXM}Y}Hp^pg)!`MM5zcMz$%Zl3_ZmdlOB*OFZ*YE!R4_w3f8HznE&`R<@Nn}B z27D&RS}DLeN-o*-+Ed)!DQ+p2*70LmU#1_U9345K5e zoYHz9^j5I=9L*Eijhnt^ixIeO-SjG_6G3$ObHO3n_%C}8RP~i7W+&rLPm3by&|zch z(MjhQJXmNv^0cBk%$}&pzi!G#3>cBb8q8)yM{TOXkvabW3Ucy41Apnu+XpUFro}Kv zir7Pl+*`pan^4P(PK3!Vk~%bXC11N9KrD(1CP$XWT&)f#-CxevpkMlGe$3pjmr=mQ z$PLN=1UAKa`G7F5*uLjQgNZ1BN9E18(J%#Iqrj#rRAG6 z*H>V9O88rsCM{-)jV3q4+PE0)f>_$^oN_H{Va&&Meb^t7SP_kxg^}inUmw(PtfJLt z0)%Zf^C>y7K2|#(NXd3=GIDX-AHvi13X>}$H#oOwU_EQ8L3EN!jMvKTt|I7Ku8=rY z9!a1Q;f>f%X)O>l@wGVLBy5Ll4|TM>bycTJ%VSHO3&0-2*3qoa)bnD79AMJesibg8 z_venv*l3w<$scOM$aGt1vNnqSd#;33x`~(M$9p{PEjDKdRBw3O!2ww3X|Kl+RBqh( z!=1;-Ee@xl<;6KVewi>~Z>Tr}%8{R>=Vr$QxY}+&m;fBv0HOR-RB{76n3;sg!JV;( zHV1%TVaI^4JUb(_te53vv<8+D!@0kzvCGi4=<%B_L{4OFe+?9$iHuqOmROqS?YD=H zTmJycT={g%gN=Pj8c&Uep*!Npgkv?JkmF{`lbx^OIh$lYZFB)wjXpTd#|v71K?+P( z2W@i&e>I+1lXiy1(gA^t&1+n2jKpMdMmKG5;#)bK{CGgFNLc)BS}hAKfgQF{e*APt z)VyZNA-E$ZPJmKudZ4QIMAo&y{cj%?qWwTWi>0#0$UapT-{!o}M8lIm#8FExFMONa zPi5-(;x@trW9oa9d{8#)W<$przFv^wRlU{K3&8VzzejE}&6YZ=K3@S@HH|t6b1sZT*&R`J4IF2{WrmB# zQSP8aCRf=d!*oW4w#QJ3!KMnxr5Z6hCY|<;dIDk*$r6i(GCmCv#}kCWjhhIFE;Gh}?Z z?sLtXS2<(<0HBt3+rU(rB(_Av&5tKbjtN_`SmP&mVk?!GgFFcw2^I+yv|dvo!H!l6 zcG3x0Jdozj=XAFe$VE(4rs1?{#z2%#?Vm8q^y$C zN-IwaF_nzs)pmBQ$lJB9CEmeOgKRf6m6CNmO|Ua-4Y_9=Uo@okbBb(|$urB(B&+WS zx+rznWyy>^jpu8Hf%)pB-JW+I+${5t$juOI8qx~S7~!}Z z&u1SruJKMgz8t_$(PHs@Bbk$^c?@l{e%;5S*GK&y<;3U4#x(60W1&O-I{h#Fm-tM? zmr&N_5aT|{1cSPQyzs6wqr`Ntc=H3_8=KT!s&5Zy8iZQN^JSAAv4US-l0w+K8w(N{ z7}rM-uU9qi)oH_mF;-^FozF!-g`NgBLGuFynJ+8{zeV0H%ljNy~HbA#imh$XJ@Bxl;(CpL^VB3sN%j zvoN0Ma)X$5-&+UsSnRwxv9leJ=;VaS$m%QTuQW|3J5`XMw7x+bM>0RB$SeyAH+=Wf z3pa>9&+)ob?M<*&GgH)`m6qwf&voe8&<1HzZp9v8A)?#MPj!^mwETAIQRciclN0a) zIsB7x<56}iEZmWq8AP61ftMh2I2{okGY8-ZPRJdZYg#cfu0zQ}>ZZ!}-@pQj_X2nb z(LmQFw3MtPlCDUh3(X5S#{U2%$LO`#^9KRS^M*Xe@aCRE)#-YGmNxT7xmdH~y`yiB zmbA@7AGE1)OdZE{RRrP87EzlpX#^}SQPE7gifiDb2}RPWk0Sc1Eu0h9ke5bFHb1rF zy^bF+vN?mN$kN&aVP*BqVGdUUn*RV$T}VBgjGYxscGm)?M)yeS9aL8~kul`iAo;B* z$o5S!mb8+D;c9z5Y~@FmAUYxdgyG6U)MF7PGDZ;92!Ix*k@8Qa%7aW9NQmHuRTd)U z%avG1E?l`n3b}IS2qNXnlpvv6_;ID$%s_iP`6{5Td^sSn#M$*?e37u8{(tm;v-cboXO^j!UaIK9S4hmtDFrQ^uAo(r^k zBoYxE&u>RGCpulxy{>q1*}8$~y#3xO%!%!cZ2{4MerVEohauSx81jcVZ5K2U2=Bt5 z1j_#aBOjw;`2%rU;%U}-t|J$(xCt_!2Sfe@NChI%_=)DTatDd;oQ;Op6k&3C97jero<$3Swm^;ZF%?ENA87TixFc7 zmiI>E)P$LFtqzAf+dU#pOBI@%BV>bogOIF@CP+>42%7s7dS}jM##g7jRm5VI5J<3_ZIiNQY;y*gw?cjq-3@!q>e)N z?gleqK@qp)2hATMM^5199)f}sLwVdT`f`}8Q%lh1Gz%e(c!q*ypH&lbKC?(6#QBn45f7;zfIR5t;j(F=% zpij9~+D3SGr#?=x95P7bx;O2z-|ml+t{S6U@mp+rsZeLa`C1&{3F+-=GIOEO$BnaD zh|GMv#vBZI;B!s7K)@(_eC=ol3Wvk9K*vvR0rC*xXScGvFKOsOS}@6QvnP=Tr%R#+ zY_EyTjyCR*=9&So;Dr21V1(q8zCrOcdnJlm%9>Y@3w;6P{x0fUav1NI=92igY_)M( zE1#`~fEyj|9nVE!q|WS&UGlrDxE{*CFHehkm9zo;AaIL~l*nV)&H@-^YI|ccV@@AZ z)y!a&_58{c;1Gi(0=?PpqC)wyjtA z_p;dX9y^Zeiam9h{w2!67GmM;;=r-U3i-KFxuMNA3QgLkH7~-NY#i+KSy8!>wbplc z9?DyEj1bTUC=_ptDtq!{Gy&(h`6XnG{o(m37{Rcd=72lPiV_Sg+8Tcd6tl7GP&v+x z@wzHBOFAt~`vhdUVb~y=XYs*z1!}_Mj(rN0Ws!DTws`LF`7j2H-q1a%WjszCbjbja5n{)5GtU;O0{mu`vm(r?WpOgeciNPOymnCGWs;>u z3EgF6oUCprq=_u#Be4!P5~M`J??~&}XR9=)qW4Mg-hQJ9m5pm6KaKn=$h->T-(Fim z`86(?s%2thMGyh(V|iiVg=WtYJ8%wzPlWhmJ!~yvy!>cjFbB%sT6Kb=_OJIga{{YiL67ZpY6)*J}akR{K zyWz}@8x!p2rLTMib(W zuZNmhG4f@EQZ`t_!Ry&uczz6QtzsCmeNj02g{+wruRI~A{{UI*9#NddvAe~0rJ1T$ zY~BWUT|1rkj+Qjyl&#dK zZY7}i+~6MTD#%Ei)TWa9m!Hz|@t*H+d(+)rab zs&aKm4c)TOCsZ146jNkET_ltX3u=vDUWl0fD8?-R0CXeh<(`@ea?DXOcgYlg3uNjQ zrXHBqk>&uK2+oG7C+xY0K0Nl8zM^ONlq~EmD#3n4j~>D5(;f_H;sCLY`i`ovRD1$M z=xaxE0zNV+%@F0(@$qBwaHH7Imvqd%A0A7^Id6{S+yk3ogn(+t^G<>+63;R(DaGH2 z(lnRlk{m(z39rI)T$?#l{{T^`aYbCd91+ygY5-s13^!wfn9Va25tFs9GnO>FaTGyT zE)Uw!TJc@_A~tv-VKYe3-u5h_kA+LIGyecll4S(iz|tr3ORPkt2bH00_M81VG6_aDVVht#bwa`b1EBka-1;}1NTDLjuU%kT$4*l6lN`Z zJ{!o-gAn&@Ox*GH_EE8XIhzJ!<$hx_jDnn8`f*x!#>oXapo7&0EiVcei6h4ifA3jG zEIg1A%Hy^1pPOYzb) z!^)L(d8m&g7G}CIW0j`Gj;h8TYg37|8r8fSCN@?<%gY9LJ-(K_P-yuCPwEXT{{TfF zUxsBhSiy=MDh&S6&#@UySDI<}XB#;Esdpx6bhHknXrmKbc(y zk)`7}IxGgU!=a^r+2js=ONPd+^3BN8BsQi&5n#MJ*>OcykM$Tj6mJQ=`C2-q) z1*wkIH2ita{FvH%i?sO8DN&kGlXgs*!YE{LZ$^{+7oM5q`*uW+Yli+wu8Ucf;w%R_ zkg`qBF93i$DvZ20Bj z8_yMK_~lzN$#T(Balt$USfG1;5?g-7Ob`o1Y$?uQtW6Ni5}){w{ZL(rU9ak`ge$(z z3La=LiL#-%<-Hmeu8oI~XJ$)Sb~VDvt}J=(O~f=W+oIk;oG;cIj$o1{FQD2^-iBn%yf{nFg!7V zpxD)46~WRhFOPDCeG7GHxkZ*K2OoCX&yy>5hg- z+{p}^s*thHOLgbu9Crxb-i;h^mmJL!cw^|(oUI;g!87$H8Eb~U#iS`2xS08kW=kiH zv6hy&k_%oJpT8b$L&Te9h0(Ro0xokkIM{iHkE7876Wj6GfwDEjMaZIak$Gd7!5@YCI%3(V<9tVtsT~ zJ|TelFu1qz($q1aFa=HGRk3=&QRgTbG zMFv<1ZweMxKdm8^B3PUpf?7hLkj2F*2@r*1E?l`n#ay{^gb{M($`DYj^ah7&@rMFM zJAw37pcBJdN%<`|gLLec>yS?*ep@JyUmcRN$#G+_#knEUNKECTI|NbOqs=p=pg;kn zfC9eD(#!LwX=S($oxfE>G)6a;o}pojUXH~&8Xs)hj|QJEWfnamj=9%?p2pJ?q#j>$kf?Qm856Ge87CF9L4UN=Cq2p-LU#_$isW2cX(DUpMd6FjXWKK&?hv@zrRr=QVQJ`W=x zirRaHs>spcg^YY}e4w952bR~#M9jg4d~(?FOCAk}G@JR4{re)6DbOn?C1ztRo_>n7 z#NMu34802p!*m(0V=B*^87BV#AhXkA<3%B7+X1it08^1g&=T1KCbhFhTpDS>)6b{# z`6KERGdC#DUlf6qVmCz&9|mt$jQLtD}2`A5iA5m}7KnzQ+?evK5A z@hE8~xKdr04^aSXnrgdJknGM2sDCCm4VwBzrrkSJ=KOnXe9cBp+uiZd7iLPc^)>{{RF?GQA?oTY~gH zGf(;V@Z(L?)W|pREe;_XYEhu6nuP!hmFhuOqO^HI)VAEe{f$5DDv=}>-*bT%ghoi%%>NyknhUJdDw|2CQu2ELPYaITiju(JDJ&za;joCzX zbDzQdg0hRl8Ve(JX_0zG-*S5(NA{Q*>t&C2n^NM+4j^oB`mTTZB}>OqS_XVKqP$nw zA|FK?C&D^Ok<4rbgmiNq-C4gNHKfr|B+hReY$)@C94(ZZrh@G^4ou8^t->*7vH@g# ziloNZUe^Fk{-J1d=lg6@#lFF52aby_%_<2Uwmibq^6tF{gXB(7+dSv`pNEb!(ljx6 zfy|2d{K|os;yE25uAky6B${48i)hqaUpA;O(xqd$&JO9QnvV}NeazRJ6o8yaU@;EU(z9IWSua$f^J#2g*nt|pb^-7mQPSB&%LmFI1q%frWw zVo5S4qv6d9CK6wcAb0%8_#^UIZ5kP|yjvbV45YcTZ4M^451QL&O7_KXbq{rdlPXL- zd+k`x8`}G6Bj$_5b7`p$$rvT3dnPowEocuR-<2tm%=6W%78LmsW5($sWtM_Veu{Hm zQ!U9NLnJZY&^Z;zT1_`E7HAod zkpm-hMQ(2vvaF72Wc#UG$QQWPE4*w-%nW922ZCwrbr6}4QUSYEUd4u3^5~|q?C#2B zLS_ncZn|=*@v$-3(CD=i2=^-69xxei&Ww*@X>=5##5E<*{G8^)6}&jtS{)WwR@b9( zEohR>eieP1A~CqPEu8$8Pg2E}Z&#QDF3GN{-9CiMQeA+Se5@)id9%$EYECbSa)aox zr6U;E#L)H{Zk;=_Dawo&9Wo3L!0DOXU`H?ZF`!td}=$y=n@uIJ@ zU(r`(>vNm_%m>vmCLy%?6y*TKKs&$YOX*}nCVP}O3p|@W$`lzh@Mi1KTXMH z`U|VL=()aJ?a|xtG19vrhWg4b%N?8=n1(m`ujBB_|^!8HOIG`T` z!RtopYVbd#De&QJZqp$wV4_**{!1wH>P`*ZnHlle62hd7yuZ>8kDC#PFAjF|V{5qz z!xzQc9MXrinSg)*xZG>>>akiQVTU)&lNaqGz6!JTTIOmPj}2=9i~FU7Qt9CPtFx7w z93@7k9JnWelQKXW@ne4n^h}m%T;>dEpm4uffB7mWWHwd?HO+N%!a(Ta{i~>+-IksL zk)jhcA5_tPPNeTRy`)6l{^sZp^I4DUHnLWEFuqf`a$Cbk&0URuNa%GuP)AT?q^UkG zth#=QA7m0ceCNzQ$KfA9jKLq^+xb$in_AIiX!A83L;nExf`)bN4Eg#>3C%q2+kr z!>pJ)`qw5#v+zd30saUcOXwvU?AF9z<&QC&Pqo^InH-_aEyxkKcXApB>Q+{7=`&0q zvl9ksiT(coNdEvd&-UL_$ZfYt#dAkZ?z9;v8m7X>30{#6*v)RKlIdmHQkv(gv>5t- zl=9|>65gd_HN5$9=M#bDIJlQJr-AZS`1+<)Pd782V!11sk`j}&&YmeHqiS({uqBQX zYoSkvCoq!G)5uxDtY(PWb2#zbq{Y{=rA2LFw zlNw96G>@oPIk^TXvEz`3N(tn5Rnki&f}Hmssamngxa`E@qb(5x4esC)hyXkbMcOSq zG0wfCpt6{o1%VNKkz>SsuG+>IA7Cu4mxi?6CTv!_C87BQ^4FdR(OrqLupU_4M#j$1 zjlDwE3=OL}**w_7Tu(iZLeG`En~5nO;Z<2A#Pb`P<~^R0)5k^Y<3APS(<^^9<^DCs z7~1rbF~Q82)nnaUuu=yfna)&K#UXJ9HBHKLUWEk-#v7E3`b>GDi|mm8sTp_Rg0pu^B3V~5EfnEwEY-BH@Y zQe4_*pN=wHDn7@N7`M0q^;<13TGFyKDD>QbH})+(3Uo3i%+tjsvW%_?N<{HTE?l`;2@ptL@Ygz> z*~;Dwg3-0&oE0uJ3+HGG;zkFLn$41|)rmT?ba@{;Qd>J|XPqnHbrOpncTQ4%E9iI0 zU7mv+4GdHsFK?HoHN*GTiJ*q8uZ<;m#DSfQ?G8KSi^|sqV~OQ=REfY^=p56ScDNOw z$8df)Ay92rx^&jfhq53fOe!q7K3S>=@{?3JwGL>UTC5R1+eIha1BDw=WQon}heRk@ zEVw(B9rb)94nFCwP_YP1Dd~<>5@K59iOp$opr|9Mbt`Nw11~F+wkFra{sOwd@a7Z^ zYvyU0{loqr(I$DL5%9q&8CWp#a-`b~FMao=b&26eya#1US^d^^{Z^f^wl;>bp`dgC zQs#PG3dcVsy(3;f6)wn7=DCBF(gbMaK1#>R1!XoKKfd>qIn#hy04MmR`A#ezG9l-IFFCQeSk*0x8` zXdMNuR+j{NR$HFX_Q^-7t`#<`hdx~Fc!k?sEiyTG(HGPv z_(B=7m>>Q(raF20ycC~Ld_7cIWMnXVk zmPu-XcL7~t;xX9ncs4-w@zAMw-WYa7ZZMa)HQt~HApF(F7KmVt@Jk~BBIxyU3FNh+ z;S~qAH$%dEaT@n+0!N*@hsjgwkhdE;Sb_LWSFu{?q>>5ShXhS~F{9q{;5Sj}&(&r; zK-nYKCuG69_ij6SQRt~5a(5!2o>B0ne0h;Mjj|pH;WKC^z(&QflNko7!=Gg(&{5kx z3m;H?%-b|T*scvDHIO`xTorCML6ibOclWA_pAolJE_-_(;HyErxZBftNMzaYGSAHP zT=x(tD6+VPO@SDuL)LO$=m?Tty(4cxsb%wggXn7mdy&`Zt>?rOhq$__wlDc84~_3` z(&FHK)`&|(91^_94AhRQk4iBReN(zi8=O=6GXRnY*168V6gDSPHX0 zLCMp6w&cjr9@1LoI>*qaeZ7da=&ti+bPs=+@_$tc#oLH*BkGR9x4Ha^D;_P6K3i$wgNUHg!wVNaEYuGIwi>70{QI1(dGI0&vnk_#ub`|!a;Qc=}kC#oK z%btl58Z1BPi2)}^o{-bs7t0NZJIrf|<6z{Entomk_;b1}h|F(kq8!o?qiHUt@>P*D zw*l9L$4=JwM3t9*{>m(nJllgwuVreAY)P_OV=O%ih#g%LJacGe!M#(IQ$iftCo*bp zB^oTPrgL~|BT$_;51 z)Gmi4Y!>=eGG$%1(nTS=Ce{2!e~|8r$4&qQn?pG_@T&IYU&GhgHU9u=F1BOHevK+D zU-(?JlBUQlH)<5wr0~}vJ-LVC$D97bqC7YgxuhSMr08O!HcZX*O~Vez&5A!YtS@-= zIP_kjg4e>q1mU609Y9`j;dpU!HFn38*EzdMZ5{#nt(HDUtBJsknGueTXZj~;1CDO3 znuw!;#)wXzPsNj~ZBt@vlU~ViA8Ntck$hG$Ncy^wS`D>#L>#>z2w&Zg%+jWYC~@@{ z2p-lxxN8sjsd|=Sd_}-*{{X0zFAw2j&lJ;>zb5E8$DmofjX{saDDp`bc-n;QAR0ea zXBK;&EzD}KW|;5ZE&B4N!KX^r*5;qhaShYsL0_8I{{X@TM4Knh1U4pxCD;>xbpB{( z3Py`@Ye&^e0XUTzT2@|keohksd$@avpaSeq=>l%pDVr!ww4V!SS zr>E2_O*6!@&l6id(rc*hy$^#b#(9tRDMe-3AN_@9+HRvIpLPmSC-4qSNiphS$Jxy* zRTiTZgV`y}g{R_M`LmsP%yd2u)$ru=gQJ*LQx8AIB|FBkUsgcWCw|^!BGg|C=}gu2uqAlgAFpX29d=N&G8$|L z4t=bv9|^&iCa4Z1hBq)0=T(3Y{=&(TC8Tux7b!;MdY&{w1^~gegMdAPl-U|jRSyXBHntulz{SU7UFMlG97iPd3Yh5AP04#l@mbR~^o-=rH$g?%^5Rytz8c(p zbAj}2{{WgJd^HH`JCFS#IWcc$RtL)0?Vv-t*jEhGb7i{?U>(U;?a*+c1e|kyt%R&3vjt{tL~r55m#bl+?6CYH)Lb9HV-a%?!$L-ta0^s#^Bj>_g}~< zxZVrNYno@3v9qZ+WnRJId`2^wBz64Nf0>3p%)jAfo4P2!t$g9MVQu-pg##vN8aKOV z_*&Z~YI1xl1KLb8I6K+gf}$S@JhZgR#-H&20Oc3?*lO%s{{Tqv&GzyB-OJU+|PXYKY z#V+$DCfQw&y2nWNMGu($?H63NWXpz~BUT?FRWg1qqb5E;o$V5IX}&3HF+4+v@C4Yd z4*82&EM2}~4i*5qTFfmsA0j5Xv5*`ugTjA{H5EpGCLEoj(j89%M%ZP4(vodg8ZY=x zchDz8q(;Vrxx?z7{VFFmi=Fu`t;PE?ab-4kxirx^vBKDa?(_ajID9I-uMHTu?5xT0@f>)C3 zCe%5bX4gBMj)%h!NUUy|1GoVZx+F)SQzC6T)X4c&@<|ingY2wkiq@NLeu~Q)H$=^) z9j#8JE^YQ-#~Acw^XO!j9=1xXdjM;Q>JJLfRACt}aO8&-TpITR2`p$BEoP>J`|<*%EvqCQqc1e#mm;%?3rsE1E}pSFmCk zw_S>^iOtZalOxw7Hhop8pmIS~qOTG2NswPNi=A8&RPBWH36bMEESVczG?1lvZU8&6 z=!U?eIb*$&fk^&cl21g1pD?0jHKN-eQ;#r*Hc=eyXaoaSO2$0t<7U^}$IJu#mQpxO zQ~9hkRlYW&=ua`Q{X*Rg%|!D)M~5$w$sMS@%wduj$iwW=Xe@4ip*-?=Suz<1;U}`) zWNTx}KXo7Iv3lN1awK-vF~2~Mr~Rd{6wDOj3~$zGxPQu84+IR%4-Y%%!ls}rZk5Y;Zb09vV5OJXSS}*eRAH!OEa-+93jrf*j z`i}dN&+4K#RU%s4e=?0lu`Z%q>)s%O9CtN`*Y#d$sAj%--0SLjTCW;I{fi4OF{)M&a>sJR?i5cgDqW9)v`PCp zb^~%pG~&l`-Al~dk%5Y3V_ZWEc^zn`V86x-Pq9)4+KbjWkJ}cRt z%<#UQm1T@DIQM7zDm>2z=EH8sb7pU0(5<~CAd2=q6Jefl6+a#lJgR(Iv7T8hZfPFj z33|`jBh7eC%ItW4BM|2Q05!7~S1!(WYzrSu^6faZNbTOj zm5tj$T5l3~mq*jFU!>@oY)s;vJK1Gm~u{X~5GEu3+H zI9Pm)wWM^sY*x82uO@lSj^h6S24QOImh z#(Rrn2HFT!@-^r<;Z13l+04PzB5SdyW}hns^JEa8GEztZfcjOqz&ZL@WTmjVkG5Cw2kL=M`yDJ)uE`C;(H)dq9#p~Y+D7IA4|?OW zd>HKW=JVf<*n_uy(|thppjBQzn)&m#0QO|o#tzP|r2A4HRJj=WrX0xjS4Zx%e_K*g zcXUX_ewwTtT{-S_V9Sp)8VkK(?)i|R$$^Uowde0^!(Y4-N9jtAT$!NVkjZvR2L`(Q zlnggzO!q!U)0}VO>WO5v*2;LIp4sS7J~^`@n`C=j-OiAX4^9?4#C}Bj=0n^=`2Z3= zO3NEJB0NarEn_zD4fP*I5zzhX+}8Swtd|7ED>7t_OH8b0l^m@O*|2vfgzS6>pqa9? zl3UpHQzv#lBTKSn7wk_zqJrNMK;l42Ho!}J!RPpHxK!171G2=8<) zZP7ndYAm@>4k-F9Fg)rOhK*cO`P)eydJ6x)G9XIxe#{JbWBh#Nl;B5ZWMqie3+iam-AN zKWVDBo3({&XV!8g$jyAO4j_WlKzyl2*0lqT0fGmHimJOO-{cmoQI+V+l5uNipyc?c z4nSEHhDQN@o}a3R{coV><2xHBS+~2d4(t3^nd$x`W-P9BfIY73@(SPj#}6n6MD_;B z&5j5wPscB250)#VX@MVvaa+u+$Z#aww?O?AxF_(uc@KPlW)G0r;d#zHIa6nbu(hM{ zJ?{Vys+vxo*?h1cmnrz34%U83bXU!1qDu~mE+Z9y)^fDRwk)XFNIsLe z5PpPoRjiU0d2D8#86?+IcvnM3W=Lye!hw(d($Y#ymAwZXjFT>*fvd#kP8#PCL_e?O z05w;ej`+^z z#UwHo(}T&Q`KX`Z)s`g-@tW~KSyl7kxY%h|B;~|S!?Y1r-sz2j(l*Ix{L>SXDbF00 z8JV>C!6XY&pN}+SacK)_7MJ#iZH{K{`X=RQ=N*CWk~a#z3VO=Y74bpz%zSw=$J)ou z8|}Zm!ap^3{7BF4kcMy~Jy-&-m3s@|lIfL@x=gu5aIm?>8QA$a`5sKob00v}UsW-f zEMvo%O9<#&!ahSEI|E+eTx#A0II4LQ4Pj|nxA2+Kzp8QT8G|5?Ti)H%q#PTw~k)xrG2|*Lt6Uo{GQze0>*)$=;=(;JVVD&^?ds1ZiQrGOB z5;@5$u#{7D%B=qY3}EJhSR{qt-Fc-44@8elfW?bD&PjITCD$FeR&!)aARq(J%|+AQ zJMv`NAiJtP(&d(JJ&%qk#o8?J<(Z8Qox#W5ShekN>YxV7daz%(Qa8FdfpY-*Bt^Rd zakg~u9ihT!3RTAt%)lkeljhW!dW+cFEF<$(__^=N)v@4x>@Mf#wc&%x_%6idZxkHc z=$Af)4ptPnm;y62zm7w7`KRgr63@n9-zy3B4?pI$7~f}#Fc}LO{t-%0EF!^PqsQ@< zC|9${`8hwxm9nBeBPKS{e(%u(FAF9%5@U0#_eHDg9_b8>XuIg2z|FxWMi(j0U@de~ z0y^$#3b5(fnw;b8@RHCdxS9cMwdtak7~1GsN1ENvaOf0>qibUxTR>^)T?j~UYFig5 zFGfH8fytZKK4ejRnhTZphx{@9NaxCOJl8w`-$iYuX6C$p6hXPI1d6d}B?Qg5vPu!q zV@IkRqJ_M*&T07*NjFF3wv8zHN6p7{LQgHv_+8%CY`A{5jktW4=94;OGh1=xo;ul7 znwEBJBX-H$Z?9B;>K$fWrh%7iJxhYT$Iy#5J0~I1kZiVv6^|Yqvi|_#(Uw?8+2*c( zPD{5rua-mmy-KyybnSC0LH&XC-S0aMf130-^z0a9GDV9VZav!7BY-FhTcP9EW@&jh z(lZ#EQ$&I?H_7hd%9ddf64Jm3>_WQ@YaO|u1MY3_XgW0?#ji4kXWljTxNUot2Wc&34xc{{S?`JT!*5_2{gmiY)dAG3BHi4hoA=$z~khMCGx| zTbs`gA0@}~e0joO_;hgOQ&dQDr7(mtyy8!L+)<+wy-t{P~j zUG_(IKsf$Y8~0JbMK7yV3g2XXM@@rLV?>~hp9ltkD?h4YJ5I%tSTzU0<_p^MV68^> zmllJ|daT!pbPTO)EsldJkwRPQ+&Nv(4m=%sAnE|q!LX#o^I&$TJ0~v($2vyQSw3j6=hw+;Vm*c+}R&q?p*AiTC-GeB<-0z zID?)^{nRIG5^1?jZWNPwUyIeiKPA48!}@a@LLcIy%i%pHLQj}0ObmE$% zRB8S$%X@=Fu5mp#1)_r|P|Jk5&t!k%BGnFOgd)d<^W)?Zv|iWnqDI-^Wd}Le@>^l# zIjcY{NYlxOG?(^`OJh&5QD3OzXwXR>JG|FBtBJE~KP%^OR|ytzf}^P{7*NEtLTRePzJz8}Feih^eGTeprDn^f@hx|Ct3C6Up)V<`Us zGz~Mtuha6p{{Xg`Xja#RiFk9q%`44KTSPd#C#N-}{iW^PZ;%kiho(U#yC(ilB9-<| zhBA%GKHu<;6j*#Ai5ttGJdzS`o)bUCl?Z-QZ?iL-q{WcwUxN#t_S3fx_t{fRhm#4Z zV0$avFGFq&IC&;GE{9uFL=2IX_JR*$5PVMPC7o5X%L_>D!b2U70`z>(4(a)=Hy4)w z0N!T>P(Q(Xka_Zp9Lw~Q>Le@pWE#%~XQGXzqQWu54sQzaz7N#cMTq|Z?o#6LwrfYI z$NvCwC5~&*xyu{&V)C&hs%W)Gm#0eWC9Bl`0NHGp9$y#gkoYamuxDVuV3`lyhISfrZCz$5V>2&5m&{z{gPR z0-b}XX>Xi4vNTX6f+cufu(AoY26?UmCpw8}O@xHxj*S+Bq+x5i8N<|B=4^9=IjyJP`L8eW9*+GN zS)U2O(;ew2xL(H=G&u1?CM3HX47;2^cy#{&HJAR7bR3;q#5m2sgvj^B_(wtRR)|i_ zlY?7hf1@2XGRd_GKyhcGfR2_qDsPA&Y#CFzq?VF4-_2ckTSSvb(ncHT&JDi3(6vtw zYFW=NF^apgdZ{aGLow23HO+9V3PuF3W?KmQE2(@hsd+#geg6P3;lds_hqI%8=i@j5 z?v$f1!$&ColXVE&lczQA_?T!PlA|%w(&gj29XD&6w3h`{kEZ41$^XEt41(&tJ`xI?g71-K@v7g?t^z5R}(T^*mYlEH-td5uLu5#GzVVJT& z!euPj_a26nNi|->a!K-i6h=26g{1uzrkml+jKCj0=%efp#rZ3UaCH3{f?TN@=|{h1 z7c<3d4RbKzb=3#EkKmgaLK~2Y=9HfpB6QPfx)e=pY-^-HgmU7udHSYCY_8tztn9{~ z0*FRdY~}kOBc0r-&}cbRa^e_0`k<8ME|!8&jy=iSFy1E8Joo*o7CF)$90%eGuOGsh zPsSNJ&lq^;@jrrpCF{)6@$mf+v`ssDJ;Q*0N-kG|@iV0RRbqRCyVENJ|CB1t?p}2(Rr_RWvc4=y1U7h)g9YoZ^G4Iu#TZjP;px;H2F(J ztab|esmvTG5J)&4%5ZlAlg#7D0XKfsx58wAk-~tSa%j?4AQ|xi7S&rcZezBPuBndr zUqwvQv00It!7v*KE^-;lknC}Cl^vpCjC@c?^}CW))J?h`$S`BOs~F(d8ys*H$m22f zTzs-}m7V-iQH=xvbtMCYhSFH%g`u{Gbr0;5vQ5!QdHJb{z@fH_;+YB0%Z$-Glc3DV zh1W;vxT#L+gDq|7iAjRt5&rRKO)5jPbq|+sBMvk+UDK#MwN?k zMXPmO868f6fcv!3Qy|U4a3bYnNB6B~+#!5`F@?NWDnuBjUCjl8#d?LSqMU#9(lTr_ zF?4dvdrh6@={8vL-ynHldG|6|D>CeN;>{#XmEaCKq%X-}v5;Nza8M2(`f8!m@!uPq zVQqn7y-EF2HG)1{j>sGHAQha4H&EI{WO3GzXUoi-2EI!9qO=3YFVjILOhQoB-bA!W zjv=`4sP!#xJRtGkFiP6SMQC&&qW3yuIBlsdQSz z%IL6X&3Q5zCU6!=1k#feMm(b1@ScjtMAcuVTc5G)m%GYhc76={6xrlSs6n%mR%fp3sxEW-Xu(OF{F&i&>OOUf}(a*vy#Wd@pUJv--Z&BreN}O zD3Ub{$ncACA=u$wu2x4-z{r)a$nxCCZkk#TWW?u& zJJ1~7E9kc>#*S^gtn;VfO&O;H%Wr{dMm&anu?7b0=G(>nR?AnwhIt74E2Hndqkyxs zcz%66$CSyUb6W5VL&eePX*xL+mdw+{(>fs1+Kwq62YywSnAtKVY;i(d;%EjARQcZy zpS6Z)o+M@c+kvmDw9s|j4JRPWE*|$iw%J2@N^-UmjT%h@LeGXVHdu-`2GcFJ;r{@Y za}Jx29Hv)Xk8$L?pUFUGyv&A)LrX)2fKMqV*BKi@-Wz7QJxVydN!Wj8sTXa=fHVOM zK=}k2aIxgOg`E2eQ1P{PI1T(-l#b2d)n_e(_ZTVmlWCtbgqHsOi4KRrGq{w-NZF( zvM!?@EV4DPiNY`|(EX)X%yisBz{ki5?nuAQNyvMpaCsC7prLgJU=D{QG>(MvYO^a)A*MF%k;kLL7F$FxmPX+raIK^8q2j{>f%Er+ zUxad1%Sh?si;@5ZB@R6gD85@qWPz0HN;a(^WY=W;a$l1hOD^5g`l32b@dj*Y+DW?P zr(#LuWydbt+EuQ|&2)H})5IEEKyWXI50}kIgG!a2sPY}R>Z0LiLnK4Xdq_Wnjz3j* zjUWvJVK?lz!L+DUlvo)Vn#j1xC+o_~>eFg1yUK6m0@vhZLL;KtIra-PsLhQ$t%a;{ zd(O~HXel|gi5Nxn$vzl~(&^2S^6unaqE=KT4J;7~0y-#+0m25Ioal zaUqkqURb1>F%RV;%X*1!vOYgD^KBl zP5F2(Y@pj-MV{*?k>TQ6=-cA|0H|h?ro+djPZ0IX7#{YB>?V;$X#W6JDttE1;_ord zC-Vp{(wtjOlK%kdSRaa$(l;+5y|z;t(f2A8BW4rfc6*Ts}R7CiKC zVze*OvOf-4jQg}IZx^(;7ahV<`C~P>iY{6_Xe@KO5#?o+@zvRH8+W$v)PIWY(?;L} zUC*+>Vt9`)9ouBzXWx*t7+xgvS{h{puB4+ow9Z5)jcKDm*=2jShP(7#E2fFNhzIJa zX7Ll^=;oUDQ04Iy`2>mw+R@|Yp1{iSzKEVE)b$o*!w`ryr`74_f#2x6MDZR>aR4N? z_l?|-$pc>VX49KHo(qqso;dbd{WcugBy4a-=^jr&ET!a^*v#>{eqzj_u+HhT$a|XOOuKK@Ey=!y!xY-tTbts6 z3u%l1`|^w7S7+)PvvYDW-f?!Fk9R5@7+TZ~F<$#kPJIdT+cG~Q{Ys7~fX%d;hG(8~m%JX;UOyK_jC61sftD;1n#zfor zcOcKAVz`?kFcqjOgTfMr=|QhPrkWvNTYGYY=Y$r`oET{G9>(nlfzefXlSIPt34zkR z?UE~}FwrBpQ|t<+kIf0uusZ9hrI$C7q^SiMB%(?T=`o)Rdae4EZo`#mJ@` zunz<1sScA9Sy@?If$Pd_dRoYI-&fA&3V! z#yIDqsnPsf3*E9uQ*OORmunXcapPwfB&C{s(l^ltF@QBW)zpqX)qWQnwl7g5kQ*aM9o;cwNLKz4xl$5=A~Pqm4E@ ziEM_8Z`ms%*0LK;A(!r-DXDEC*y8JKwbW(6j~UOOVKrWnM%H>O;mzZo5uf3_nVq_P zwv+R6nB5*mfCRChp;@vnPe!OpF;v+%P1o4tpnIt_5VJ(j>jXyPAEF z;*xwf4U$N}I}!e<^s&NvyQIyyBKnY@F-xzs2Y+WvVFD>-EttrW?MtM?n#>Wg%@*B^& zO6N7b(}WfV;(sLHECMjOM;OTh+I zGu;9_mOmqF9A&?5LOWvs8)yWD2UFFw?+@Xb@}*>T_(#O!^hECMm8zn9oXFVe9^l5b zStRreBdhq|7)JOs*R}8HW$X{hV?0IT-9yCFc`)yT5FQu}U(BBW0Ftl9#``!*%ax^3 z9ft+GXqBIvmpr?tn7p`M-IV~isSkj*5sN-Od2;J<(!o88{C04#(X)%Oj{n zV;k0$HWw1tPi!(yBV=vd@IV#SSmx=GK@4qwlnaIRRM_kVz}aaX2<)^mG7QMr*(PJ; z0=IN>UlKh7k{vQkW{0qPM--~!!j1AaIJqt~txhf+QV8UdUCuNImU&t|E5q=|wrOK? zOeNO~j812DUc4%mbIZtCXfStZvq{0G_wv z@zh1 z3JGKK+|n9)hLRB!e4K$34ZSLIj8(C)py>n9i(}GP{(oulV@JAs+UcL=Lfx$HP-4r*mcf|FdxPBv zP}GJzcO;F9F4fehsY0m3f_(#<|Vdmo&>don+!vnsgGPQPRFOKJx47<`ic6zDSiaGf!HKd(WGN4hIGbgl{Zwr_Y5}CH z7qPOkirHpjvF*cgv1~rzrED@-@@8X)%+eNC6p^@=iwY&ZoN^Q)U}u&iQo`Z$9E77f z0r3K%Gcsl$ipQ}<8IZW#ur!~Nh0!bR*#7{!QjFLyfTDqgD}E<2Ik=e4APj-|s0|W^ zL=O~caE=)T0uTn8>-5aR6Wgaq4f&(;D2kw;WN)}!G0Qp>Na7KSGK2Liq|Aal^@Co@ zi9j6pFpdq~EmoTl#>8VJisXH`xba^vqR;5HkUb_M1(yPHzHS5!rDR@q2B4hfz>o8R|rBw9`1NR zoyW^Gj^LwCX^P|65+O?RUDZg39mXRu>=YSY>QkGMvrTZm$@D3aoi#~nWLbxY5C_py z7jtS$UH4&K6=a9xx%n@3{6_wXUn_PVR6ut;uG~8nD74EQOs7YV@yDy(Ml%xQ%4Bb- z%TqUc%9KkEA8xdS@>2ojI0Zo_J)aUL`sAK{(ApE6JtYGenL86vnY?+OJ=KFXY=GMI zJMvU`@jcF_f=TQGxx>-(@+1t88TWjWC6GCO58%LZ^;p31)V=iomzgtkU^R>+= z2&9~lJ=!>4qYsC4&p&iJfqTzJ(6lX6!npacZIVW~{_zx6oO6^r=);;Y$hFzzIU4?c zLxFVEecRO|HN8k5_sM@%YvK%`PKQgw$lh6tm2B_5ONH28Q!$Qgt@6PQWU&KQqBBm)fuMg{64E_ecukKJ9hoLc zcTPRah$SlMBK9ruT(_O-q zj#^n>SrzPfU9S_2AhvlwKa}$_UL!G#H1{>t{pwNk@!)4iLTp`cvZui4JiokUID550 z%$^n!SjL0zOHVasHwL0W$7BtYlYil9C2Kq?_qQfi29~gm-l0nzbtxGsK9>IggssRk+sg? z0(n}OEdKzB=Y^VVmmuhRa;jaTU)82zqKU#n(pvHJ;ag!CxZR8o&@B5*j(Bu(Zv|ap zJ3O>8k?ubxu9}=wZJZ~LQl5)B8H!p@lm7ttsD@ZteKA+iBf2d~&7+QgMH*N$Z)>q+ zA3dmkczR=A44;LL20jj`MlNOScOVm1R+j@vz|-Bk6B)5Os>fA_YoCsM$s}xHqUalQ zk8Tz2jpDp~sLXN`=SFL9cPyDCljQn0c<|)7uFY2OQ3zgqdy87@aO|qx;v8npPKt03 z;_}S}V~p52njgp4=9Z_+q3I;)j%4>H*8)DM#1qjnNX&qi)%Gi~9`hTUD{0L&^+c^c zBxw*c^+_-q=gEgOk&nc|VG9FW8FLm%1K|a?8=NRV=&l{IR+cyi1HlCjNFsbfGREx& z>XdPn+GVLms)R2Az)`c@1p4K0OVt_yoaa++iTWhk*%@vedla?@bSdTX<0LC>C9*5@ z67~vh0J??R98NRA$rtVr!E;@(o=5UjnHn=6(gr?UxOmUSW8UV=bl#QoSsl_dFi9gu z@;yx>qV<{U%H^TN^aLy)h$EZ&+Bsj0*jh%=T6(2q(+)iqm>H63x~x)qgfBdTI4f`c zZHCqdmlI;>3t2G>cUf^f5z3XPYLlGyX)$B9&nJWO_bDsJj!9b?KO#_#C1#5cQI|SW z*f8W|ZR;$ak@+YZk(VP>kIBo~j~O0j-h`>T?reBCu<6a5M)^mmwcV9?bWFrPNe-^S ztvGxvcV;~PW<;te(a(=IRv>mH+a5X^;QdfBvy4N?$+pNklBzVH5ygiyak5E@Bk-4U z0?=gQVrsbCyPt*aJw9o&gktC@N>f&IACD|121`w%Jtv-35%5c-$TDSWbH5wA8^J2u z69eqnq!G4OU7nz#N1wgMGWJ;OPUw*=oLw=l3SNx#o)yw^WNa{LlRs#p_nyC7M32F` zd~yaIF_qocwId<1wV}WZHDMLJsGz0nzD_Er&O5<+K>eF#kKb&DimQVME5p7bhaOy$ zHXcJx!zWgsWv12j2jI1Vm-n5=MOB5kE6Qq#P0@XbJB!)KIMW0}^ zIzWM9o+Br$mM_D{<3JTmK10?URldvR+-%!o4L204HwV4=ng09C26J<%JD z&SCi!_+&{_9q?K;lj(yZiO4rq!Ak~~+;Pm#cjl;K&B|+d$bagb{Jf{OjziJ&fDa7I z@hljD&UB)_Wl`m4vo=>4+qJFWA9V@Px?^(4=bxH;V{9?{MIfF_(isd~cFLTIT-=8r znn9F$p=G?8UJtqxUH5j9Hi?HR4NaZt7y$?f~H7FSh>iHS<&-)4$QXsJIEdkC;8 zFtqL|?CJuti4AD(6WYdI6xfF}rLqu(vd6Wo4I4i+Xk&b`wm5+=ao_~l;T@EiW|Ib1 z&kSNm4xv(HeH$$^791E@>D(lj_na=3h|b49@c{aQvrX|%_75`&;QIk-kMU*`YkV?` z{_58cBZAR_emj%4YDQi;{{V^;+cZw;BTweC%<)c+O*!SCR+TC}V@aB}WU~HcIeCmj z@l6nWdlZBMso6F&#j$ay2`iFs%r@tI|{r?C8&0ZI!bk%!_=ms5fW$&ur5 z>OyKgVrpSwa?3qJ-m=7pfc{9t)EC+WAv+U)L-dbMn<;K@HHhyx^ zzZL}*vdP-iahS>2c)p&d?lvf=9_A$`M5ywG64G zqW6*ANP;|xd1wRJz1E*7k*1voKSYs8`l=`#hDIo|he(%ran!_aJwsZoAoB8|4#5s5n|Rfh%>8~|H-lCs&^@aMVFHsm$xly&+loQ#=uIZe6E zhWj6hNsgK+qJpH_V|Xe&_Z~vY0=R-hx7|@O-k_~9Wa5hK99B=>2%^;2f<*!NafCXB%ZbqOr3Ji1JB z{B+Ci)fnkGP59)0(Lj`uL>@<3XS1u9ao*}|?r|3$Av{Dzi^>HhJ zC!iR3Q1@*Ree!yzf=Z_Hi`)MSxty>uE~b3ic?AD6dhx71Saj_xZ(drLqE(hkM z&ysLnB918HX!v%vmZ;)QTQa=Ql_LokgEhxC{>TT&y}#;>{=(}|b^V?u(Ek9K7Rj2a zd#iaLGCC%^P?ATVE>}LftN5Z$SsOBAz?#?YMgIW(0&ws)usXIO{{Z&_(~Rtg@X-7D zf}ApD{CkJGpBw^TA)9A{H6!s!3qG$>Bk(psH7;Zg`HpE{dFDbIBnR_R@+N#uBpa{L zs`%g%c^j)N@HE{!OM#KY9DAB5zqwKjz{z4;Z|?0`_RTD@(aDLV^cI}lmc-qU)EZyd z077DEEdcO4+b#04v0l>z&2bLuDMgP$!Ja+v$nCEA+N*qx5;U0$?McVZ`!oGJx$G29 zGIYUsoK~22Xi;NjiCHlPzWgWWV#|*Snnzn$2|G_frwJm?fKz~RMTlHa#*|nhh&{q5 zvq}bLMilu@CnQ<@&}nD- zE>U5Mc7b~>XLJzASsbP9_q7_KbBmm4C}h&@$%z9+t_g$B1;47g19dFcBOK>jO1Z_I zz=+;|HJ>6jVJzd0)TZLw3){#Y&~eCduF7;<1N}|hJ*{JtI#56x0+Pr^!OG_RYGB&t zk4O}j$E1jY5L1L(RN37OkwnHoBXnYmntng30ScHzC$Kfe7B)xahi~A zdVV~TiqVTM7|HChZfv^+v7tfC$#bvJ)NnXavIQDU`KBlQY=4Dwn`-+)$dRz@WwUQ! zRak2*?pE4R4Yi*%+eWMy;~gUA9KAw01B8zw*pyt2OI6wEbBFyQEH4F=rbk->&az1j zlvm-N%g)wZ2pJMK{eV=in=>8G^PKrN8}%DoETF-BEY_~k*V#87W~3)B2+kBo(qWG) zREe)^TFbWrYQpqrwrn0)XdQs;7nQdnOj#Q=XO{EzTFpOJnkF&X5x55qqoQA%pCp=K zc-|x;n)Y0sM=^|Xb~q0Kq%m90X`s?;kE*PHi>GAXRQhYc?yYh4OnIwz*8}d2cusL8 zjVm-fgq1O}!qDs}aJ9I+-yx;0t2ISPkHZ=!5%Zgf*1U7(Imd+j9ISZd5w?czfGK*0 zC)@FiTZ?Gl9sWzJfyPn&Fy)Jkhc*~r4Kbr{Vh0F+W_x2XvR$L-j}Q%vGzy_qhnJTg z7CWbw_K#s@XyF#DPqEO4#U9t4)!Zk7tKin4$cRWIk)ZY?lzd%B4=~g-w7a_x4*eCW zDxx&QwagdKJ@x7e3xg@KX_?NL!Dvl75VSo1$muL>~D3k4^pJ(qduZ=>hL!TIt*d;_jtY>fSojaY&8_ zzDWtMNLf8Y#FFY7lV^qR3lL zeU9J$htwve0VH{BtB1wd${ z%W3mnK>!cCAxy|Vv%-(H!=OY11On7(bTXNJ5A8AE?jnesofO);Yd&A9 zu2$O1Z$3|{RlZri6%0>Ed<>@oLY5F(Htk34N)#n4Jqt@3u4#$VY-2^Z(yY2#F9!br zzfb-F{L`?c=93ZRPmC=Z41W)4*y6mSA@^~#XK7fkX#ty0Vid<;6l#sGE(~dNjR3np z3_lJZ&y)0`&(eO)5tXuTZ*g4~LsiAS&%er-p=yTkUa?w(JjM}Am*l}hRF1EWH#ple zPi;7)Xr*B;KdYh>vCp#3Xa^TArD=~DZ~$_k#|RG!*A2HyiDZ^y@zFo*<-G!%1a{D! zEI^|Yh&5lO6IhoUg^L?n;&fd!<7kCb$s)4H`)GjWZ*L zW-`w}LXgu7{{Uw^XY&gra9}@xBp5LcTe+v)6-`96sM)eVVAJ$dnD)buZ#BZf#@v{N zN0TLeQ>2?e%dfP$uGOVX2}b)abzN2EuGws8{71jZX0oy!lxfx(`?uHXn=F#bZb=J| z%`^)}uFC0B6`XYFjNU>U8jjWiJKDP~CV7}su^wn&x`GWOLm*-2qU@YTTn8xg=Z3pv zG~@f-lsR&pBX%^?QyLY57|QoJ8600;=#gj13$3PhlP^oLL-zA@!zpTmKMD9 zqPeq;XzOFhs?7v)HfDz~@QJp_S^O-=;z_aQ*tAhe9Lx`m*0RbpZiJH%u{4j8Df%Xq zra1##Q3F9vG1tY%)k4Uw1fWdPSf)MA27pnf?u`P`148(>fmEU68Q zHK5Yq%TkOW#4M@E2No`!sm-M3GbR_&9b4JM+Lxl^EtOniSrSzT2XnJv`JdqzgUKX(z88)>cl?Gczybq8*6J(cWb?-#N*B9=`$6!W_?&e9zq<~sTX%+aNFTwj{KbQuT!F#MZHZ^g(h{j-neuj563kjlvP ziKBRRH-u5AKKa-bkFwH}pa0ZBAu1QUcrD8Hile;HRD`JGX&kShlwG z3PEQn;yx02G2BrM;>7N)39i$lEZiDDMKf(BrD|-a1Xlk5Rz~B?KtY>Hj6c#9%UNY} zqQ1z!Ng;n6N&}<^bO>(I-R(<4$i?!TD}6|oX%z6p&AUl(N&Qy;0A+sWu4{fsmT496 z#H_;8fP^a=Nc>!c$2cCz z&ZEL@4*tr~2=Wot0E_I8C3K`BjR3)x{E=d|n*lPd9xr6X#W>j^uJl@uHzw4E^rRVj zqT~+-MRlI4&jG=pTCZ{WDHzWop(`WM%yFh)!62nQlQ+u>hA9e_=hHwXX0grzaAIVtkI8#O+3ZwpFHDMw)B){~`zJmV%KMO0fABBuJN0BRB(_rrItTf*p;BRIwRJ8sE{>4^i_-85N z*)Vtbf}op0$&Vq9nhR@9+j&jJ<7L6N22A*}t|^|Zb0e2zkvKiP@(L``GbRHYg|*Ai zSloypK1|P!{fc%cjI*@T8<+&m9Zy0Qh-KX~Jg~LVf0?7|P*KNudqJ>AP=X9o*p?41 z?fgJdzja}z__s;as7E-B=kUqFR;TQ9)5v4*y>(3bzL>g_A?bOpko}%VxR6$t3UsMtzzgObuZ91y!wPMVW~%pN~?$R?~nNK{J|5vbZ@i&KKh5#wCVE zy{Dla(zhLf+o@$Vd`(MC#+D3uN0!?muI!(tWb0V@68VlZhnuHyx9GDxk$=)1@U_!4 zvEwn0B>KI+Ntrs99t-@uiCYmpHyX8(c29_1slIrg0CkTjiweIdLCx1S4?9uFpalTV zfFfDaUsOkiP1|O#7hT2AmPf(4{#*9+;HOKMF>`}j7}L^}d~6(TJ_bXL8)IPWUC+8S zgftD^&`T_&f>`2#Ofp?fl3HtxdQT~tIyMxsdV`$qjSnV5{tTV$t!$-7kamRCuy^Zw|F9Hgh~1Pel}|*fPeY*{6e3#>r?gyjkp2fc8J5 zm!3r2fzSZL8u(CI$RDlCic^YRV&8 zqEuC}z)?gAfG34PP~_l{S9Gcbg#|69f|XEXflmaGZ44)Y!BC;oj#4Q2TYpOAxQYgL0>Q`B2RB|2yX0J0FhFTm6cLJ7PVBNl>R;21VRL!pb zYNh#s&a&J5*E7hUDOuC;vGIU8A{TUoSkc)%`2hA&pObe>HJWI4#@|II2Zj&|gx8Zu z%qO8lnN1g%*$n|YY4;DJtAXwv(aVV)Qx`&-*yqc~Dh$tags&b>Ap^ zK|H58o8>mr+YX6vyK{-4K8dm#kfuQHQ)VY}t1g0vkZd9|AcCQX*HoLyD(r>3W)2*b z*RVN4$CU4)rIM+#Q5s10xTXfF5^~fq5ZQc2?MXl)bVT25lGHv+AEr` zk$h1T?B67xXZb0lp}VD?h?8YFq(<_CRBX()W3sFh>=NhaM-wTB)TqdG@^5iXjBN>& zk(5djB@3`{#{!5Ph54nmc2h&#cuWhoE>=)%cWjgua@u@U3ZVvyl@@EGpi~8-Yq2*v z={h_Syd;NGkB!yJKlOw@>J>p*iow|#tz=`OhIJUnM$B&Rg>Q!0>@-Xazvh& zaPG(5Qad)!bf0YHCV2THMjVbVnW2(B!;wp|b7jJpsoGRr4MCX=@}6nKp(@4AWSGT- zavf_7qgrQ989k!r45;#$9M_Aa;tj04Q%i?9EhlK|75*Nf7EqvR-o<8~I#z6kTP6lb zKM7qk(|Q5g4Xxp;B9JWPj14<)0aD!xs7SC5wlKE1*`u{F-LH#Br2 z(<3@tGtU}eTjK1de0c0CRDLvwe0Yxhii&aJ-DRT6b8+DP(3#F6J|%=hxL{1~epm0XSj8e+Wa(1hBSmVb(C^1Ix={zMi!(eTF7tkCDG!S>+CZNG5$@M=iIL+rMG+$keg4~1f5<|gk1xXWQ`I5UaAe7q z>;a7?$>n(FyW$-G021bx7ntK50N#pUh_yW3dnvATW(dIHo3Hgy@v&I|7A*|3XgK)q z*xW21C7%`hsRguDsG2tP>X_#GmRCD9taO0Y8X-70grs_{JRz{Sf^$+1sKubAV;g*_ zWpM`3oC1{C+g%qrHjc`<1H_521PLnmQy$t;-obVeCQc-0Q9SUGyrY=GHd8#R=!r6M z6^`0dp5U4ql(j;*vzy91L(~x1#CV(8P-zmFD2_o!JfN|u;Gr6a-7dRa*-K-4HnyGA z*C=G#6302*q%LO9SHyfeVfD!!47PGWI#F^Hkc@COT z0R!q$WN~s2S0jdnOgfRUe1XzB=-M2fTsY8p{4AW)Wxh<#mBG=D zDOW!NN#v^PrbhZ`3PfPJzy_1_T!h@7j^2`{SGPcGjXdomp#!3w7L`6Nd3kez>>RAb zauznDar~66uG-&0DV#EX2zfE4Mi|-7XeS}(>Q#mY1XyyuQzM@D3bK*zc%UP2;W^U! znk%X$7P|&gO=y=Bg9FF!3QmBAIJ>wUC}vO}N4j{J14>#3gF_n{Uh4Nz10GymNUoeV zCl%02*EA|^Fp^|>WPOH!Y;{7GcNdNi3QMF8${{j0H|;!x0V20K&zhRvs=fGmY;NNV z>*N)-p_K-k!Y z0K0&@${oa1Wv=uDDxwt-w;9nmzh)F2}3N(Ts{ACh;MO+v^;a6=_ZEd?~j z+UTf+LubD}$wNM69LLWAca}mc27!jscGT*ms#$3REj@yBVSr~sudRYbBDK)DKRY#`bspR_5_ z^j3w)K+9KJQ$uoN`YNlXWrrwZm`}1|5k82z(Ei^gd#cjgD#uZKUy$c@B|;%W*FytR zKAJ42lSnd~;ZZ}QEIA>p=4%b(386$@%}EW47PTC+{tHbyk55oR6!Zjdxl03kJDFj$SbfKrJ3+Lmijgp4Hsu?tq(*jcq z!S0q?B|vDToYT`HcL}n(-NK-bCepW}Yk5TMqbMXCKGe$!yf}x7M-n*+VI^?_!Vq~$ zB&MlH^9VdEqFFC`?bbk1e8(={QI7* zl)K7pE~RA9?Zow59FmfNsDUGu(L6b)m7~*j7UVE7=AN@CuuAAQ0#`|#Uj0hy?F>O<7K9027)klT$SKuH2UQi@F}LLp;`vYy@oU|b0b$|SYi1_DgiQl|%+_*)itADR4n?RzOY!^i8Bfno%HF#{6F-P?!_iPjp34=A>{= z2?$ciF%g$kQxRGJ0Ky3{qP7*C5dq;03Qw*QnA#D^jc(&s0&}?(n%2>^aRNw{j>5+a zQ^nURz7l=Z!2S~~3LH%mP$iJx2#wxGp7d3ap$*gG)uH$&T!H2wV%m zl2Nv z$ZLGypYJPNeQy08XVQx7IYM1CgB6k*k}sUtq_AOd`Y4iyvDDLQ1iHy&ZXlO)b!xI- z5w)b$Mb++A#xVBDDbLa`Oh!joQC*Nc!)Db3yhoQi*%K-@7j{#A(8bB}+!U%OTfw@Pro{9q9 z5u|wzDH!J-=_F|mPK~PQTVVku5t5dX&m*Eh&t=7>St`zv#qT7h9uXSLT;}>nP^u!i z)==DR+9ZOI!R11U5C8@DMlPXhGdNuNUAB}=u>OC|IkL2s19?4Dn))cgvdxbOz=9Q9 zB_QxrmSg}D+Oeuihe|Avn$`eq23&w0)eG%j%BZVE(m_ow3MZUOUBvfRK(3aGW2QZd z6N&DdY68L+?i5oT5?XLBP=K7&-Kg8XK{U8~C|wSPD~BnqG@sQ`Vg$BQ(m<%8QJK=v zt-kAnuZ1XwO5w^5<9sK$j;KV7;aVttr!*3p#@SDjXmO%0arJfz(z2NM$k=1IDqOtD zG9Bf&;qIH0l_o>z9tud90QsjzG$M1|AaO%a^#u8+j~Sb!G!bkyz>=u7iTv3b-lM9~ zjy#!@B>2Y2*_qGDkn>GZOOh1ITjLa#j19SVF>+PP6msRulqluPmn$L3QYBD_B?%IR zWF1SXb*|i@4hd6tF0~3AoB|L$qDSg`M{DH^=(M(IG2BFLt_>-XO@5c2Rb+CvrK1S} zSf?GGC`(0y!eckU?=gmeLW*KIaj>Kp(*tV3NoZ=77Pwil2;OI6{l-7_vT4tUz*z<04raUC3l8{u`Sx|Sw3K2c^Y##p-()j=a_TU2OH(BS8L zqBY055bB8Dii;jyK{4*W$x~c8R6&KuvT1QoAvA?#6cbiTa4D%lP=ea+#`s*g1x18u zMr(=#LNE%8L7O2Q6j3SKqlEU@>ZmY=Uv$GLJ=0&vq!)4ZP^K*8Qi$$|u5s>y;*ATC z!Z}Gvd)nZL0bA^rl8>NH6jUfcDJtSC{d+F83J|U#J9n@NFWf6AZ6u`hqLeIP7L+wS zHpTEMCv{}Ax+eskS5kyS?RBOCooHyg6qMVrxSLF}eoDwYk95Z+36cTSDj?E8Oe7>B zAqa{d6M;e;B?N=XP@+W-D|kHnA=+tovOuh{_KL$`6d)7Yf+l%11cb6O+jZWk7`Ev0S(SmWN`YLWF`LBl#c?a=MZg z6Dgo_z!>TjN4QLDOHs+7nY)y0BSPhkF|H)EizosDPYO>7?FgPp1Mx%f4n98F0e9rA z6nmt;XdOxiCi@K}x(er{W6kwKGJ;a>RbfzI@(DN9H*qBLh8&l2mP#Yf%aBSeytxjQ zSZN&6;oTHSNTP*FMPF4-m(ceVl({{jP$NT6vOIqTwE$pdHuce_INPlejj?Ee z4Aa71se^>;QHF=Ngpv*tZlpORB&sQq<>!PdT@~yQvJ0QrJcacz}KSfT7)RauE3^cBD2~*+@KtX`lq9q;*{0s)&L#@k!w}FpSpP zpvG0M5fW5@#`_|*jrLSRGjZ&6T==$&Q-A<;QD!5uvdE4JjzxLp4MGSwPP$wIP!%!@ zWpY|wN)$AtMUDxkKX$_5@?7Yi!Rs4U(Lh{HQgm4INH;a4kCH-TXtN_#jQ%fz91pYO z;<1kcw*ZbYuq7%hrOSg6p0UX6s$VPfCNBIcJKrW;u95Dvc6vbhCaBS#Q)285O?;v* zhSEzY9XhDQ-%^;6ry=f?xY<I%aX2EK^G-lp#%u=Fwk)vc0yxI+!{KPtfYs_4Q+G@ za&$5gw_w=%Qsa;oi%?t$O4pv{DXSi(MYA3c2+_>uov!36=w=6kRFL}=Qk+LdU!=!@ z*+cV8PH<@>ltxNGqsomh#!&H0K2%MIRGEZZtbEk`ZCR!N0C)$PX^sZcIJ9U|OlfclgxWLl)|p9a(K3REH*FMw3<^#PiV0zIXbY`c1&%4Jt#YtO0+c2L&84&Mp$DfHIjsba zsg|5%C84L9S7a9Wq@<>9OKK46OF?ivQbJW0Eg_x?d!0cJ`Lzj05>s7toL%xwDi#d% zO|je}I3^IRp)GPl!s1jYcuJTYQ>{W+_Sx#56Isf5_^DGZ4hg{0Q4#k@SV91-;_g>8 zrk)bD$`Z*j{3xKP(Z7^%R4p;(4E0Vu5Xn?n;8$HF1vb`b?v}zJXmOL-GVLi`2v=mGTgo5^VZk`PODu9!(DdTrN?Bms-fc3I zoaDs|vxr;=E3GIfNn(JW6KyT3AmV8tT$C#ysg5bd3Ch7^90@&Fd0oPA32j&+2GV;# z6p<|`T4U+GlS@)sLZ~YggqKT_U6nytRyjJt2;nWMM6u+A+vPRgX>jXms4ED$aBxg> zy_BL@`$@Soazf+T6%^R*#V@Rj>=3Qj)jP~PNavMw17dCmsyhfHg%}iQ-YGy+4@-(* za_2o$4Gt#Iq%>CjdQ)A(GX;c?VZH*0wutUcJyYH& zrV@=X2Q(s55OGEa(h8;$Ll0U=1t$;*WB$!P zSu4`i0Q0moa4B~k%C02k`f(~e($@iW^M>#Wg!xH4CPpIVBsxhCK!oAFq#o<8(W8j< zN6@GCD~Q@i_FNRK_#F(P#87y!R8X`<+A~W`8dd1+{*7?X3kTa}8COpsfz1U~Yah|p zZkvZLTv-grWK>9KJFB^*sO5`v6NHhCQ}mq|H(bm6E(Bg=v|U$R1rhN*goiYbs9w$e zAL8O;_;(s?c-kb8ILPwRxbyGqic+E_Z1QbGLDaOM)18SVEqB6PI4ZuE(K(n{nzkdL zo+eKdtWh04p2c|&hx{uBui{*dGIvP}BM%^sydD)PqBt`rOR0KRcl2S69L)PRsswH{ zcej!HD!pI&H`FxTLz4^HmeFO+ipc}9rGFwP250n74Qg8a&W{El@gK(WX`xQmyc4SE zSWL>wjk_G}r^`FG{Z{_~`aaV24J$~S?J<@apZ9Ek2EginRio5!pvuyv#m;y!%G12v z5I&&~$cy;hS@Yc_CXw=E5oA4spm7KUCMRGBxpL%15_I+l=Ee`Yx1KHBs*OG3Jjlzs z6H7xuXUOTAaVtecvC-v6b7-qc<7p>_3Gwo&FrT;JHr`<#>Ej*=bh&(H5!A!Gj ztRYImO@uh5z7&S~f(oIEL^2&~grsm(w>1sWwcjNyCJ%TcszD_>lV2Xfn@Z>#BnP8M zlOqVHIDHC+H~S()`gf@difAR0NVvz=XNALY+!d5s-ZaEEUUgCxFDha- z$OZeQG|=TF`X17Z!kA!tIqE&adq+gJHX)i*tqr96B_#-SImC{L4{@$j-0lz`$X0=1 zp5!7^o_!?-(-IdZKXOn|?I=CbGzEmRR|C!WO=+-~qN*#9@gY4^ORT2SUJ+4TnZ?ON zlSM8iT@_=urQSQCl!}RAyw760c=thFN)p3~2f9%2ouCBZR4h1h;_!qDs%LAs9C|u+l?nRgKd?>3M%NP!MLOsb!o1DG>|!617pHp%?Opi@&c+Q zh96YFnqW(6s5=}SQtn8RLRjMKOk9y!RxOaZCDLx|S3ubNP6ynfTJJEcqO2{hv_1FH zJ8~KcF;^tD)}lq&r7*as5}H-fEbYg-;^Wygrj;m`6M0FvrUdY)zCwa+a&QRC!&Rg@JfNArzZP8mypTBe&tC!$EL*jIP!@SCOm8;y`*O2EcQQEX(6>#O_lc zsAELJ0VTyyzcNQ2s1B5q$xeiH+ejM?3~{6x9E#@IK#`BWoG5{o$dbF%h6R*a zBYAg3Sh1b>f;&iG7Qw|Go251wiQokIak#prA*~G*5K3rbgI$`R2xz)~wU3pJos8Fk zPGiRoZ_uV{ztKIDCYPAqr=)WK0IH$W{7EN=wRmNS+eoQfd=P)ldgc~f8TfH!ID+(>0kk-aq6LyyY&tRir>Do>fNzQ^MvnEn^$?0$*Pk8ur}%Sw#jGwi!O!{#ve3P6h^$=c}|e}oV9Mw?*q zGdk~p^qI8mnXz|4k^`jNU2Q$;mypQat|5EgP8XktEEAC5IfbR$hyi&{x8RLmN@MaQ zfI0?~axuWy)O8DH8QP{}%L;akw$;?0MHSSvne1S;kVjCon6mlU%ysew6`iGTq&T`K zu=YvHuVe7eod%flRA(u&#z{c(`Jxh#`4J>)326$!@e1Wfd~}U5Z3B#>2}mkEZ7J5H zL{5o}kT`Nv)J8Z1WlCeg2xuiB615!q;*Ng@toPP*GmTG^v!4 zz!vhTglNl}?t7;_#joR{Cd=x$#cIm|zRGZTPA~*FLg1{X=pcV6vC8%vYl!+47+6kg z(72`&n?<%hv5^e|>jT|b$F0F94voRfH@!KpdoD{$h)|X# zE=y~b(ROiM3Q!jip)Brw()LM7X;l)$x=UaRE2(uUM6oR)DM(0EqO55oro5+Jc1?Gv zt0j!Ld#0Q0o_I~AbW0VEBdT#Ao(gRx4IxS@&K6MuKofve!c1@}z?9VBmK~f*;CZFR za0(K`#nl}}VIZTl@T!YUaZI%9Oe2*=*~vNXmXlPXSm2x!EjS?!F$x>HQY*S46=?$5 zz$GMs!a#XT)fE9_NhhgX#I&5+3Q+~JloMbsmOG#`{-koLHqh`_E?Sk|_ZyMULcVpDv#xZQBAA~rCZO5Rh5jC@WBvgSb(C>uW|d{{0? z4s0)w(?z2*3cfxSQ}t&?YCBP;)MuNAJlDw@$0h^K6kfVaJaTQ|k=a65z* z1_#QC&Xzvq56_HuP>uVhkgtJHA!6Ldfk3CXEI8Gww4jmDtKf<9GR@L%=xsDT*VRH~ zt_bnTxT*L1mZGy@3SrvYWHHrwc&+?Nb-uK4@Jw7rY(*+4s;}u+j4A=mVG{U2Q*wq zmp1z@T#gO%LZ|$m5i~)vk$nmgZ4wtQT|{#k+d`S9JhLb_v$!jlA)oRdKj^uYv=l-) zT)AdO#v{d>LUdtrv0^ z(2W$bG2Vv|xpG|68y3?nF|{c{r+R{zCiAM=1+HAONmDuyZK3Ujt`?Z+h0^87NWr#Pa^++cuBFS7B7~&0xpIKBh+SMRT&)6j+fR{!yKC8UN?n zcHRN^T)9Gyb7?ZUT)9yN*e;VC&n zT&)z&XilZem4YGaxpL)bf`q$%YnLi4N~D)-mn$HITI!|Cm6UZZ0dnO;7LwZK$`ItM zmnd1wk1LldAksNWOP3-=GpTXtxpIJt-rqFp;FZgj7BzJ)T%iRi7cN#qlJs1;5G+6~ zJc=Jh%aE|q)Vh~0LRrJ2<;#_#n8)zyNO%jED?p9hkhu0-xl;&RG>{X0S1v*t2*YNP zgkXz3mo8LV1tw3Iz;8tYeMVA9XxsU&T#g`QdLce{xz=253GO9w<)#K1$=E9-^;}5@ zYURnuNS8^cms;h@%4|a8*$lX_TII?hSq^-M7Z9VFTzjruofINX*wCC8E=Dbi086!U zP~k)~;0(royc{4J!nwl25|}|6A%hqwXjfkL`Q!V?=ljVPD$_Dj(=!8< zDs^H&YDS9oh(fJaWQtPmm-m$o-kar5>MZPj&B=gis`RCQ*3>Yt@x~rq7)w7t1;_n_ppvy&U$e^WqNY0siGE#MY8*eVjs7@p1KD;z<+#-_DyTKmZZ|Q64BVljRl$jTcNk>jms& z$X{sN-fB!Xd$YH@U32V1Hq5pWR^wY9i2(llbh71E8o%_(i#5ii7+;Ul>PvVA4&52!>~nhloOrFLue zmqY@CMV_k>GzA{^5&=5?7fv R1g2ow-wIx== 0 + #assert label > self.last_label + assert len(imgs) > 0 + label = self.wlabel + for img in imgs: + idx = self.widx + image_meta = {'image_index': idx, 'image_classes': [label]} + header = mx.recordio.IRHeader(0, label, idx, 0) + if isinstance(img, np.ndarray): + s = mx.recordio.pack_img(header,img,quality=95,img_fmt='.jpg') + else: + s = mx.recordio.pack(header, img) + self.writer.write_idx(idx, s) + self.meta.append(image_meta) + self.widx += 1 + self.max_label = label + self.wlabel += 1 + + + def add_image(self, img, label): + #!!! img should be BGR!!!! + #assert label >= 0 + #assert label > self.last_label + idx = self.widx + header = mx.recordio.IRHeader(0, label, idx, 0) + if isinstance(label, list): + idlabel = label[0] + else: + idlabel = label + image_meta = {'image_index': idx, 'image_classes': [idlabel]} + if isinstance(img, np.ndarray): + s = mx.recordio.pack_img(header,img,quality=95,img_fmt='.jpg') + else: + s = mx.recordio.pack(header, img) + self.writer.write_idx(idx, s) + self.meta.append(image_meta) + self.widx += 1 + self.max_label = max(self.max_label, idlabel) + + def close(self): + with open(osp.join(self.path, 'train.meta'), 'wb') as pfile: + pickle.dump(self.meta, pfile, protocol=pickle.HIGHEST_PROTOCOL) + print('stat:', self.widx, self.wlabel) + with open(os.path.join(self.path, 'property'), 'w') as f: + f.write("%d,%d,%d\n" % (self.max_label+1, self.image_size[0], self.image_size[1])) + f.write("%d\n" % (self.widx)) + diff --git a/src/utils/dependencies/insightface/model_zoo/__init__.py b/src/utils/dependencies/insightface/model_zoo/__init__.py new file mode 100644 index 0000000..225623d --- /dev/null +++ b/src/utils/dependencies/insightface/model_zoo/__init__.py @@ -0,0 +1,6 @@ +from .model_zoo import get_model +from .arcface_onnx import ArcFaceONNX +from .retinaface import RetinaFace +from .scrfd import SCRFD +from .landmark import Landmark +from .attribute import Attribute diff --git a/src/utils/dependencies/insightface/model_zoo/arcface_onnx.py b/src/utils/dependencies/insightface/model_zoo/arcface_onnx.py new file mode 100644 index 0000000..b537ce2 --- /dev/null +++ b/src/utils/dependencies/insightface/model_zoo/arcface_onnx.py @@ -0,0 +1,92 @@ +# -*- coding: utf-8 -*- +# @Organization : insightface.ai +# @Author : Jia Guo +# @Time : 2021-05-04 +# @Function : + +from __future__ import division +import numpy as np +import cv2 +import onnx +import onnxruntime +from ..utils import face_align + +__all__ = [ + 'ArcFaceONNX', +] + + +class ArcFaceONNX: + def __init__(self, model_file=None, session=None): + assert model_file is not None + self.model_file = model_file + self.session = session + self.taskname = 'recognition' + find_sub = False + find_mul = False + model = onnx.load(self.model_file) + graph = model.graph + for nid, node in enumerate(graph.node[:8]): + #print(nid, node.name) + if node.name.startswith('Sub') or node.name.startswith('_minus'): + find_sub = True + if node.name.startswith('Mul') or node.name.startswith('_mul'): + find_mul = True + if find_sub and find_mul: + #mxnet arcface model + input_mean = 0.0 + input_std = 1.0 + else: + input_mean = 127.5 + input_std = 127.5 + self.input_mean = input_mean + self.input_std = input_std + #print('input mean and std:', self.input_mean, self.input_std) + if self.session is None: + self.session = onnxruntime.InferenceSession(self.model_file, None) + input_cfg = self.session.get_inputs()[0] + input_shape = input_cfg.shape + input_name = input_cfg.name + self.input_size = tuple(input_shape[2:4][::-1]) + self.input_shape = input_shape + outputs = self.session.get_outputs() + output_names = [] + for out in outputs: + output_names.append(out.name) + self.input_name = input_name + self.output_names = output_names + assert len(self.output_names)==1 + self.output_shape = outputs[0].shape + + def prepare(self, ctx_id, **kwargs): + if ctx_id<0: + self.session.set_providers(['CPUExecutionProvider']) + + def get(self, img, face): + aimg = face_align.norm_crop(img, landmark=face.kps, image_size=self.input_size[0]) + face.embedding = self.get_feat(aimg).flatten() + return face.embedding + + def compute_sim(self, feat1, feat2): + from numpy.linalg import norm + feat1 = feat1.ravel() + feat2 = feat2.ravel() + sim = np.dot(feat1, feat2) / (norm(feat1) * norm(feat2)) + return sim + + def get_feat(self, imgs): + if not isinstance(imgs, list): + imgs = [imgs] + input_size = self.input_size + + blob = cv2.dnn.blobFromImages(imgs, 1.0 / self.input_std, input_size, + (self.input_mean, self.input_mean, self.input_mean), swapRB=True) + net_out = self.session.run(self.output_names, {self.input_name: blob})[0] + return net_out + + def forward(self, batch_data): + blob = (batch_data - self.input_mean) / self.input_std + net_out = self.session.run(self.output_names, {self.input_name: blob})[0] + return net_out + + diff --git a/src/utils/dependencies/insightface/model_zoo/attribute.py b/src/utils/dependencies/insightface/model_zoo/attribute.py new file mode 100644 index 0000000..40c34de --- /dev/null +++ b/src/utils/dependencies/insightface/model_zoo/attribute.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- +# @Organization : insightface.ai +# @Author : Jia Guo +# @Time : 2021-06-19 +# @Function : + +from __future__ import division +import numpy as np +import cv2 +import onnx +import onnxruntime +from ..utils import face_align + +__all__ = [ + 'Attribute', +] + + +class Attribute: + def __init__(self, model_file=None, session=None): + assert model_file is not None + self.model_file = model_file + self.session = session + find_sub = False + find_mul = False + model = onnx.load(self.model_file) + graph = model.graph + for nid, node in enumerate(graph.node[:8]): + #print(nid, node.name) + if node.name.startswith('Sub') or node.name.startswith('_minus'): + find_sub = True + if node.name.startswith('Mul') or node.name.startswith('_mul'): + find_mul = True + if nid<3 and node.name=='bn_data': + find_sub = True + find_mul = True + if find_sub and find_mul: + #mxnet arcface model + input_mean = 0.0 + input_std = 1.0 + else: + input_mean = 127.5 + input_std = 128.0 + self.input_mean = input_mean + self.input_std = input_std + #print('input mean and std:', model_file, self.input_mean, self.input_std) + if self.session is None: + self.session = onnxruntime.InferenceSession(self.model_file, None) + input_cfg = self.session.get_inputs()[0] + input_shape = input_cfg.shape + input_name = input_cfg.name + self.input_size = tuple(input_shape[2:4][::-1]) + self.input_shape = input_shape + outputs = self.session.get_outputs() + output_names = [] + for out in outputs: + output_names.append(out.name) + self.input_name = input_name + self.output_names = output_names + assert len(self.output_names)==1 + output_shape = outputs[0].shape + #print('init output_shape:', output_shape) + if output_shape[1]==3: + self.taskname = 'genderage' + else: + self.taskname = 'attribute_%d'%output_shape[1] + + def prepare(self, ctx_id, **kwargs): + if ctx_id<0: + self.session.set_providers(['CPUExecutionProvider']) + + def get(self, img, face): + bbox = face.bbox + w, h = (bbox[2] - bbox[0]), (bbox[3] - bbox[1]) + center = (bbox[2] + bbox[0]) / 2, (bbox[3] + bbox[1]) / 2 + rotate = 0 + _scale = self.input_size[0] / (max(w, h)*1.5) + #print('param:', img.shape, bbox, center, self.input_size, _scale, rotate) + aimg, M = face_align.transform(img, center, self.input_size[0], _scale, rotate) + input_size = tuple(aimg.shape[0:2][::-1]) + #assert input_size==self.input_size + blob = cv2.dnn.blobFromImage(aimg, 1.0/self.input_std, input_size, (self.input_mean, self.input_mean, self.input_mean), swapRB=True) + pred = self.session.run(self.output_names, {self.input_name : blob})[0][0] + if self.taskname=='genderage': + assert len(pred)==3 + gender = np.argmax(pred[:2]) + age = int(np.round(pred[2]*100)) + face['gender'] = gender + face['age'] = age + return gender, age + else: + return pred + + diff --git a/src/utils/dependencies/insightface/model_zoo/inswapper.py b/src/utils/dependencies/insightface/model_zoo/inswapper.py new file mode 100644 index 0000000..f321c62 --- /dev/null +++ b/src/utils/dependencies/insightface/model_zoo/inswapper.py @@ -0,0 +1,114 @@ +import time +import numpy as np +import onnxruntime +import cv2 +import onnx +from onnx import numpy_helper +from ..utils import face_align + + + + +class INSwapper(): + def __init__(self, model_file=None, session=None): + self.model_file = model_file + self.session = session + model = onnx.load(self.model_file) + graph = model.graph + self.emap = numpy_helper.to_array(graph.initializer[-1]) + self.input_mean = 0.0 + self.input_std = 255.0 + #print('input mean and std:', model_file, self.input_mean, self.input_std) + if self.session is None: + self.session = onnxruntime.InferenceSession(self.model_file, None) + inputs = self.session.get_inputs() + self.input_names = [] + for inp in inputs: + self.input_names.append(inp.name) + outputs = self.session.get_outputs() + output_names = [] + for out in outputs: + output_names.append(out.name) + self.output_names = output_names + assert len(self.output_names)==1 + output_shape = outputs[0].shape + input_cfg = inputs[0] + input_shape = input_cfg.shape + self.input_shape = input_shape + # print('inswapper-shape:', self.input_shape) + self.input_size = tuple(input_shape[2:4][::-1]) + + def forward(self, img, latent): + img = (img - self.input_mean) / self.input_std + pred = self.session.run(self.output_names, {self.input_names[0]: img, self.input_names[1]: latent})[0] + return pred + + def get(self, img, target_face, source_face, paste_back=True): + face_mask = np.zeros((img.shape[0], img.shape[1]), np.uint8) + cv2.fillPoly(face_mask, np.array([target_face.landmark_2d_106[[1,9,10,11,12,13,14,15,16,2,3,4,5,6,7,8,0,24,23,22,21,20,19,18,32,31,30,29,28,27,26,25,17,101,105,104,103,51,49,48,43]].astype('int64')]), 1) + aimg, M = face_align.norm_crop2(img, target_face.kps, self.input_size[0]) + blob = cv2.dnn.blobFromImage(aimg, 1.0 / self.input_std, self.input_size, + (self.input_mean, self.input_mean, self.input_mean), swapRB=True) + latent = source_face.normed_embedding.reshape((1,-1)) + latent = np.dot(latent, self.emap) + latent /= np.linalg.norm(latent) + pred = self.session.run(self.output_names, {self.input_names[0]: blob, self.input_names[1]: latent})[0] + #print(latent.shape, latent.dtype, pred.shape) + img_fake = pred.transpose((0,2,3,1))[0] + bgr_fake = np.clip(255 * img_fake, 0, 255).astype(np.uint8)[:,:,::-1] + if not paste_back: + return bgr_fake, M + else: + target_img = img + fake_diff = bgr_fake.astype(np.float32) - aimg.astype(np.float32) + fake_diff = np.abs(fake_diff).mean(axis=2) + fake_diff[:2,:] = 0 + fake_diff[-2:,:] = 0 + fake_diff[:,:2] = 0 + fake_diff[:,-2:] = 0 + IM = cv2.invertAffineTransform(M) + img_white = np.full((aimg.shape[0],aimg.shape[1]), 255, dtype=np.float32) + bgr_fake = cv2.warpAffine(bgr_fake, IM, (target_img.shape[1], target_img.shape[0]), borderValue=0.0) + img_white = cv2.warpAffine(img_white, IM, (target_img.shape[1], target_img.shape[0]), borderValue=0.0) + fake_diff = cv2.warpAffine(fake_diff, IM, (target_img.shape[1], target_img.shape[0]), borderValue=0.0) + img_white[img_white>20] = 255 + fthresh = 10 + fake_diff[fake_diff=fthresh] = 255 + img_mask = img_white + mask_h_inds, mask_w_inds = np.where(img_mask==255) + mask_h = np.max(mask_h_inds) - np.min(mask_h_inds) + mask_w = np.max(mask_w_inds) - np.min(mask_w_inds) + mask_size = int(np.sqrt(mask_h*mask_w)) + k = max(mask_size//10, 10) + #k = max(mask_size//20, 6) + #k = 6 + kernel = np.ones((k,k),np.uint8) + img_mask = cv2.erode(img_mask,kernel,iterations = 1) + kernel = np.ones((2,2),np.uint8) + fake_diff = cv2.dilate(fake_diff,kernel,iterations = 1) + + face_mask = cv2.erode(face_mask,np.ones((11,11),np.uint8),iterations = 1) + fake_diff[face_mask==1] = 255 + + k = max(mask_size//20, 5) + #k = 3 + #k = 3 + kernel_size = (k, k) + blur_size = tuple(2*i+1 for i in kernel_size) + img_mask = cv2.GaussianBlur(img_mask, blur_size, 0) + k = 5 + kernel_size = (k, k) + blur_size = tuple(2*i+1 for i in kernel_size) + fake_diff = cv2.blur(fake_diff, (11,11), 0) + ##fake_diff = cv2.GaussianBlur(fake_diff, blur_size, 0) + # print('blur_size: ', blur_size) + # fake_diff = cv2.blur(fake_diff, (21, 21), 0) # blur_size + img_mask /= 255 + fake_diff /= 255 + # img_mask = fake_diff + img_mask = img_mask*fake_diff + img_mask = np.reshape(img_mask, [img_mask.shape[0],img_mask.shape[1],1]) + fake_merged = img_mask * bgr_fake + (1-img_mask) * target_img.astype(np.float32) + fake_merged = fake_merged.astype(np.uint8) + return fake_merged diff --git a/src/utils/dependencies/insightface/model_zoo/landmark.py b/src/utils/dependencies/insightface/model_zoo/landmark.py new file mode 100644 index 0000000..598b4b2 --- /dev/null +++ b/src/utils/dependencies/insightface/model_zoo/landmark.py @@ -0,0 +1,114 @@ +# -*- coding: utf-8 -*- +# @Organization : insightface.ai +# @Author : Jia Guo +# @Time : 2021-05-04 +# @Function : + +from __future__ import division +import numpy as np +import cv2 +import onnx +import onnxruntime +from ..utils import face_align +from ..utils import transform +from ..data import get_object + +__all__ = [ + 'Landmark', +] + + +class Landmark: + def __init__(self, model_file=None, session=None): + assert model_file is not None + self.model_file = model_file + self.session = session + find_sub = False + find_mul = False + model = onnx.load(self.model_file) + graph = model.graph + for nid, node in enumerate(graph.node[:8]): + #print(nid, node.name) + if node.name.startswith('Sub') or node.name.startswith('_minus'): + find_sub = True + if node.name.startswith('Mul') or node.name.startswith('_mul'): + find_mul = True + if nid<3 and node.name=='bn_data': + find_sub = True + find_mul = True + if find_sub and find_mul: + #mxnet arcface model + input_mean = 0.0 + input_std = 1.0 + else: + input_mean = 127.5 + input_std = 128.0 + self.input_mean = input_mean + self.input_std = input_std + #print('input mean and std:', model_file, self.input_mean, self.input_std) + if self.session is None: + self.session = onnxruntime.InferenceSession(self.model_file, None) + input_cfg = self.session.get_inputs()[0] + input_shape = input_cfg.shape + input_name = input_cfg.name + self.input_size = tuple(input_shape[2:4][::-1]) + self.input_shape = input_shape + outputs = self.session.get_outputs() + output_names = [] + for out in outputs: + output_names.append(out.name) + self.input_name = input_name + self.output_names = output_names + assert len(self.output_names)==1 + output_shape = outputs[0].shape + self.require_pose = False + #print('init output_shape:', output_shape) + if output_shape[1]==3309: + self.lmk_dim = 3 + self.lmk_num = 68 + self.mean_lmk = get_object('meanshape_68.pkl') + self.require_pose = True + else: + self.lmk_dim = 2 + self.lmk_num = output_shape[1]//self.lmk_dim + self.taskname = 'landmark_%dd_%d'%(self.lmk_dim, self.lmk_num) + + def prepare(self, ctx_id, **kwargs): + if ctx_id<0: + self.session.set_providers(['CPUExecutionProvider']) + + def get(self, img, face): + bbox = face.bbox + w, h = (bbox[2] - bbox[0]), (bbox[3] - bbox[1]) + center = (bbox[2] + bbox[0]) / 2, (bbox[3] + bbox[1]) / 2 + rotate = 0 + _scale = self.input_size[0] / (max(w, h)*1.5) + #print('param:', img.shape, bbox, center, self.input_size, _scale, rotate) + aimg, M = face_align.transform(img, center, self.input_size[0], _scale, rotate) + input_size = tuple(aimg.shape[0:2][::-1]) + #assert input_size==self.input_size + blob = cv2.dnn.blobFromImage(aimg, 1.0/self.input_std, input_size, (self.input_mean, self.input_mean, self.input_mean), swapRB=True) + pred = self.session.run(self.output_names, {self.input_name : blob})[0][0] + if pred.shape[0] >= 3000: + pred = pred.reshape((-1, 3)) + else: + pred = pred.reshape((-1, 2)) + if self.lmk_num < pred.shape[0]: + pred = pred[self.lmk_num*-1:,:] + pred[:, 0:2] += 1 + pred[:, 0:2] *= (self.input_size[0] // 2) + if pred.shape[1] == 3: + pred[:, 2] *= (self.input_size[0] // 2) + + IM = cv2.invertAffineTransform(M) + pred = face_align.trans_points(pred, IM) + face[self.taskname] = pred + if self.require_pose: + P = transform.estimate_affine_matrix_3d23d(self.mean_lmk, pred) + s, R, t = transform.P2sRt(P) + rx, ry, rz = transform.matrix2angle(R) + pose = np.array( [rx, ry, rz], dtype=np.float32 ) + face['pose'] = pose #pitch, yaw, roll + return pred + + diff --git a/src/utils/dependencies/insightface/model_zoo/model_store.py b/src/utils/dependencies/insightface/model_zoo/model_store.py new file mode 100644 index 0000000..50bb85d --- /dev/null +++ b/src/utils/dependencies/insightface/model_zoo/model_store.py @@ -0,0 +1,103 @@ +""" +This code file mainly comes from https://github.com/dmlc/gluon-cv/blob/master/gluoncv/model_zoo/model_store.py +""" +from __future__ import print_function + +__all__ = ['get_model_file'] +import os +import zipfile +import glob + +from ..utils import download, check_sha1 + +_model_sha1 = { + name: checksum + for checksum, name in [ + ('95be21b58e29e9c1237f229dae534bd854009ce0', 'arcface_r100_v1'), + ('', 'arcface_mfn_v1'), + ('39fd1e087a2a2ed70a154ac01fecaa86c315d01b', 'retinaface_r50_v1'), + ('2c9de8116d1f448fd1d4661f90308faae34c990a', 'retinaface_mnet025_v1'), + ('0db1d07921d005e6c9a5b38e059452fc5645e5a4', 'retinaface_mnet025_v2'), + ('7dd8111652b7aac2490c5dcddeb268e53ac643e6', 'genderage_v1'), + ] +} + +base_repo_url = 'https://insightface.ai/files/' +_url_format = '{repo_url}models/{file_name}.zip' + + +def short_hash(name): + if name not in _model_sha1: + raise ValueError( + 'Pretrained model for {name} is not available.'.format(name=name)) + return _model_sha1[name][:8] + + +def find_params_file(dir_path): + if not os.path.exists(dir_path): + return None + paths = glob.glob("%s/*.params" % dir_path) + if len(paths) == 0: + return None + paths = sorted(paths) + return paths[-1] + + +def get_model_file(name, root=os.path.join('~', '.insightface', 'models')): + r"""Return location for the pretrained on local file system. + + This function will download from online model zoo when model cannot be found or has mismatch. + The root directory will be created if it doesn't exist. + + Parameters + ---------- + name : str + Name of the model. + root : str, default '~/.mxnet/models' + Location for keeping the model parameters. + + Returns + ------- + file_path + Path to the requested pretrained model file. + """ + + file_name = name + root = os.path.expanduser(root) + dir_path = os.path.join(root, name) + file_path = find_params_file(dir_path) + #file_path = os.path.join(root, file_name + '.params') + sha1_hash = _model_sha1[name] + if file_path is not None: + if check_sha1(file_path, sha1_hash): + return file_path + else: + print( + 'Mismatch in the content of model file detected. Downloading again.' + ) + else: + print('Model file is not found. Downloading.') + + if not os.path.exists(root): + os.makedirs(root) + if not os.path.exists(dir_path): + os.makedirs(dir_path) + + zip_file_path = os.path.join(root, file_name + '.zip') + repo_url = base_repo_url + if repo_url[-1] != '/': + repo_url = repo_url + '/' + download(_url_format.format(repo_url=repo_url, file_name=file_name), + path=zip_file_path, + overwrite=True) + with zipfile.ZipFile(zip_file_path) as zf: + zf.extractall(dir_path) + os.remove(zip_file_path) + file_path = find_params_file(dir_path) + + if check_sha1(file_path, sha1_hash): + return file_path + else: + raise ValueError( + 'Downloaded file has different hash. Please try again.') + diff --git a/src/utils/dependencies/insightface/model_zoo/model_zoo.py b/src/utils/dependencies/insightface/model_zoo/model_zoo.py new file mode 100644 index 0000000..d8366e2 --- /dev/null +++ b/src/utils/dependencies/insightface/model_zoo/model_zoo.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- +# @Organization : insightface.ai +# @Author : Jia Guo +# @Time : 2021-05-04 +# @Function : + +import os +import os.path as osp +import glob +import onnxruntime +from .arcface_onnx import * +from .retinaface import * +#from .scrfd import * +from .landmark import * +from .attribute import Attribute +from .inswapper import INSwapper +from ..utils import download_onnx + +__all__ = ['get_model'] + + +class PickableInferenceSession(onnxruntime.InferenceSession): + # This is a wrapper to make the current InferenceSession class pickable. + def __init__(self, model_path, **kwargs): + super().__init__(model_path, **kwargs) + self.model_path = model_path + + def __getstate__(self): + return {'model_path': self.model_path} + + def __setstate__(self, values): + model_path = values['model_path'] + self.__init__(model_path) + +class ModelRouter: + def __init__(self, onnx_file): + self.onnx_file = onnx_file + + def get_model(self, **kwargs): + session = PickableInferenceSession(self.onnx_file, **kwargs) + # print(f'Applied providers: {session._providers}, with options: {session._provider_options}') + inputs = session.get_inputs() + input_cfg = inputs[0] + input_shape = input_cfg.shape + outputs = session.get_outputs() + + if len(outputs)>=5: + return RetinaFace(model_file=self.onnx_file, session=session) + elif input_shape[2]==192 and input_shape[3]==192: + return Landmark(model_file=self.onnx_file, session=session) + elif input_shape[2]==96 and input_shape[3]==96: + return Attribute(model_file=self.onnx_file, session=session) + elif len(inputs)==2 and input_shape[2]==128 and input_shape[3]==128: + return INSwapper(model_file=self.onnx_file, session=session) + elif input_shape[2]==input_shape[3] and input_shape[2]>=112 and input_shape[2]%16==0: + return ArcFaceONNX(model_file=self.onnx_file, session=session) + else: + #raise RuntimeError('error on model routing') + return None + +def find_onnx_file(dir_path): + if not os.path.exists(dir_path): + return None + paths = glob.glob("%s/*.onnx" % dir_path) + if len(paths) == 0: + return None + paths = sorted(paths) + return paths[-1] + +def get_default_providers(): + return ['CUDAExecutionProvider', 'CPUExecutionProvider'] + +def get_default_provider_options(): + return None + +def get_model(name, **kwargs): + root = kwargs.get('root', '~/.insightface') + root = os.path.expanduser(root) + model_root = osp.join(root, 'models') + allow_download = kwargs.get('download', False) + download_zip = kwargs.get('download_zip', False) + if not name.endswith('.onnx'): + model_dir = os.path.join(model_root, name) + model_file = find_onnx_file(model_dir) + if model_file is None: + return None + else: + model_file = name + if not osp.exists(model_file) and allow_download: + model_file = download_onnx('models', model_file, root=root, download_zip=download_zip) + assert osp.exists(model_file), 'model_file %s should exist'%model_file + assert osp.isfile(model_file), 'model_file %s should be a file'%model_file + router = ModelRouter(model_file) + providers = kwargs.get('providers', get_default_providers()) + provider_options = kwargs.get('provider_options', get_default_provider_options()) + model = router.get_model(providers=providers, provider_options=provider_options) + return model diff --git a/src/utils/dependencies/insightface/model_zoo/retinaface.py b/src/utils/dependencies/insightface/model_zoo/retinaface.py new file mode 100644 index 0000000..fc4ad91 --- /dev/null +++ b/src/utils/dependencies/insightface/model_zoo/retinaface.py @@ -0,0 +1,301 @@ +# -*- coding: utf-8 -*- +# @Organization : insightface.ai +# @Author : Jia Guo +# @Time : 2021-09-18 +# @Function : + +from __future__ import division +import datetime +import numpy as np +import onnx +import onnxruntime +import os +import os.path as osp +import cv2 +import sys + +def softmax(z): + assert len(z.shape) == 2 + s = np.max(z, axis=1) + s = s[:, np.newaxis] # necessary step to do broadcasting + e_x = np.exp(z - s) + div = np.sum(e_x, axis=1) + div = div[:, np.newaxis] # dito + return e_x / div + +def distance2bbox(points, distance, max_shape=None): + """Decode distance prediction to bounding box. + + Args: + points (Tensor): Shape (n, 2), [x, y]. + distance (Tensor): Distance from the given point to 4 + boundaries (left, top, right, bottom). + max_shape (tuple): Shape of the image. + + Returns: + Tensor: Decoded bboxes. + """ + x1 = points[:, 0] - distance[:, 0] + y1 = points[:, 1] - distance[:, 1] + x2 = points[:, 0] + distance[:, 2] + y2 = points[:, 1] + distance[:, 3] + if max_shape is not None: + x1 = x1.clamp(min=0, max=max_shape[1]) + y1 = y1.clamp(min=0, max=max_shape[0]) + x2 = x2.clamp(min=0, max=max_shape[1]) + y2 = y2.clamp(min=0, max=max_shape[0]) + return np.stack([x1, y1, x2, y2], axis=-1) + +def distance2kps(points, distance, max_shape=None): + """Decode distance prediction to bounding box. + + Args: + points (Tensor): Shape (n, 2), [x, y]. + distance (Tensor): Distance from the given point to 4 + boundaries (left, top, right, bottom). + max_shape (tuple): Shape of the image. + + Returns: + Tensor: Decoded bboxes. + """ + preds = [] + for i in range(0, distance.shape[1], 2): + px = points[:, i%2] + distance[:, i] + py = points[:, i%2+1] + distance[:, i+1] + if max_shape is not None: + px = px.clamp(min=0, max=max_shape[1]) + py = py.clamp(min=0, max=max_shape[0]) + preds.append(px) + preds.append(py) + return np.stack(preds, axis=-1) + +class RetinaFace: + def __init__(self, model_file=None, session=None): + import onnxruntime + self.model_file = model_file + self.session = session + self.taskname = 'detection' + if self.session is None: + assert self.model_file is not None + assert osp.exists(self.model_file) + self.session = onnxruntime.InferenceSession(self.model_file, None) + self.center_cache = {} + self.nms_thresh = 0.4 + self.det_thresh = 0.5 + self._init_vars() + + def _init_vars(self): + input_cfg = self.session.get_inputs()[0] + input_shape = input_cfg.shape + #print(input_shape) + if isinstance(input_shape[2], str): + self.input_size = None + else: + self.input_size = tuple(input_shape[2:4][::-1]) + #print('image_size:', self.image_size) + input_name = input_cfg.name + self.input_shape = input_shape + outputs = self.session.get_outputs() + output_names = [] + for o in outputs: + output_names.append(o.name) + self.input_name = input_name + self.output_names = output_names + self.input_mean = 127.5 + self.input_std = 128.0 + #print(self.output_names) + #assert len(outputs)==10 or len(outputs)==15 + self.use_kps = False + self._anchor_ratio = 1.0 + self._num_anchors = 1 + if len(outputs)==6: + self.fmc = 3 + self._feat_stride_fpn = [8, 16, 32] + self._num_anchors = 2 + elif len(outputs)==9: + self.fmc = 3 + self._feat_stride_fpn = [8, 16, 32] + self._num_anchors = 2 + self.use_kps = True + elif len(outputs)==10: + self.fmc = 5 + self._feat_stride_fpn = [8, 16, 32, 64, 128] + self._num_anchors = 1 + elif len(outputs)==15: + self.fmc = 5 + self._feat_stride_fpn = [8, 16, 32, 64, 128] + self._num_anchors = 1 + self.use_kps = True + + def prepare(self, ctx_id, **kwargs): + if ctx_id<0: + self.session.set_providers(['CPUExecutionProvider']) + nms_thresh = kwargs.get('nms_thresh', None) + if nms_thresh is not None: + self.nms_thresh = nms_thresh + det_thresh = kwargs.get('det_thresh', None) + if det_thresh is not None: + self.det_thresh = det_thresh + input_size = kwargs.get('input_size', None) + if input_size is not None: + if self.input_size is not None: + print('warning: det_size is already set in detection model, ignore') + else: + self.input_size = input_size + + def forward(self, img, threshold): + scores_list = [] + bboxes_list = [] + kpss_list = [] + input_size = tuple(img.shape[0:2][::-1]) + blob = cv2.dnn.blobFromImage(img, 1.0/self.input_std, input_size, (self.input_mean, self.input_mean, self.input_mean), swapRB=True) + net_outs = self.session.run(self.output_names, {self.input_name : blob}) + + input_height = blob.shape[2] + input_width = blob.shape[3] + fmc = self.fmc + for idx, stride in enumerate(self._feat_stride_fpn): + scores = net_outs[idx] + bbox_preds = net_outs[idx+fmc] + bbox_preds = bbox_preds * stride + if self.use_kps: + kps_preds = net_outs[idx+fmc*2] * stride + height = input_height // stride + width = input_width // stride + K = height * width + key = (height, width, stride) + if key in self.center_cache: + anchor_centers = self.center_cache[key] + else: + #solution-1, c style: + #anchor_centers = np.zeros( (height, width, 2), dtype=np.float32 ) + #for i in range(height): + # anchor_centers[i, :, 1] = i + #for i in range(width): + # anchor_centers[:, i, 0] = i + + #solution-2: + #ax = np.arange(width, dtype=np.float32) + #ay = np.arange(height, dtype=np.float32) + #xv, yv = np.meshgrid(np.arange(width), np.arange(height)) + #anchor_centers = np.stack([xv, yv], axis=-1).astype(np.float32) + + #solution-3: + anchor_centers = np.stack(np.mgrid[:height, :width][::-1], axis=-1).astype(np.float32) + #print(anchor_centers.shape) + + anchor_centers = (anchor_centers * stride).reshape( (-1, 2) ) + if self._num_anchors>1: + anchor_centers = np.stack([anchor_centers]*self._num_anchors, axis=1).reshape( (-1,2) ) + if len(self.center_cache)<100: + self.center_cache[key] = anchor_centers + + pos_inds = np.where(scores>=threshold)[0] + bboxes = distance2bbox(anchor_centers, bbox_preds) + pos_scores = scores[pos_inds] + pos_bboxes = bboxes[pos_inds] + scores_list.append(pos_scores) + bboxes_list.append(pos_bboxes) + if self.use_kps: + kpss = distance2kps(anchor_centers, kps_preds) + #kpss = kps_preds + kpss = kpss.reshape( (kpss.shape[0], -1, 2) ) + pos_kpss = kpss[pos_inds] + kpss_list.append(pos_kpss) + return scores_list, bboxes_list, kpss_list + + def detect(self, img, input_size = None, max_num=0, metric='default'): + assert input_size is not None or self.input_size is not None + input_size = self.input_size if input_size is None else input_size + + im_ratio = float(img.shape[0]) / img.shape[1] + model_ratio = float(input_size[1]) / input_size[0] + if im_ratio>model_ratio: + new_height = input_size[1] + new_width = int(new_height / im_ratio) + else: + new_width = input_size[0] + new_height = int(new_width * im_ratio) + det_scale = float(new_height) / img.shape[0] + resized_img = cv2.resize(img, (new_width, new_height)) + det_img = np.zeros( (input_size[1], input_size[0], 3), dtype=np.uint8 ) + det_img[:new_height, :new_width, :] = resized_img + + scores_list, bboxes_list, kpss_list = self.forward(det_img, self.det_thresh) + + scores = np.vstack(scores_list) + scores_ravel = scores.ravel() + order = scores_ravel.argsort()[::-1] + bboxes = np.vstack(bboxes_list) / det_scale + if self.use_kps: + kpss = np.vstack(kpss_list) / det_scale + pre_det = np.hstack((bboxes, scores)).astype(np.float32, copy=False) + pre_det = pre_det[order, :] + keep = self.nms(pre_det) + det = pre_det[keep, :] + if self.use_kps: + kpss = kpss[order,:,:] + kpss = kpss[keep,:,:] + else: + kpss = None + if max_num > 0 and det.shape[0] > max_num: + area = (det[:, 2] - det[:, 0]) * (det[:, 3] - + det[:, 1]) + img_center = img.shape[0] // 2, img.shape[1] // 2 + offsets = np.vstack([ + (det[:, 0] + det[:, 2]) / 2 - img_center[1], + (det[:, 1] + det[:, 3]) / 2 - img_center[0] + ]) + offset_dist_squared = np.sum(np.power(offsets, 2.0), 0) + if metric=='max': + values = area + else: + values = area - offset_dist_squared * 2.0 # some extra weight on the centering + bindex = np.argsort( + values)[::-1] # some extra weight on the centering + bindex = bindex[0:max_num] + det = det[bindex, :] + if kpss is not None: + kpss = kpss[bindex, :] + return det, kpss + + def nms(self, dets): + thresh = self.nms_thresh + x1 = dets[:, 0] + y1 = dets[:, 1] + x2 = dets[:, 2] + y2 = dets[:, 3] + scores = dets[:, 4] + + areas = (x2 - x1 + 1) * (y2 - y1 + 1) + order = scores.argsort()[::-1] + + keep = [] + while order.size > 0: + i = order[0] + keep.append(i) + xx1 = np.maximum(x1[i], x1[order[1:]]) + yy1 = np.maximum(y1[i], y1[order[1:]]) + xx2 = np.minimum(x2[i], x2[order[1:]]) + yy2 = np.minimum(y2[i], y2[order[1:]]) + + w = np.maximum(0.0, xx2 - xx1 + 1) + h = np.maximum(0.0, yy2 - yy1 + 1) + inter = w * h + ovr = inter / (areas[i] + areas[order[1:]] - inter) + + inds = np.where(ovr <= thresh)[0] + order = order[inds + 1] + + return keep + +def get_retinaface(name, download=False, root='~/.insightface/models', **kwargs): + if not download: + assert os.path.exists(name) + return RetinaFace(name) + else: + from .model_store import get_model_file + _file = get_model_file("retinaface_%s" % name, root=root) + return retinaface(_file) + + diff --git a/src/utils/dependencies/insightface/model_zoo/scrfd.py b/src/utils/dependencies/insightface/model_zoo/scrfd.py new file mode 100644 index 0000000..674db4b --- /dev/null +++ b/src/utils/dependencies/insightface/model_zoo/scrfd.py @@ -0,0 +1,348 @@ +# -*- coding: utf-8 -*- +# @Organization : insightface.ai +# @Author : Jia Guo +# @Time : 2021-05-04 +# @Function : + +from __future__ import division +import datetime +import numpy as np +import onnx +import onnxruntime +import os +import os.path as osp +import cv2 +import sys + +def softmax(z): + assert len(z.shape) == 2 + s = np.max(z, axis=1) + s = s[:, np.newaxis] # necessary step to do broadcasting + e_x = np.exp(z - s) + div = np.sum(e_x, axis=1) + div = div[:, np.newaxis] # dito + return e_x / div + +def distance2bbox(points, distance, max_shape=None): + """Decode distance prediction to bounding box. + + Args: + points (Tensor): Shape (n, 2), [x, y]. + distance (Tensor): Distance from the given point to 4 + boundaries (left, top, right, bottom). + max_shape (tuple): Shape of the image. + + Returns: + Tensor: Decoded bboxes. + """ + x1 = points[:, 0] - distance[:, 0] + y1 = points[:, 1] - distance[:, 1] + x2 = points[:, 0] + distance[:, 2] + y2 = points[:, 1] + distance[:, 3] + if max_shape is not None: + x1 = x1.clamp(min=0, max=max_shape[1]) + y1 = y1.clamp(min=0, max=max_shape[0]) + x2 = x2.clamp(min=0, max=max_shape[1]) + y2 = y2.clamp(min=0, max=max_shape[0]) + return np.stack([x1, y1, x2, y2], axis=-1) + +def distance2kps(points, distance, max_shape=None): + """Decode distance prediction to bounding box. + + Args: + points (Tensor): Shape (n, 2), [x, y]. + distance (Tensor): Distance from the given point to 4 + boundaries (left, top, right, bottom). + max_shape (tuple): Shape of the image. + + Returns: + Tensor: Decoded bboxes. + """ + preds = [] + for i in range(0, distance.shape[1], 2): + px = points[:, i%2] + distance[:, i] + py = points[:, i%2+1] + distance[:, i+1] + if max_shape is not None: + px = px.clamp(min=0, max=max_shape[1]) + py = py.clamp(min=0, max=max_shape[0]) + preds.append(px) + preds.append(py) + return np.stack(preds, axis=-1) + +class SCRFD: + def __init__(self, model_file=None, session=None): + import onnxruntime + self.model_file = model_file + self.session = session + self.taskname = 'detection' + self.batched = False + if self.session is None: + assert self.model_file is not None + assert osp.exists(self.model_file) + self.session = onnxruntime.InferenceSession(self.model_file, None) + self.center_cache = {} + self.nms_thresh = 0.4 + self.det_thresh = 0.5 + self._init_vars() + + def _init_vars(self): + input_cfg = self.session.get_inputs()[0] + input_shape = input_cfg.shape + #print(input_shape) + if isinstance(input_shape[2], str): + self.input_size = None + else: + self.input_size = tuple(input_shape[2:4][::-1]) + #print('image_size:', self.image_size) + input_name = input_cfg.name + self.input_shape = input_shape + outputs = self.session.get_outputs() + if len(outputs[0].shape) == 3: + self.batched = True + output_names = [] + for o in outputs: + output_names.append(o.name) + self.input_name = input_name + self.output_names = output_names + self.input_mean = 127.5 + self.input_std = 128.0 + #print(self.output_names) + #assert len(outputs)==10 or len(outputs)==15 + self.use_kps = False + self._anchor_ratio = 1.0 + self._num_anchors = 1 + if len(outputs)==6: + self.fmc = 3 + self._feat_stride_fpn = [8, 16, 32] + self._num_anchors = 2 + elif len(outputs)==9: + self.fmc = 3 + self._feat_stride_fpn = [8, 16, 32] + self._num_anchors = 2 + self.use_kps = True + elif len(outputs)==10: + self.fmc = 5 + self._feat_stride_fpn = [8, 16, 32, 64, 128] + self._num_anchors = 1 + elif len(outputs)==15: + self.fmc = 5 + self._feat_stride_fpn = [8, 16, 32, 64, 128] + self._num_anchors = 1 + self.use_kps = True + + def prepare(self, ctx_id, **kwargs): + if ctx_id<0: + self.session.set_providers(['CPUExecutionProvider']) + nms_thresh = kwargs.get('nms_thresh', None) + if nms_thresh is not None: + self.nms_thresh = nms_thresh + det_thresh = kwargs.get('det_thresh', None) + if det_thresh is not None: + self.det_thresh = det_thresh + input_size = kwargs.get('input_size', None) + if input_size is not None: + if self.input_size is not None: + print('warning: det_size is already set in scrfd model, ignore') + else: + self.input_size = input_size + + def forward(self, img, threshold): + scores_list = [] + bboxes_list = [] + kpss_list = [] + input_size = tuple(img.shape[0:2][::-1]) + blob = cv2.dnn.blobFromImage(img, 1.0/self.input_std, input_size, (self.input_mean, self.input_mean, self.input_mean), swapRB=True) + net_outs = self.session.run(self.output_names, {self.input_name : blob}) + + input_height = blob.shape[2] + input_width = blob.shape[3] + fmc = self.fmc + for idx, stride in enumerate(self._feat_stride_fpn): + # If model support batch dim, take first output + if self.batched: + scores = net_outs[idx][0] + bbox_preds = net_outs[idx + fmc][0] + bbox_preds = bbox_preds * stride + if self.use_kps: + kps_preds = net_outs[idx + fmc * 2][0] * stride + # If model doesn't support batching take output as is + else: + scores = net_outs[idx] + bbox_preds = net_outs[idx + fmc] + bbox_preds = bbox_preds * stride + if self.use_kps: + kps_preds = net_outs[idx + fmc * 2] * stride + + height = input_height // stride + width = input_width // stride + K = height * width + key = (height, width, stride) + if key in self.center_cache: + anchor_centers = self.center_cache[key] + else: + #solution-1, c style: + #anchor_centers = np.zeros( (height, width, 2), dtype=np.float32 ) + #for i in range(height): + # anchor_centers[i, :, 1] = i + #for i in range(width): + # anchor_centers[:, i, 0] = i + + #solution-2: + #ax = np.arange(width, dtype=np.float32) + #ay = np.arange(height, dtype=np.float32) + #xv, yv = np.meshgrid(np.arange(width), np.arange(height)) + #anchor_centers = np.stack([xv, yv], axis=-1).astype(np.float32) + + #solution-3: + anchor_centers = np.stack(np.mgrid[:height, :width][::-1], axis=-1).astype(np.float32) + #print(anchor_centers.shape) + + anchor_centers = (anchor_centers * stride).reshape( (-1, 2) ) + if self._num_anchors>1: + anchor_centers = np.stack([anchor_centers]*self._num_anchors, axis=1).reshape( (-1,2) ) + if len(self.center_cache)<100: + self.center_cache[key] = anchor_centers + + pos_inds = np.where(scores>=threshold)[0] + bboxes = distance2bbox(anchor_centers, bbox_preds) + pos_scores = scores[pos_inds] + pos_bboxes = bboxes[pos_inds] + scores_list.append(pos_scores) + bboxes_list.append(pos_bboxes) + if self.use_kps: + kpss = distance2kps(anchor_centers, kps_preds) + #kpss = kps_preds + kpss = kpss.reshape( (kpss.shape[0], -1, 2) ) + pos_kpss = kpss[pos_inds] + kpss_list.append(pos_kpss) + return scores_list, bboxes_list, kpss_list + + def detect(self, img, input_size = None, max_num=0, metric='default'): + assert input_size is not None or self.input_size is not None + input_size = self.input_size if input_size is None else input_size + + im_ratio = float(img.shape[0]) / img.shape[1] + model_ratio = float(input_size[1]) / input_size[0] + if im_ratio>model_ratio: + new_height = input_size[1] + new_width = int(new_height / im_ratio) + else: + new_width = input_size[0] + new_height = int(new_width * im_ratio) + det_scale = float(new_height) / img.shape[0] + resized_img = cv2.resize(img, (new_width, new_height)) + det_img = np.zeros( (input_size[1], input_size[0], 3), dtype=np.uint8 ) + det_img[:new_height, :new_width, :] = resized_img + + scores_list, bboxes_list, kpss_list = self.forward(det_img, self.det_thresh) + + scores = np.vstack(scores_list) + scores_ravel = scores.ravel() + order = scores_ravel.argsort()[::-1] + bboxes = np.vstack(bboxes_list) / det_scale + if self.use_kps: + kpss = np.vstack(kpss_list) / det_scale + pre_det = np.hstack((bboxes, scores)).astype(np.float32, copy=False) + pre_det = pre_det[order, :] + keep = self.nms(pre_det) + det = pre_det[keep, :] + if self.use_kps: + kpss = kpss[order,:,:] + kpss = kpss[keep,:,:] + else: + kpss = None + if max_num > 0 and det.shape[0] > max_num: + area = (det[:, 2] - det[:, 0]) * (det[:, 3] - + det[:, 1]) + img_center = img.shape[0] // 2, img.shape[1] // 2 + offsets = np.vstack([ + (det[:, 0] + det[:, 2]) / 2 - img_center[1], + (det[:, 1] + det[:, 3]) / 2 - img_center[0] + ]) + offset_dist_squared = np.sum(np.power(offsets, 2.0), 0) + if metric=='max': + values = area + else: + values = area - offset_dist_squared * 2.0 # some extra weight on the centering + bindex = np.argsort( + values)[::-1] # some extra weight on the centering + bindex = bindex[0:max_num] + det = det[bindex, :] + if kpss is not None: + kpss = kpss[bindex, :] + return det, kpss + + def nms(self, dets): + thresh = self.nms_thresh + x1 = dets[:, 0] + y1 = dets[:, 1] + x2 = dets[:, 2] + y2 = dets[:, 3] + scores = dets[:, 4] + + areas = (x2 - x1 + 1) * (y2 - y1 + 1) + order = scores.argsort()[::-1] + + keep = [] + while order.size > 0: + i = order[0] + keep.append(i) + xx1 = np.maximum(x1[i], x1[order[1:]]) + yy1 = np.maximum(y1[i], y1[order[1:]]) + xx2 = np.minimum(x2[i], x2[order[1:]]) + yy2 = np.minimum(y2[i], y2[order[1:]]) + + w = np.maximum(0.0, xx2 - xx1 + 1) + h = np.maximum(0.0, yy2 - yy1 + 1) + inter = w * h + ovr = inter / (areas[i] + areas[order[1:]] - inter) + + inds = np.where(ovr <= thresh)[0] + order = order[inds + 1] + + return keep + +def get_scrfd(name, download=False, root='~/.insightface/models', **kwargs): + if not download: + assert os.path.exists(name) + return SCRFD(name) + else: + from .model_store import get_model_file + _file = get_model_file("scrfd_%s" % name, root=root) + return SCRFD(_file) + + +def scrfd_2p5gkps(**kwargs): + return get_scrfd("2p5gkps", download=True, **kwargs) + + +if __name__ == '__main__': + import glob + detector = SCRFD(model_file='./det.onnx') + detector.prepare(-1) + img_paths = ['tests/data/t1.jpg'] + for img_path in img_paths: + img = cv2.imread(img_path) + + for _ in range(1): + ta = datetime.datetime.now() + #bboxes, kpss = detector.detect(img, 0.5, input_size = (640, 640)) + bboxes, kpss = detector.detect(img, 0.5) + tb = datetime.datetime.now() + print('all cost:', (tb-ta).total_seconds()*1000) + print(img_path, bboxes.shape) + if kpss is not None: + print(kpss.shape) + for i in range(bboxes.shape[0]): + bbox = bboxes[i] + x1,y1,x2,y2,score = bbox.astype(np.int) + cv2.rectangle(img, (x1,y1) , (x2,y2) , (255,0,0) , 2) + if kpss is not None: + kps = kpss[i] + for kp in kps: + kp = kp.astype(np.int) + cv2.circle(img, tuple(kp) , 1, (0,0,255) , 2) + filename = img_path.split('/')[-1] + print('output:', filename) + cv2.imwrite('./outputs/%s'%filename, img) + diff --git a/src/utils/dependencies/insightface/thirdparty/__init__.py b/src/utils/dependencies/insightface/thirdparty/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/utils/dependencies/insightface/thirdparty/face3d/__init__.py b/src/utils/dependencies/insightface/thirdparty/face3d/__init__.py new file mode 100644 index 0000000..68b2847 --- /dev/null +++ b/src/utils/dependencies/insightface/thirdparty/face3d/__init__.py @@ -0,0 +1,4 @@ +#import mesh +#import morphable_model +from . import mesh +from . import morphable_model diff --git a/src/utils/dependencies/insightface/thirdparty/face3d/mesh/__init__.py b/src/utils/dependencies/insightface/thirdparty/face3d/mesh/__init__.py new file mode 100644 index 0000000..4e43296 --- /dev/null +++ b/src/utils/dependencies/insightface/thirdparty/face3d/mesh/__init__.py @@ -0,0 +1,15 @@ +#from __future__ import absolute_import +#from cython import mesh_core_cython +#import io +#import vis +#import transform +#import light +#import render + +from .cython import mesh_core_cython +from . import io +from . import vis +from . import transform +from . import light +from . import render + diff --git a/src/utils/dependencies/insightface/thirdparty/face3d/mesh/cython/mesh_core.cpp b/src/utils/dependencies/insightface/thirdparty/face3d/mesh/cython/mesh_core.cpp new file mode 100644 index 0000000..aeea4da --- /dev/null +++ b/src/utils/dependencies/insightface/thirdparty/face3d/mesh/cython/mesh_core.cpp @@ -0,0 +1,375 @@ +/* +functions that can not be optimazed by vertorization in python. +1. rasterization.(need process each triangle) +2. normal of each vertex.(use one-ring, need process each vertex) +3. write obj(seems that it can be verctorized? anyway, writing it in c++ is simple, so also add function here. --> however, why writting in c++ is still slow?) + +Author: Yao Feng +Mail: yaofeng1995@gmail.com +*/ + +#include "mesh_core.h" + + +/* Judge whether the point is in the triangle +Method: + http://blackpawn.com/texts/pointinpoly/ +Args: + point: [x, y] + tri_points: three vertices(2d points) of a triangle. 2 coords x 3 vertices +Returns: + bool: true for in triangle +*/ +bool isPointInTri(point p, point p0, point p1, point p2) +{ + // vectors + point v0, v1, v2; + v0 = p2 - p0; + v1 = p1 - p0; + v2 = p - p0; + + // dot products + float dot00 = v0.dot(v0); //v0.x * v0.x + v0.y * v0.y //np.dot(v0.T, v0) + float dot01 = v0.dot(v1); //v0.x * v1.x + v0.y * v1.y //np.dot(v0.T, v1) + float dot02 = v0.dot(v2); //v0.x * v2.x + v0.y * v2.y //np.dot(v0.T, v2) + float dot11 = v1.dot(v1); //v1.x * v1.x + v1.y * v1.y //np.dot(v1.T, v1) + float dot12 = v1.dot(v2); //v1.x * v2.x + v1.y * v2.y//np.dot(v1.T, v2) + + // barycentric coordinates + float inverDeno; + if(dot00*dot11 - dot01*dot01 == 0) + inverDeno = 0; + else + inverDeno = 1/(dot00*dot11 - dot01*dot01); + + float u = (dot11*dot02 - dot01*dot12)*inverDeno; + float v = (dot00*dot12 - dot01*dot02)*inverDeno; + + // check if point in triangle + return (u >= 0) && (v >= 0) && (u + v < 1); +} + + +void get_point_weight(float* weight, point p, point p0, point p1, point p2) +{ + // vectors + point v0, v1, v2; + v0 = p2 - p0; + v1 = p1 - p0; + v2 = p - p0; + + // dot products + float dot00 = v0.dot(v0); //v0.x * v0.x + v0.y * v0.y //np.dot(v0.T, v0) + float dot01 = v0.dot(v1); //v0.x * v1.x + v0.y * v1.y //np.dot(v0.T, v1) + float dot02 = v0.dot(v2); //v0.x * v2.x + v0.y * v2.y //np.dot(v0.T, v2) + float dot11 = v1.dot(v1); //v1.x * v1.x + v1.y * v1.y //np.dot(v1.T, v1) + float dot12 = v1.dot(v2); //v1.x * v2.x + v1.y * v2.y//np.dot(v1.T, v2) + + // barycentric coordinates + float inverDeno; + if(dot00*dot11 - dot01*dot01 == 0) + inverDeno = 0; + else + inverDeno = 1/(dot00*dot11 - dot01*dot01); + + float u = (dot11*dot02 - dot01*dot12)*inverDeno; + float v = (dot00*dot12 - dot01*dot02)*inverDeno; + + // weight + weight[0] = 1 - u - v; + weight[1] = v; + weight[2] = u; +} + + +void _get_normal_core( + float* normal, float* tri_normal, int* triangles, + int ntri) +{ + int i, j; + int tri_p0_ind, tri_p1_ind, tri_p2_ind; + + for(i = 0; i < ntri; i++) + { + tri_p0_ind = triangles[3*i]; + tri_p1_ind = triangles[3*i + 1]; + tri_p2_ind = triangles[3*i + 2]; + + for(j = 0; j < 3; j++) + { + normal[3*tri_p0_ind + j] = normal[3*tri_p0_ind + j] + tri_normal[3*i + j]; + normal[3*tri_p1_ind + j] = normal[3*tri_p1_ind + j] + tri_normal[3*i + j]; + normal[3*tri_p2_ind + j] = normal[3*tri_p2_ind + j] + tri_normal[3*i + j]; + } + } +} + + +void _rasterize_triangles_core( + float* vertices, int* triangles, + float* depth_buffer, int* triangle_buffer, float* barycentric_weight, + int nver, int ntri, + int h, int w) +{ + int i; + int x, y, k; + int tri_p0_ind, tri_p1_ind, tri_p2_ind; + point p0, p1, p2, p; + int x_min, x_max, y_min, y_max; + float p_depth, p0_depth, p1_depth, p2_depth; + float weight[3]; + + for(i = 0; i < ntri; i++) + { + tri_p0_ind = triangles[3*i]; + tri_p1_ind = triangles[3*i + 1]; + tri_p2_ind = triangles[3*i + 2]; + + p0.x = vertices[3*tri_p0_ind]; p0.y = vertices[3*tri_p0_ind + 1]; p0_depth = vertices[3*tri_p0_ind + 2]; + p1.x = vertices[3*tri_p1_ind]; p1.y = vertices[3*tri_p1_ind + 1]; p1_depth = vertices[3*tri_p1_ind + 2]; + p2.x = vertices[3*tri_p2_ind]; p2.y = vertices[3*tri_p2_ind + 1]; p2_depth = vertices[3*tri_p2_ind + 2]; + + x_min = max((int)ceil(min(p0.x, min(p1.x, p2.x))), 0); + x_max = min((int)floor(max(p0.x, max(p1.x, p2.x))), w - 1); + + y_min = max((int)ceil(min(p0.y, min(p1.y, p2.y))), 0); + y_max = min((int)floor(max(p0.y, max(p1.y, p2.y))), h - 1); + + if(x_max < x_min || y_max < y_min) + { + continue; + } + + for(y = y_min; y <= y_max; y++) //h + { + for(x = x_min; x <= x_max; x++) //w + { + p.x = x; p.y = y; + if(p.x < 2 || p.x > w - 3 || p.y < 2 || p.y > h - 3 || isPointInTri(p, p0, p1, p2)) + { + get_point_weight(weight, p, p0, p1, p2); + p_depth = weight[0]*p0_depth + weight[1]*p1_depth + weight[2]*p2_depth; + + if((p_depth > depth_buffer[y*w + x])) + { + depth_buffer[y*w + x] = p_depth; + triangle_buffer[y*w + x] = i; + for(k = 0; k < 3; k++) + { + barycentric_weight[y*w*3 + x*3 + k] = weight[k]; + } + } + } + } + } + } +} + + +void _render_colors_core( + float* image, float* vertices, int* triangles, + float* colors, + float* depth_buffer, + int nver, int ntri, + int h, int w, int c) +{ + int i; + int x, y, k; + int tri_p0_ind, tri_p1_ind, tri_p2_ind; + point p0, p1, p2, p; + int x_min, x_max, y_min, y_max; + float p_depth, p0_depth, p1_depth, p2_depth; + float p_color, p0_color, p1_color, p2_color; + float weight[3]; + + for(i = 0; i < ntri; i++) + { + tri_p0_ind = triangles[3*i]; + tri_p1_ind = triangles[3*i + 1]; + tri_p2_ind = triangles[3*i + 2]; + + p0.x = vertices[3*tri_p0_ind]; p0.y = vertices[3*tri_p0_ind + 1]; p0_depth = vertices[3*tri_p0_ind + 2]; + p1.x = vertices[3*tri_p1_ind]; p1.y = vertices[3*tri_p1_ind + 1]; p1_depth = vertices[3*tri_p1_ind + 2]; + p2.x = vertices[3*tri_p2_ind]; p2.y = vertices[3*tri_p2_ind + 1]; p2_depth = vertices[3*tri_p2_ind + 2]; + + x_min = max((int)ceil(min(p0.x, min(p1.x, p2.x))), 0); + x_max = min((int)floor(max(p0.x, max(p1.x, p2.x))), w - 1); + + y_min = max((int)ceil(min(p0.y, min(p1.y, p2.y))), 0); + y_max = min((int)floor(max(p0.y, max(p1.y, p2.y))), h - 1); + + if(x_max < x_min || y_max < y_min) + { + continue; + } + + for(y = y_min; y <= y_max; y++) //h + { + for(x = x_min; x <= x_max; x++) //w + { + p.x = x; p.y = y; + if(p.x < 2 || p.x > w - 3 || p.y < 2 || p.y > h - 3 || isPointInTri(p, p0, p1, p2)) + { + get_point_weight(weight, p, p0, p1, p2); + p_depth = weight[0]*p0_depth + weight[1]*p1_depth + weight[2]*p2_depth; + + if((p_depth > depth_buffer[y*w + x])) + { + for(k = 0; k < c; k++) // c + { + p0_color = colors[c*tri_p0_ind + k]; + p1_color = colors[c*tri_p1_ind + k]; + p2_color = colors[c*tri_p2_ind + k]; + + p_color = weight[0]*p0_color + weight[1]*p1_color + weight[2]*p2_color; + image[y*w*c + x*c + k] = p_color; + } + + depth_buffer[y*w + x] = p_depth; + } + } + } + } + } +} + + +void _render_texture_core( + float* image, float* vertices, int* triangles, + float* texture, float* tex_coords, int* tex_triangles, + float* depth_buffer, + int nver, int tex_nver, int ntri, + int h, int w, int c, + int tex_h, int tex_w, int tex_c, + int mapping_type) +{ + int i; + int x, y, k; + int tri_p0_ind, tri_p1_ind, tri_p2_ind; + int tex_tri_p0_ind, tex_tri_p1_ind, tex_tri_p2_ind; + point p0, p1, p2, p; + point tex_p0, tex_p1, tex_p2, tex_p; + int x_min, x_max, y_min, y_max; + float weight[3]; + float p_depth, p0_depth, p1_depth, p2_depth; + float xd, yd; + float ul, ur, dl, dr; + for(i = 0; i < ntri; i++) + { + // mesh + tri_p0_ind = triangles[3*i]; + tri_p1_ind = triangles[3*i + 1]; + tri_p2_ind = triangles[3*i + 2]; + + p0.x = vertices[3*tri_p0_ind]; p0.y = vertices[3*tri_p0_ind + 1]; p0_depth = vertices[3*tri_p0_ind + 2]; + p1.x = vertices[3*tri_p1_ind]; p1.y = vertices[3*tri_p1_ind + 1]; p1_depth = vertices[3*tri_p1_ind + 2]; + p2.x = vertices[3*tri_p2_ind]; p2.y = vertices[3*tri_p2_ind + 1]; p2_depth = vertices[3*tri_p2_ind + 2]; + + // texture + tex_tri_p0_ind = tex_triangles[3*i]; + tex_tri_p1_ind = tex_triangles[3*i + 1]; + tex_tri_p2_ind = tex_triangles[3*i + 2]; + + tex_p0.x = tex_coords[3*tex_tri_p0_ind]; tex_p0.y = tex_coords[3*tri_p0_ind + 1]; + tex_p1.x = tex_coords[3*tex_tri_p1_ind]; tex_p1.y = tex_coords[3*tri_p1_ind + 1]; + tex_p2.x = tex_coords[3*tex_tri_p2_ind]; tex_p2.y = tex_coords[3*tri_p2_ind + 1]; + + + x_min = max((int)ceil(min(p0.x, min(p1.x, p2.x))), 0); + x_max = min((int)floor(max(p0.x, max(p1.x, p2.x))), w - 1); + + y_min = max((int)ceil(min(p0.y, min(p1.y, p2.y))), 0); + y_max = min((int)floor(max(p0.y, max(p1.y, p2.y))), h - 1); + + + if(x_max < x_min || y_max < y_min) + { + continue; + } + + for(y = y_min; y <= y_max; y++) //h + { + for(x = x_min; x <= x_max; x++) //w + { + p.x = x; p.y = y; + if(p.x < 2 || p.x > w - 3 || p.y < 2 || p.y > h - 3 || isPointInTri(p, p0, p1, p2)) + { + get_point_weight(weight, p, p0, p1, p2); + p_depth = weight[0]*p0_depth + weight[1]*p1_depth + weight[2]*p2_depth; + + if((p_depth > depth_buffer[y*w + x])) + { + // -- color from texture + // cal weight in mesh tri + get_point_weight(weight, p, p0, p1, p2); + // cal coord in texture + tex_p = tex_p0*weight[0] + tex_p1*weight[1] + tex_p2*weight[2]; + tex_p.x = max(min(tex_p.x, float(tex_w - 1)), float(0)); + tex_p.y = max(min(tex_p.y, float(tex_h - 1)), float(0)); + + yd = tex_p.y - floor(tex_p.y); + xd = tex_p.x - floor(tex_p.x); + for(k = 0; k < c; k++) + { + if(mapping_type==0)// nearest + { + image[y*w*c + x*c + k] = texture[int(round(tex_p.y))*tex_w*tex_c + int(round(tex_p.x))*tex_c + k]; + } + else//bilinear interp + { + ul = texture[(int)floor(tex_p.y)*tex_w*tex_c + (int)floor(tex_p.x)*tex_c + k]; + ur = texture[(int)floor(tex_p.y)*tex_w*tex_c + (int)ceil(tex_p.x)*tex_c + k]; + dl = texture[(int)ceil(tex_p.y)*tex_w*tex_c + (int)floor(tex_p.x)*tex_c + k]; + dr = texture[(int)ceil(tex_p.y)*tex_w*tex_c + (int)ceil(tex_p.x)*tex_c + k]; + + image[y*w*c + x*c + k] = ul*(1-xd)*(1-yd) + ur*xd*(1-yd) + dl*(1-xd)*yd + dr*xd*yd; + } + + } + + depth_buffer[y*w + x] = p_depth; + } + } + } + } + } +} + + + +// ------------------------------------------------- write +// obj write +// Ref: https://github.com/patrikhuber/eos/blob/master/include/eos/core/Mesh.hpp +void _write_obj_with_colors_texture(string filename, string mtl_name, + float* vertices, int* triangles, float* colors, float* uv_coords, + int nver, int ntri, int ntexver) +{ + int i; + + ofstream obj_file(filename.c_str()); + + // first line of the obj file: the mtl name + obj_file << "mtllib " << mtl_name << endl; + + // write vertices + for (i = 0; i < nver; ++i) + { + obj_file << "v " << vertices[3*i] << " " << vertices[3*i + 1] << " " << vertices[3*i + 2] << colors[3*i] << " " << colors[3*i + 1] << " " << colors[3*i + 2] << endl; + } + + // write uv coordinates + for (i = 0; i < ntexver; ++i) + { + //obj_file << "vt " << uv_coords[2*i] << " " << (1 - uv_coords[2*i + 1]) << endl; + obj_file << "vt " << uv_coords[2*i] << " " << uv_coords[2*i + 1] << endl; + } + + obj_file << "usemtl FaceTexture" << endl; + // write triangles + for (i = 0; i < ntri; ++i) + { + // obj_file << "f " << triangles[3*i] << "/" << triangles[3*i] << " " << triangles[3*i + 1] << "/" << triangles[3*i + 1] << " " << triangles[3*i + 2] << "/" << triangles[3*i + 2] << endl; + obj_file << "f " << triangles[3*i + 2] << "/" << triangles[3*i + 2] << " " << triangles[3*i + 1] << "/" << triangles[3*i + 1] << " " << triangles[3*i] << "/" << triangles[3*i] << endl; + } + +} diff --git a/src/utils/dependencies/insightface/thirdparty/face3d/mesh/cython/mesh_core.h b/src/utils/dependencies/insightface/thirdparty/face3d/mesh/cython/mesh_core.h new file mode 100644 index 0000000..3eb0029 --- /dev/null +++ b/src/utils/dependencies/insightface/thirdparty/face3d/mesh/cython/mesh_core.h @@ -0,0 +1,83 @@ +#ifndef MESH_CORE_HPP_ +#define MESH_CORE_HPP_ + +#include +#include +#include +#include +#include +#include + +using namespace std; + +class point +{ + public: + float x; + float y; + + float dot(point p) + { + return this->x * p.x + this->y * p.y; + } + + point operator-(const point& p) + { + point np; + np.x = this->x - p.x; + np.y = this->y - p.y; + return np; + } + + point operator+(const point& p) + { + point np; + np.x = this->x + p.x; + np.y = this->y + p.y; + return np; + } + + point operator*(float s) + { + point np; + np.x = s * this->x; + np.y = s * this->y; + return np; + } +}; + + +bool isPointInTri(point p, point p0, point p1, point p2, int h, int w); +void get_point_weight(float* weight, point p, point p0, point p1, point p2); + +void _get_normal_core( + float* normal, float* tri_normal, int* triangles, + int ntri); + +void _rasterize_triangles_core( + float* vertices, int* triangles, + float* depth_buffer, int* triangle_buffer, float* barycentric_weight, + int nver, int ntri, + int h, int w); + +void _render_colors_core( + float* image, float* vertices, int* triangles, + float* colors, + float* depth_buffer, + int nver, int ntri, + int h, int w, int c); + +void _render_texture_core( + float* image, float* vertices, int* triangles, + float* texture, float* tex_coords, int* tex_triangles, + float* depth_buffer, + int nver, int tex_nver, int ntri, + int h, int w, int c, + int tex_h, int tex_w, int tex_c, + int mapping_type); + +void _write_obj_with_colors_texture(string filename, string mtl_name, + float* vertices, int* triangles, float* colors, float* uv_coords, + int nver, int ntri, int ntexver); + +#endif \ No newline at end of file diff --git a/src/utils/dependencies/insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.c b/src/utils/dependencies/insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.c new file mode 100644 index 0000000..e113ac5 --- /dev/null +++ b/src/utils/dependencies/insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.c @@ -0,0 +1,9091 @@ +/* Generated by Cython 0.28.2 */ + +/* BEGIN: Cython Metadata +{ + "distutils": { + "depends": [ + "insightface/thirdparty/face3d/mesh/cython/mesh_core.h" + ], + "include_dirs": [ + "insightface/thirdparty/face3d/mesh/cython" + ], + "name": "mesh_core_cython", + "sources": [ + "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx" + ] + }, + "module_name": "mesh_core_cython" +} +END: Cython Metadata */ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" +#ifndef Py_PYTHON_H + #error Python headers needed to compile C extensions, please install development version of Python. +#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) + #error Cython requires Python 2.6+ or Python 3.3+. +#else +#define CYTHON_ABI "0_28_2" +#define CYTHON_FUTURE_DIVISION 0 +#include +#ifndef offsetof + #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) +#endif +#if !defined(WIN32) && !defined(MS_WINDOWS) + #ifndef __stdcall + #define __stdcall + #endif + #ifndef __cdecl + #define __cdecl + #endif + #ifndef __fastcall + #define __fastcall + #endif +#endif +#ifndef DL_IMPORT + #define DL_IMPORT(t) t +#endif +#ifndef DL_EXPORT + #define DL_EXPORT(t) t +#endif +#define __PYX_COMMA , +#ifndef HAVE_LONG_LONG + #if PY_VERSION_HEX >= 0x02070000 + #define HAVE_LONG_LONG + #endif +#endif +#ifndef PY_LONG_LONG + #define PY_LONG_LONG LONG_LONG +#endif +#ifndef Py_HUGE_VAL + #define Py_HUGE_VAL HUGE_VAL +#endif +#ifdef PYPY_VERSION + #define CYTHON_COMPILING_IN_PYPY 1 + #define CYTHON_COMPILING_IN_PYSTON 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #if PY_VERSION_HEX < 0x03050000 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 +#elif defined(PYSTON_VERSION) + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_PYSTON 1 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 +#else + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_PYSTON 0 + #define CYTHON_COMPILING_IN_CPYTHON 1 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #if PY_VERSION_HEX < 0x02070000 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #elif !defined(CYTHON_USE_PYTYPE_LOOKUP) + #define CYTHON_USE_PYTYPE_LOOKUP 1 + #endif + #if PY_MAJOR_VERSION < 3 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #if PY_VERSION_HEX < 0x02070000 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #elif !defined(CYTHON_USE_PYLONG_INTERNALS) + #define CYTHON_USE_PYLONG_INTERNALS 1 + #endif + #ifndef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 1 + #endif + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #if PY_VERSION_HEX < 0x030300F0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #elif !defined(CYTHON_USE_UNICODE_WRITER) + #define CYTHON_USE_UNICODE_WRITER 1 + #endif + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #ifndef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 1 + #endif + #ifndef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 1 + #endif + #ifndef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT (0 && PY_VERSION_HEX >= 0x03050000) + #endif + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1) + #endif +#endif +#if !defined(CYTHON_FAST_PYCCALL) +#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) +#endif +#if CYTHON_USE_PYLONG_INTERNALS + #include "longintrepr.h" + #undef SHIFT + #undef BASE + #undef MASK +#endif +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif +#ifndef __has_cpp_attribute + #define __has_cpp_attribute(x) 0 +#endif +#ifndef CYTHON_RESTRICT + #if defined(__GNUC__) + #define CYTHON_RESTRICT __restrict__ + #elif defined(_MSC_VER) && _MSC_VER >= 1400 + #define CYTHON_RESTRICT __restrict + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_RESTRICT restrict + #else + #define CYTHON_RESTRICT + #endif +#endif +#ifndef CYTHON_UNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_MAYBE_UNUSED_VAR +# if defined(__cplusplus) + template void CYTHON_MAYBE_UNUSED_VAR( const T& ) { } +# else +# define CYTHON_MAYBE_UNUSED_VAR(x) (void)(x) +# endif +#endif +#ifndef CYTHON_NCP_UNUSED +# if CYTHON_COMPILING_IN_CPYTHON +# define CYTHON_NCP_UNUSED +# else +# define CYTHON_NCP_UNUSED CYTHON_UNUSED +# endif +#endif +#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) +#ifdef _MSC_VER + #ifndef _MSC_STDINT_H_ + #if _MSC_VER < 1300 + typedef unsigned char uint8_t; + typedef unsigned int uint32_t; + #else + typedef unsigned __int8 uint8_t; + typedef unsigned __int32 uint32_t; + #endif + #endif +#else + #include +#endif +#ifndef CYTHON_FALLTHROUGH + #if defined(__cplusplus) && __cplusplus >= 201103L + #if __has_cpp_attribute(fallthrough) + #define CYTHON_FALLTHROUGH [[fallthrough]] + #elif __has_cpp_attribute(clang::fallthrough) + #define CYTHON_FALLTHROUGH [[clang::fallthrough]] + #elif __has_cpp_attribute(gnu::fallthrough) + #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_attribute(fallthrough) + #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) + #else + #define CYTHON_FALLTHROUGH + #endif + #endif + #if defined(__clang__ ) && defined(__apple_build_version__) + #if __apple_build_version__ < 7000000 + #undef CYTHON_FALLTHROUGH + #define CYTHON_FALLTHROUGH + #endif + #endif +#endif + +#ifndef CYTHON_INLINE + #if defined(__clang__) + #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) + #elif defined(__GNUC__) + #define CYTHON_INLINE __inline__ + #elif defined(_MSC_VER) + #define CYTHON_INLINE __inline + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_INLINE inline + #else + #define CYTHON_INLINE + #endif +#endif + +#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) + #define Py_OptimizeFlag 0 +#endif +#define __PYX_BUILD_PY_SSIZE_T "n" +#define CYTHON_FORMAT_SSIZE_T "z" +#if PY_MAJOR_VERSION < 3 + #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) + #define __Pyx_DefaultClassType PyClass_Type +#else + #define __Pyx_BUILTIN_MODULE_NAME "builtins" + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) + #define __Pyx_DefaultClassType PyType_Type +#endif +#ifndef Py_TPFLAGS_CHECKTYPES + #define Py_TPFLAGS_CHECKTYPES 0 +#endif +#ifndef Py_TPFLAGS_HAVE_INDEX + #define Py_TPFLAGS_HAVE_INDEX 0 +#endif +#ifndef Py_TPFLAGS_HAVE_NEWBUFFER + #define Py_TPFLAGS_HAVE_NEWBUFFER 0 +#endif +#ifndef Py_TPFLAGS_HAVE_FINALIZE + #define Py_TPFLAGS_HAVE_FINALIZE 0 +#endif +#if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) + #ifndef METH_FASTCALL + #define METH_FASTCALL 0x80 + #endif + typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); + typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, + Py_ssize_t nargs, PyObject *kwnames); +#else + #define __Pyx_PyCFunctionFast _PyCFunctionFast + #define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords +#endif +#if CYTHON_FAST_PYCCALL +#define __Pyx_PyFastCFunction_Check(func)\ + ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS))))) +#else +#define __Pyx_PyFastCFunction_Check(func) 0 +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) + #define PyObject_Malloc(s) PyMem_Malloc(s) + #define PyObject_Free(p) PyMem_Free(p) + #define PyObject_Realloc(p) PyMem_Realloc(p) +#endif +#if CYTHON_COMPILING_IN_PYSTON + #define __Pyx_PyCode_HasFreeVars(co) PyCode_HasFreeVars(co) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) PyFrame_SetLineNumber(frame, lineno) +#else + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) +#endif +#if !CYTHON_FAST_THREAD_STATE || PY_VERSION_HEX < 0x02070000 + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#elif PY_VERSION_HEX >= 0x03060000 + #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() +#elif PY_VERSION_HEX >= 0x03000000 + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#else + #define __Pyx_PyThreadState_Current _PyThreadState_Current +#endif +#if PY_VERSION_HEX < 0x030700A2 && !defined(PyThread_tss_create) && !defined(Py_tss_NEEDS_INIT) +#include "pythread.h" +#define Py_tss_NEEDS_INIT 0 +typedef int Py_tss_t; +static CYTHON_INLINE int PyThread_tss_create(Py_tss_t *key) { + *key = PyThread_create_key(); + return 0; // PyThread_create_key reports success always +} +static CYTHON_INLINE Py_tss_t * PyThread_tss_alloc(void) { + Py_tss_t *key = (Py_tss_t *)PyObject_Malloc(sizeof(Py_tss_t)); + *key = Py_tss_NEEDS_INIT; + return key; +} +static CYTHON_INLINE void PyThread_tss_free(Py_tss_t *key) { + PyObject_Free(key); +} +static CYTHON_INLINE int PyThread_tss_is_created(Py_tss_t *key) { + return *key != Py_tss_NEEDS_INIT; +} +static CYTHON_INLINE void PyThread_tss_delete(Py_tss_t *key) { + PyThread_delete_key(*key); + *key = Py_tss_NEEDS_INIT; +} +static CYTHON_INLINE int PyThread_tss_set(Py_tss_t *key, void *value) { + return PyThread_set_key_value(*key, value); +} +static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { + return PyThread_get_key_value(*key); +} +#endif // TSS (Thread Specific Storage) API +#if CYTHON_COMPILING_IN_CPYTHON || defined(_PyDict_NewPresized) +#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) +#else +#define __Pyx_PyDict_NewPresized(n) PyDict_New() +#endif +#if PY_MAJOR_VERSION >= 3 || CYTHON_FUTURE_DIVISION + #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) +#else + #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 && CYTHON_USE_UNICODE_INTERNALS +#define __Pyx_PyDict_GetItemStr(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) +#else +#define __Pyx_PyDict_GetItemStr(dict, name) PyDict_GetItem(dict, name) +#endif +#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) + #define CYTHON_PEP393_ENABLED 1 + #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ + 0 : _PyUnicode_Ready((PyObject *)(op))) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) + #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u) + #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) + #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, ch) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) +#else + #define CYTHON_PEP393_ENABLED 0 + #define PyUnicode_1BYTE_KIND 1 + #define PyUnicode_2BYTE_KIND 2 + #define PyUnicode_4BYTE_KIND 4 + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(Py_UNICODE) == 2) ? 65535 : 1114111) + #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE)) + #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((Py_UNICODE*)d)[i] = ch) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) +#endif +#if CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) +#else + #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ + PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) + #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyByteArray_Check) + #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Format) + #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) +#endif +#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) +#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) +#else + #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) +#endif +#if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) + #define PyObject_ASCII(o) PyObject_Repr(o) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBaseString_Type PyUnicode_Type + #define PyStringObject PyUnicodeObject + #define PyString_Type PyUnicode_Type + #define PyString_Check PyUnicode_Check + #define PyString_CheckExact PyUnicode_CheckExact +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) + #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) +#else + #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) + #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) +#endif +#ifndef PySet_CheckExact + #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) +#endif +#if CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) +#else + #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyIntObject PyLongObject + #define PyInt_Type PyLong_Type + #define PyInt_Check(op) PyLong_Check(op) + #define PyInt_CheckExact(op) PyLong_CheckExact(op) + #define PyInt_FromString PyLong_FromString + #define PyInt_FromUnicode PyLong_FromUnicode + #define PyInt_FromLong PyLong_FromLong + #define PyInt_FromSize_t PyLong_FromSize_t + #define PyInt_FromSsize_t PyLong_FromSsize_t + #define PyInt_AsLong PyLong_AsLong + #define PyInt_AS_LONG PyLong_AS_LONG + #define PyInt_AsSsize_t PyLong_AsSsize_t + #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask + #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask + #define PyNumber_Int PyNumber_Long +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBoolObject PyLongObject +#endif +#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY + #ifndef PyUnicode_InternFromString + #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) + #endif +#endif +#if PY_VERSION_HEX < 0x030200A4 + typedef long Py_hash_t; + #define __Pyx_PyInt_FromHash_t PyInt_FromLong + #define __Pyx_PyInt_AsHash_t PyInt_AsLong +#else + #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t + #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : (Py_INCREF(func), func)) +#else + #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass) +#endif +#if CYTHON_USE_ASYNC_SLOTS + #if PY_VERSION_HEX >= 0x030500B1 + #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods + #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) + #else + #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) + #endif +#else + #define __Pyx_PyType_AsAsync(obj) NULL +#endif +#ifndef __Pyx_PyAsyncMethodsStruct + typedef struct { + unaryfunc am_await; + unaryfunc am_aiter; + unaryfunc am_anext; + } __Pyx_PyAsyncMethodsStruct; +#endif + +#if defined(WIN32) || defined(MS_WINDOWS) + #define _USE_MATH_DEFINES +#endif +#include +#ifdef NAN +#define __PYX_NAN() ((float) NAN) +#else +static CYTHON_INLINE float __PYX_NAN() { + float value; + memset(&value, 0xFF, sizeof(value)); + return value; +} +#endif +#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) +#define __Pyx_truncl trunc +#else +#define __Pyx_truncl truncl +#endif + + +#define __PYX_ERR(f_index, lineno, Ln_error) \ +{ \ + __pyx_filename = __pyx_f[f_index]; __pyx_lineno = lineno; __pyx_clineno = __LINE__; goto Ln_error; \ +} + +#ifndef __PYX_EXTERN_C + #ifdef __cplusplus + #define __PYX_EXTERN_C extern "C" + #else + #define __PYX_EXTERN_C extern + #endif +#endif + +#define __PYX_HAVE__mesh_core_cython +#define __PYX_HAVE_API__mesh_core_cython +/* Early includes */ +#include +#include +#include "numpy/arrayobject.h" +#include "numpy/ufuncobject.h" +#include "ios" +#include "new" +#include "stdexcept" +#include "typeinfo" +#include +#include "mesh_core.h" +#ifdef _OPENMP +#include +#endif /* _OPENMP */ + +#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) +#define CYTHON_WITHOUT_ASSERTIONS +#endif + +typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; + const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; + +#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0 +#define __PYX_DEFAULT_STRING_ENCODING "" +#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString +#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#define __Pyx_uchar_cast(c) ((unsigned char)c) +#define __Pyx_long_cast(x) ((long)x) +#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ + (sizeof(type) < sizeof(Py_ssize_t)) ||\ + (sizeof(type) > sizeof(Py_ssize_t) &&\ + likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX) &&\ + (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ + v == (type)PY_SSIZE_T_MIN))) ||\ + (sizeof(type) == sizeof(Py_ssize_t) &&\ + (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX))) ) +#if defined (__cplusplus) && __cplusplus >= 201103L + #include + #define __Pyx_sst_abs(value) std::abs(value) +#elif SIZEOF_INT >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) abs(value) +#elif SIZEOF_LONG >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) labs(value) +#elif defined (_MSC_VER) + #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define __Pyx_sst_abs(value) llabs(value) +#elif defined (__GNUC__) + #define __Pyx_sst_abs(value) __builtin_llabs(value) +#else + #define __Pyx_sst_abs(value) ((value<0) ? -value : value) +#endif +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); +#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s)) +#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) +#define __Pyx_PyBytes_FromString PyBytes_FromString +#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); +#if PY_MAJOR_VERSION < 3 + #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#else + #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize +#endif +#define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyObject_AsWritableString(s) ((char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) +#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) +#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) +#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) +#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) +static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) { + const Py_UNICODE *u_end = u; + while (*u_end++) ; + return (size_t)(u_end - u - 1); +} +#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) +#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode +#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode +#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) +#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) +#define __Pyx_PyBool_FromLong(b) ((b) ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False)) +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); +#define __Pyx_PySequence_Tuple(obj)\ + (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); +#if CYTHON_ASSUME_SAFE_MACROS +#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) +#else +#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) +#endif +#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) +#if PY_MAJOR_VERSION >= 3 +#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) +#else +#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) +#endif +#define __Pyx_PyNumber_Float(x) (PyFloat_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Float(x)) +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII +static int __Pyx_sys_getdefaultencoding_not_ascii; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + PyObject* ascii_chars_u = NULL; + PyObject* ascii_chars_b = NULL; + const char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + if (strcmp(default_encoding_c, "ascii") == 0) { + __Pyx_sys_getdefaultencoding_not_ascii = 0; + } else { + char ascii_chars[128]; + int c; + for (c = 0; c < 128; c++) { + ascii_chars[c] = c; + } + __Pyx_sys_getdefaultencoding_not_ascii = 1; + ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); + if (!ascii_chars_u) goto bad; + ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); + if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { + PyErr_Format( + PyExc_ValueError, + "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", + default_encoding_c); + goto bad; + } + Py_DECREF(ascii_chars_u); + Py_DECREF(ascii_chars_b); + } + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + Py_XDECREF(ascii_chars_u); + Py_XDECREF(ascii_chars_b); + return -1; +} +#endif +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) +#else +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +static char* __PYX_DEFAULT_STRING_ENCODING; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c)); + if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; + strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + return -1; +} +#endif +#endif + + +/* Test for GCC > 2.95 */ +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) + #define likely(x) __builtin_expect(!!(x), 1) + #define unlikely(x) __builtin_expect(!!(x), 0) +#else /* !__GNUC__ or GCC < 2.95 */ + #define likely(x) (x) + #define unlikely(x) (x) +#endif /* __GNUC__ */ +static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } + +static PyObject *__pyx_m = NULL; +static PyObject *__pyx_d; +static PyObject *__pyx_b; +static PyObject *__pyx_cython_runtime; +static PyObject *__pyx_empty_tuple; +static PyObject *__pyx_empty_bytes; +static PyObject *__pyx_empty_unicode; +static int __pyx_lineno; +static int __pyx_clineno = 0; +static const char * __pyx_cfilenm= __FILE__; +static const char *__pyx_filename; + +/* Header.proto */ +#if !defined(CYTHON_CCOMPLEX) + #if defined(__cplusplus) + #define CYTHON_CCOMPLEX 1 + #elif defined(_Complex_I) + #define CYTHON_CCOMPLEX 1 + #else + #define CYTHON_CCOMPLEX 0 + #endif +#endif +#if CYTHON_CCOMPLEX + #ifdef __cplusplus + #include + #else + #include + #endif +#endif +#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__) + #undef _Complex_I + #define _Complex_I 1.0fj +#endif + + +static const char *__pyx_f[] = { + "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx", + "__init__.pxd", + "stringsource", + "type.pxd", +}; +/* BufferFormatStructs.proto */ +#define IS_UNSIGNED(type) (((type) -1) > 0) +struct __Pyx_StructField_; +#define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0) +typedef struct { + const char* name; + struct __Pyx_StructField_* fields; + size_t size; + size_t arraysize[8]; + int ndim; + char typegroup; + char is_unsigned; + int flags; +} __Pyx_TypeInfo; +typedef struct __Pyx_StructField_ { + __Pyx_TypeInfo* type; + const char* name; + size_t offset; +} __Pyx_StructField; +typedef struct { + __Pyx_StructField* field; + size_t parent_offset; +} __Pyx_BufFmt_StackElem; +typedef struct { + __Pyx_StructField root; + __Pyx_BufFmt_StackElem* head; + size_t fmt_offset; + size_t new_count, enc_count; + size_t struct_alignment; + int is_complex; + char enc_type; + char new_packmode; + char enc_packmode; + char is_valid_array; +} __Pyx_BufFmt_Context; + + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":730 + * # in Cython to enable them only on the right systems. + * + * ctypedef npy_int8 int8_t # <<<<<<<<<<<<<< + * ctypedef npy_int16 int16_t + * ctypedef npy_int32 int32_t + */ +typedef npy_int8 __pyx_t_5numpy_int8_t; + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":731 + * + * ctypedef npy_int8 int8_t + * ctypedef npy_int16 int16_t # <<<<<<<<<<<<<< + * ctypedef npy_int32 int32_t + * ctypedef npy_int64 int64_t + */ +typedef npy_int16 __pyx_t_5numpy_int16_t; + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":732 + * ctypedef npy_int8 int8_t + * ctypedef npy_int16 int16_t + * ctypedef npy_int32 int32_t # <<<<<<<<<<<<<< + * ctypedef npy_int64 int64_t + * #ctypedef npy_int96 int96_t + */ +typedef npy_int32 __pyx_t_5numpy_int32_t; + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":733 + * ctypedef npy_int16 int16_t + * ctypedef npy_int32 int32_t + * ctypedef npy_int64 int64_t # <<<<<<<<<<<<<< + * #ctypedef npy_int96 int96_t + * #ctypedef npy_int128 int128_t + */ +typedef npy_int64 __pyx_t_5numpy_int64_t; + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":737 + * #ctypedef npy_int128 int128_t + * + * ctypedef npy_uint8 uint8_t # <<<<<<<<<<<<<< + * ctypedef npy_uint16 uint16_t + * ctypedef npy_uint32 uint32_t + */ +typedef npy_uint8 __pyx_t_5numpy_uint8_t; + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":738 + * + * ctypedef npy_uint8 uint8_t + * ctypedef npy_uint16 uint16_t # <<<<<<<<<<<<<< + * ctypedef npy_uint32 uint32_t + * ctypedef npy_uint64 uint64_t + */ +typedef npy_uint16 __pyx_t_5numpy_uint16_t; + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":739 + * ctypedef npy_uint8 uint8_t + * ctypedef npy_uint16 uint16_t + * ctypedef npy_uint32 uint32_t # <<<<<<<<<<<<<< + * ctypedef npy_uint64 uint64_t + * #ctypedef npy_uint96 uint96_t + */ +typedef npy_uint32 __pyx_t_5numpy_uint32_t; + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":740 + * ctypedef npy_uint16 uint16_t + * ctypedef npy_uint32 uint32_t + * ctypedef npy_uint64 uint64_t # <<<<<<<<<<<<<< + * #ctypedef npy_uint96 uint96_t + * #ctypedef npy_uint128 uint128_t + */ +typedef npy_uint64 __pyx_t_5numpy_uint64_t; + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":744 + * #ctypedef npy_uint128 uint128_t + * + * ctypedef npy_float32 float32_t # <<<<<<<<<<<<<< + * ctypedef npy_float64 float64_t + * #ctypedef npy_float80 float80_t + */ +typedef npy_float32 __pyx_t_5numpy_float32_t; + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":745 + * + * ctypedef npy_float32 float32_t + * ctypedef npy_float64 float64_t # <<<<<<<<<<<<<< + * #ctypedef npy_float80 float80_t + * #ctypedef npy_float128 float128_t + */ +typedef npy_float64 __pyx_t_5numpy_float64_t; + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":754 + * # The int types are mapped a bit surprising -- + * # numpy.int corresponds to 'l' and numpy.long to 'q' + * ctypedef npy_long int_t # <<<<<<<<<<<<<< + * ctypedef npy_longlong long_t + * ctypedef npy_longlong longlong_t + */ +typedef npy_long __pyx_t_5numpy_int_t; + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":755 + * # numpy.int corresponds to 'l' and numpy.long to 'q' + * ctypedef npy_long int_t + * ctypedef npy_longlong long_t # <<<<<<<<<<<<<< + * ctypedef npy_longlong longlong_t + * + */ +typedef npy_longlong __pyx_t_5numpy_long_t; + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":756 + * ctypedef npy_long int_t + * ctypedef npy_longlong long_t + * ctypedef npy_longlong longlong_t # <<<<<<<<<<<<<< + * + * ctypedef npy_ulong uint_t + */ +typedef npy_longlong __pyx_t_5numpy_longlong_t; + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":758 + * ctypedef npy_longlong longlong_t + * + * ctypedef npy_ulong uint_t # <<<<<<<<<<<<<< + * ctypedef npy_ulonglong ulong_t + * ctypedef npy_ulonglong ulonglong_t + */ +typedef npy_ulong __pyx_t_5numpy_uint_t; + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":759 + * + * ctypedef npy_ulong uint_t + * ctypedef npy_ulonglong ulong_t # <<<<<<<<<<<<<< + * ctypedef npy_ulonglong ulonglong_t + * + */ +typedef npy_ulonglong __pyx_t_5numpy_ulong_t; + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":760 + * ctypedef npy_ulong uint_t + * ctypedef npy_ulonglong ulong_t + * ctypedef npy_ulonglong ulonglong_t # <<<<<<<<<<<<<< + * + * ctypedef npy_intp intp_t + */ +typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t; + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":762 + * ctypedef npy_ulonglong ulonglong_t + * + * ctypedef npy_intp intp_t # <<<<<<<<<<<<<< + * ctypedef npy_uintp uintp_t + * + */ +typedef npy_intp __pyx_t_5numpy_intp_t; + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":763 + * + * ctypedef npy_intp intp_t + * ctypedef npy_uintp uintp_t # <<<<<<<<<<<<<< + * + * ctypedef npy_double float_t + */ +typedef npy_uintp __pyx_t_5numpy_uintp_t; + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":765 + * ctypedef npy_uintp uintp_t + * + * ctypedef npy_double float_t # <<<<<<<<<<<<<< + * ctypedef npy_double double_t + * ctypedef npy_longdouble longdouble_t + */ +typedef npy_double __pyx_t_5numpy_float_t; + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":766 + * + * ctypedef npy_double float_t + * ctypedef npy_double double_t # <<<<<<<<<<<<<< + * ctypedef npy_longdouble longdouble_t + * + */ +typedef npy_double __pyx_t_5numpy_double_t; + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":767 + * ctypedef npy_double float_t + * ctypedef npy_double double_t + * ctypedef npy_longdouble longdouble_t # <<<<<<<<<<<<<< + * + * ctypedef npy_cfloat cfloat_t + */ +typedef npy_longdouble __pyx_t_5numpy_longdouble_t; +/* Declarations.proto */ +#if CYTHON_CCOMPLEX + #ifdef __cplusplus + typedef ::std::complex< float > __pyx_t_float_complex; + #else + typedef float _Complex __pyx_t_float_complex; + #endif +#else + typedef struct { float real, imag; } __pyx_t_float_complex; +#endif +static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float, float); + +/* Declarations.proto */ +#if CYTHON_CCOMPLEX + #ifdef __cplusplus + typedef ::std::complex< double > __pyx_t_double_complex; + #else + typedef double _Complex __pyx_t_double_complex; + #endif +#else + typedef struct { double real, imag; } __pyx_t_double_complex; +#endif +static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double); + + +/*--- Type declarations ---*/ + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":769 + * ctypedef npy_longdouble longdouble_t + * + * ctypedef npy_cfloat cfloat_t # <<<<<<<<<<<<<< + * ctypedef npy_cdouble cdouble_t + * ctypedef npy_clongdouble clongdouble_t + */ +typedef npy_cfloat __pyx_t_5numpy_cfloat_t; + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":770 + * + * ctypedef npy_cfloat cfloat_t + * ctypedef npy_cdouble cdouble_t # <<<<<<<<<<<<<< + * ctypedef npy_clongdouble clongdouble_t + * + */ +typedef npy_cdouble __pyx_t_5numpy_cdouble_t; + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":771 + * ctypedef npy_cfloat cfloat_t + * ctypedef npy_cdouble cdouble_t + * ctypedef npy_clongdouble clongdouble_t # <<<<<<<<<<<<<< + * + * ctypedef npy_cdouble complex_t + */ +typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t; + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":773 + * ctypedef npy_clongdouble clongdouble_t + * + * ctypedef npy_cdouble complex_t # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew1(a): + */ +typedef npy_cdouble __pyx_t_5numpy_complex_t; + +/* --- Runtime support code (head) --- */ +/* Refnanny.proto */ +#ifndef CYTHON_REFNANNY + #define CYTHON_REFNANNY 0 +#endif +#if CYTHON_REFNANNY + typedef struct { + void (*INCREF)(void*, PyObject*, int); + void (*DECREF)(void*, PyObject*, int); + void (*GOTREF)(void*, PyObject*, int); + void (*GIVEREF)(void*, PyObject*, int); + void* (*SetupContext)(const char*, int, const char*); + void (*FinishContext)(void**); + } __Pyx_RefNannyAPIStruct; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); + #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; +#ifdef WITH_THREAD + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + if (acquire_gil) {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ + PyGILState_Release(__pyx_gilstate_save);\ + } else {\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ + } +#else + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) +#endif + #define __Pyx_RefNannyFinishContext()\ + __Pyx_RefNanny->FinishContext(&__pyx_refnanny) + #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0) + #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0) + #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0) + #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0) +#else + #define __Pyx_RefNannyDeclarations + #define __Pyx_RefNannySetupContext(name, acquire_gil) + #define __Pyx_RefNannyFinishContext() + #define __Pyx_INCREF(r) Py_INCREF(r) + #define __Pyx_DECREF(r) Py_DECREF(r) + #define __Pyx_GOTREF(r) + #define __Pyx_GIVEREF(r) + #define __Pyx_XINCREF(r) Py_XINCREF(r) + #define __Pyx_XDECREF(r) Py_XDECREF(r) + #define __Pyx_XGOTREF(r) + #define __Pyx_XGIVEREF(r) +#endif +#define __Pyx_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_XDECREF(tmp);\ + } while (0) +#define __Pyx_DECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_DECREF(tmp);\ + } while (0) +#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) +#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) + +/* RaiseArgTupleInvalid.proto */ +static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, + Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); + +/* RaiseDoubleKeywords.proto */ +static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); + +/* ParseKeywords.proto */ +static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],\ + PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,\ + const char* function_name); + +/* ArgTypeTest.proto */ +#define __Pyx_ArgTypeTest(obj, type, none_allowed, name, exact)\ + ((likely((Py_TYPE(obj) == type) | (none_allowed && (obj == Py_None)))) ? 1 :\ + __Pyx__ArgTypeTest(obj, type, name, exact)) +static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact); + +/* IsLittleEndian.proto */ +static CYTHON_INLINE int __Pyx_Is_Little_Endian(void); + +/* BufferFormatCheck.proto */ +static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts); +static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, + __Pyx_BufFmt_StackElem* stack, + __Pyx_TypeInfo* type); + +/* BufferGetAndValidate.proto */ +#define __Pyx_GetBufferAndValidate(buf, obj, dtype, flags, nd, cast, stack)\ + ((obj == Py_None || obj == NULL) ?\ + (__Pyx_ZeroBuffer(buf), 0) :\ + __Pyx__GetBufferAndValidate(buf, obj, dtype, flags, nd, cast, stack)) +static int __Pyx__GetBufferAndValidate(Py_buffer* buf, PyObject* obj, + __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack); +static void __Pyx_ZeroBuffer(Py_buffer* buf); +static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info); +static Py_ssize_t __Pyx_minusones[] = { -1, -1, -1, -1, -1, -1, -1, -1 }; +static Py_ssize_t __Pyx_zeros[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + +/* PyThreadStateGet.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; +#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; +#define __Pyx_PyErr_Occurred() __pyx_tstate->curexc_type +#else +#define __Pyx_PyThreadState_declare +#define __Pyx_PyThreadState_assign +#define __Pyx_PyErr_Occurred() PyErr_Occurred() +#endif + +/* PyErrFetchRestore.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) +#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) +#else +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#endif +#else +#define __Pyx_PyErr_Clear() PyErr_Clear() +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) +#endif + +/* PyObjectGetAttrStr.proto */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) +#endif + +/* GetBuiltinName.proto */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name); + +/* PyObjectCall.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); +#else +#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) +#endif + +/* RaiseException.proto */ +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); + +/* PyCFunctionFastCall.proto */ +#if CYTHON_FAST_PYCCALL +static CYTHON_INLINE PyObject *__Pyx_PyCFunction_FastCall(PyObject *func, PyObject **args, Py_ssize_t nargs); +#else +#define __Pyx_PyCFunction_FastCall(func, args, nargs) (assert(0), NULL) +#endif + +/* PyFunctionFastCall.proto */ +#if CYTHON_FAST_PYCALL +#define __Pyx_PyFunction_FastCall(func, args, nargs)\ + __Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL) +#if 1 || PY_VERSION_HEX < 0x030600B1 +static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, int nargs, PyObject *kwargs); +#else +#define __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs) _PyFunction_FastCallDict(func, args, nargs, kwargs) +#endif +#endif + +/* PyObjectCallMethO.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); +#endif + +/* PyObjectCallOneArg.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); + +/* DictGetItem.proto */ +#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY +static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key); +#define __Pyx_PyObject_Dict_GetItem(obj, name)\ + (likely(PyDict_CheckExact(obj)) ?\ + __Pyx_PyDict_GetItem(obj, name) : PyObject_GetItem(obj, name)) +#else +#define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key) +#define __Pyx_PyObject_Dict_GetItem(obj, name) PyObject_GetItem(obj, name) +#endif + +/* RaiseTooManyValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); + +/* RaiseNeedMoreValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); + +/* RaiseNoneIterError.proto */ +static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void); + +/* ExtTypeTest.proto */ +static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); + +/* SaveResetException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_ExceptionSave(type, value, tb) __Pyx__ExceptionSave(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#define __Pyx_ExceptionReset(type, value, tb) __Pyx__ExceptionReset(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +#else +#define __Pyx_ExceptionSave(type, value, tb) PyErr_GetExcInfo(type, value, tb) +#define __Pyx_ExceptionReset(type, value, tb) PyErr_SetExcInfo(type, value, tb) +#endif + +/* PyErrExceptionMatches.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) +static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); +#else +#define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) +#endif + +/* GetException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_GetException(type, value, tb) __Pyx__GetException(__pyx_tstate, type, value, tb) +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); +#endif + +/* Import.proto */ +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); + +/* CLineInTraceback.proto */ +#ifdef CYTHON_CLINE_IN_TRACEBACK +#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) +#else +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); +#endif + +/* CodeObjectCache.proto */ +typedef struct { + PyCodeObject* code_object; + int code_line; +} __Pyx_CodeObjectCacheEntry; +struct __Pyx_CodeObjectCache { + int count; + int max_count; + __Pyx_CodeObjectCacheEntry* entries; +}; +static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); +static PyCodeObject *__pyx_find_code_object(int code_line); +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); + +/* AddTraceback.proto */ +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename); + +/* BufferStructDeclare.proto */ +typedef struct { + Py_ssize_t shape, strides, suboffsets; +} __Pyx_Buf_DimInfo; +typedef struct { + size_t refcount; + Py_buffer pybuffer; +} __Pyx_Buffer; +typedef struct { + __Pyx_Buffer *rcbuffer; + char *data; + __Pyx_Buf_DimInfo diminfo[8]; +} __Pyx_LocalBuf_ND; + +#if PY_MAJOR_VERSION < 3 + static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags); + static void __Pyx_ReleaseBuffer(Py_buffer *view); +#else + #define __Pyx_GetBuffer PyObject_GetBuffer + #define __Pyx_ReleaseBuffer PyBuffer_Release +#endif + + +/* RealImag.proto */ +#if CYTHON_CCOMPLEX + #ifdef __cplusplus + #define __Pyx_CREAL(z) ((z).real()) + #define __Pyx_CIMAG(z) ((z).imag()) + #else + #define __Pyx_CREAL(z) (__real__(z)) + #define __Pyx_CIMAG(z) (__imag__(z)) + #endif +#else + #define __Pyx_CREAL(z) ((z).real) + #define __Pyx_CIMAG(z) ((z).imag) +#endif +#if defined(__cplusplus) && CYTHON_CCOMPLEX\ + && (defined(_WIN32) || defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 5 || __GNUC__ == 4 && __GNUC_MINOR__ >= 4 )) || __cplusplus >= 201103) + #define __Pyx_SET_CREAL(z,x) ((z).real(x)) + #define __Pyx_SET_CIMAG(z,y) ((z).imag(y)) +#else + #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x) + #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y) +#endif + +/* Arithmetic.proto */ +#if CYTHON_CCOMPLEX + #define __Pyx_c_eq_float(a, b) ((a)==(b)) + #define __Pyx_c_sum_float(a, b) ((a)+(b)) + #define __Pyx_c_diff_float(a, b) ((a)-(b)) + #define __Pyx_c_prod_float(a, b) ((a)*(b)) + #define __Pyx_c_quot_float(a, b) ((a)/(b)) + #define __Pyx_c_neg_float(a) (-(a)) + #ifdef __cplusplus + #define __Pyx_c_is_zero_float(z) ((z)==(float)0) + #define __Pyx_c_conj_float(z) (::std::conj(z)) + #if 1 + #define __Pyx_c_abs_float(z) (::std::abs(z)) + #define __Pyx_c_pow_float(a, b) (::std::pow(a, b)) + #endif + #else + #define __Pyx_c_is_zero_float(z) ((z)==0) + #define __Pyx_c_conj_float(z) (conjf(z)) + #if 1 + #define __Pyx_c_abs_float(z) (cabsf(z)) + #define __Pyx_c_pow_float(a, b) (cpowf(a, b)) + #endif + #endif +#else + static CYTHON_INLINE int __Pyx_c_eq_float(__pyx_t_float_complex, __pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sum_float(__pyx_t_float_complex, __pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_diff_float(__pyx_t_float_complex, __pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prod_float(__pyx_t_float_complex, __pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quot_float(__pyx_t_float_complex, __pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_neg_float(__pyx_t_float_complex); + static CYTHON_INLINE int __Pyx_c_is_zero_float(__pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conj_float(__pyx_t_float_complex); + #if 1 + static CYTHON_INLINE float __Pyx_c_abs_float(__pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_pow_float(__pyx_t_float_complex, __pyx_t_float_complex); + #endif +#endif + +/* Arithmetic.proto */ +#if CYTHON_CCOMPLEX + #define __Pyx_c_eq_double(a, b) ((a)==(b)) + #define __Pyx_c_sum_double(a, b) ((a)+(b)) + #define __Pyx_c_diff_double(a, b) ((a)-(b)) + #define __Pyx_c_prod_double(a, b) ((a)*(b)) + #define __Pyx_c_quot_double(a, b) ((a)/(b)) + #define __Pyx_c_neg_double(a) (-(a)) + #ifdef __cplusplus + #define __Pyx_c_is_zero_double(z) ((z)==(double)0) + #define __Pyx_c_conj_double(z) (::std::conj(z)) + #if 1 + #define __Pyx_c_abs_double(z) (::std::abs(z)) + #define __Pyx_c_pow_double(a, b) (::std::pow(a, b)) + #endif + #else + #define __Pyx_c_is_zero_double(z) ((z)==0) + #define __Pyx_c_conj_double(z) (conj(z)) + #if 1 + #define __Pyx_c_abs_double(z) (cabs(z)) + #define __Pyx_c_pow_double(a, b) (cpow(a, b)) + #endif + #endif +#else + static CYTHON_INLINE int __Pyx_c_eq_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg_double(__pyx_t_double_complex); + static CYTHON_INLINE int __Pyx_c_is_zero_double(__pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj_double(__pyx_t_double_complex); + #if 1 + static CYTHON_INLINE double __Pyx_c_abs_double(__pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow_double(__pyx_t_double_complex, __pyx_t_double_complex); + #endif +#endif + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_enum__NPY_TYPES(enum NPY_TYPES value); + +/* CIntFromPy.proto */ +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); + +/* CIntFromPy.proto */ +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); + +/* FastTypeChecks.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); +#else +#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) +#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) +#define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2)) +#endif +#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) + +/* CheckBinaryVersion.proto */ +static int __Pyx_check_binary_version(void); + +/* PyIdentifierFromString.proto */ +#if !defined(__Pyx_PyIdentifier_FromString) +#if PY_MAJOR_VERSION < 3 + #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s) +#else + #define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s) +#endif +#endif + +/* ModuleImport.proto */ +static PyObject *__Pyx_ImportModule(const char *name); + +/* TypeImport.proto */ +static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict); + +/* InitStrings.proto */ +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); + + +/* Module declarations from 'cpython.buffer' */ + +/* Module declarations from 'libc.string' */ + +/* Module declarations from 'libc.stdio' */ + +/* Module declarations from '__builtin__' */ + +/* Module declarations from 'cpython.type' */ +static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0; + +/* Module declarations from 'cpython' */ + +/* Module declarations from 'cpython.object' */ + +/* Module declarations from 'cpython.ref' */ + +/* Module declarations from 'cpython.mem' */ + +/* Module declarations from 'numpy' */ + +/* Module declarations from 'numpy' */ +static PyTypeObject *__pyx_ptype_5numpy_dtype = 0; +static PyTypeObject *__pyx_ptype_5numpy_flatiter = 0; +static PyTypeObject *__pyx_ptype_5numpy_broadcast = 0; +static PyTypeObject *__pyx_ptype_5numpy_ndarray = 0; +static PyTypeObject *__pyx_ptype_5numpy_ufunc = 0; +static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *, char *, char *, int *); /*proto*/ +static CYTHON_INLINE int __pyx_f_5numpy_import_array(void); /*proto*/ + +/* Module declarations from 'libcpp.string' */ + +/* Module declarations from 'mesh_core_cython' */ +static std::string __pyx_convert_string_from_py_std__in_string(PyObject *); /*proto*/ +static __Pyx_TypeInfo __Pyx_TypeInfo_float = { "float", NULL, sizeof(float), { 0 }, 0, 'R', 0, 0 }; +static __Pyx_TypeInfo __Pyx_TypeInfo_int = { "int", NULL, sizeof(int), { 0 }, 0, IS_UNSIGNED(int) ? 'U' : 'I', IS_UNSIGNED(int), 0 }; +#define __Pyx_MODULE_NAME "mesh_core_cython" +extern int __pyx_module_is_main_mesh_core_cython; +int __pyx_module_is_main_mesh_core_cython = 0; + +/* Implementation of 'mesh_core_cython' */ +static PyObject *__pyx_builtin_ValueError; +static PyObject *__pyx_builtin_range; +static PyObject *__pyx_builtin_RuntimeError; +static PyObject *__pyx_builtin_ImportError; +static const char __pyx_k_c[] = "c"; +static const char __pyx_k_h[] = "h"; +static const char __pyx_k_w[] = "w"; +static const char __pyx_k_np[] = "np"; +static const char __pyx_k_main[] = "__main__"; +static const char __pyx_k_ntri[] = "ntri"; +static const char __pyx_k_nver[] = "nver"; +static const char __pyx_k_test[] = "__test__"; +static const char __pyx_k_image[] = "image"; +static const char __pyx_k_numpy[] = "numpy"; +static const char __pyx_k_range[] = "range"; +static const char __pyx_k_tex_c[] = "tex_c"; +static const char __pyx_k_tex_h[] = "tex_h"; +static const char __pyx_k_tex_w[] = "tex_w"; +static const char __pyx_k_colors[] = "colors"; +static const char __pyx_k_import[] = "__import__"; +static const char __pyx_k_normal[] = "normal"; +static const char __pyx_k_ntexver[] = "ntexver"; +static const char __pyx_k_texture[] = "texture"; +static const char __pyx_k_filename[] = "filename"; +static const char __pyx_k_mtl_name[] = "mtl_name"; +static const char __pyx_k_tex_nver[] = "tex_nver"; +static const char __pyx_k_vertices[] = "vertices"; +static const char __pyx_k_triangles[] = "triangles"; +static const char __pyx_k_uv_coords[] = "uv_coords"; +static const char __pyx_k_ValueError[] = "ValueError"; +static const char __pyx_k_tex_coords[] = "tex_coords"; +static const char __pyx_k_tri_normal[] = "tri_normal"; +static const char __pyx_k_ImportError[] = "ImportError"; +static const char __pyx_k_RuntimeError[] = "RuntimeError"; +static const char __pyx_k_depth_buffer[] = "depth_buffer"; +static const char __pyx_k_mapping_type[] = "mapping_type"; +static const char __pyx_k_tex_triangles[] = "tex_triangles"; +static const char __pyx_k_get_normal_core[] = "get_normal_core"; +static const char __pyx_k_triangle_buffer[] = "triangle_buffer"; +static const char __pyx_k_mesh_core_cython[] = "mesh_core_cython"; +static const char __pyx_k_barycentric_weight[] = "barycentric_weight"; +static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback"; +static const char __pyx_k_render_colors_core[] = "render_colors_core"; +static const char __pyx_k_render_texture_core[] = "render_texture_core"; +static const char __pyx_k_rasterize_triangles_core[] = "rasterize_triangles_core"; +static const char __pyx_k_ndarray_is_not_C_contiguous[] = "ndarray is not C contiguous"; +static const char __pyx_k_numpy_core_multiarray_failed_to[] = "numpy.core.multiarray failed to import"; +static const char __pyx_k_unknown_dtype_code_in_numpy_pxd[] = "unknown dtype code in numpy.pxd (%d)"; +static const char __pyx_k_Format_string_allocated_too_shor[] = "Format string allocated too short, see comment in numpy.pxd"; +static const char __pyx_k_Non_native_byte_order_not_suppor[] = "Non-native byte order not supported"; +static const char __pyx_k_insightface_thirdparty_face3d_me[] = "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx"; +static const char __pyx_k_ndarray_is_not_Fortran_contiguou[] = "ndarray is not Fortran contiguous"; +static const char __pyx_k_numpy_core_umath_failed_to_impor[] = "numpy.core.umath failed to import"; +static const char __pyx_k_write_obj_with_colors_texture_co[] = "write_obj_with_colors_texture_core"; +static const char __pyx_k_Format_string_allocated_too_shor_2[] = "Format string allocated too short."; +static PyObject *__pyx_kp_u_Format_string_allocated_too_shor; +static PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2; +static PyObject *__pyx_n_s_ImportError; +static PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor; +static PyObject *__pyx_n_s_RuntimeError; +static PyObject *__pyx_n_s_ValueError; +static PyObject *__pyx_n_s_barycentric_weight; +static PyObject *__pyx_n_s_c; +static PyObject *__pyx_n_s_cline_in_traceback; +static PyObject *__pyx_n_s_colors; +static PyObject *__pyx_n_s_depth_buffer; +static PyObject *__pyx_n_s_filename; +static PyObject *__pyx_n_s_get_normal_core; +static PyObject *__pyx_n_s_h; +static PyObject *__pyx_n_s_image; +static PyObject *__pyx_n_s_import; +static PyObject *__pyx_kp_s_insightface_thirdparty_face3d_me; +static PyObject *__pyx_n_s_main; +static PyObject *__pyx_n_s_mapping_type; +static PyObject *__pyx_n_s_mesh_core_cython; +static PyObject *__pyx_n_s_mtl_name; +static PyObject *__pyx_kp_u_ndarray_is_not_C_contiguous; +static PyObject *__pyx_kp_u_ndarray_is_not_Fortran_contiguou; +static PyObject *__pyx_n_s_normal; +static PyObject *__pyx_n_s_np; +static PyObject *__pyx_n_s_ntexver; +static PyObject *__pyx_n_s_ntri; +static PyObject *__pyx_n_s_numpy; +static PyObject *__pyx_kp_s_numpy_core_multiarray_failed_to; +static PyObject *__pyx_kp_s_numpy_core_umath_failed_to_impor; +static PyObject *__pyx_n_s_nver; +static PyObject *__pyx_n_s_range; +static PyObject *__pyx_n_s_rasterize_triangles_core; +static PyObject *__pyx_n_s_render_colors_core; +static PyObject *__pyx_n_s_render_texture_core; +static PyObject *__pyx_n_s_test; +static PyObject *__pyx_n_s_tex_c; +static PyObject *__pyx_n_s_tex_coords; +static PyObject *__pyx_n_s_tex_h; +static PyObject *__pyx_n_s_tex_nver; +static PyObject *__pyx_n_s_tex_triangles; +static PyObject *__pyx_n_s_tex_w; +static PyObject *__pyx_n_s_texture; +static PyObject *__pyx_n_s_tri_normal; +static PyObject *__pyx_n_s_triangle_buffer; +static PyObject *__pyx_n_s_triangles; +static PyObject *__pyx_kp_u_unknown_dtype_code_in_numpy_pxd; +static PyObject *__pyx_n_s_uv_coords; +static PyObject *__pyx_n_s_vertices; +static PyObject *__pyx_n_s_w; +static PyObject *__pyx_n_s_write_obj_with_colors_texture_co; +static PyObject *__pyx_pf_16mesh_core_cython_get_normal_core(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_normal, PyArrayObject *__pyx_v_tri_normal, PyArrayObject *__pyx_v_triangles, int __pyx_v_ntri); /* proto */ +static PyObject *__pyx_pf_16mesh_core_cython_2rasterize_triangles_core(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_vertices, PyArrayObject *__pyx_v_triangles, PyArrayObject *__pyx_v_depth_buffer, PyArrayObject *__pyx_v_triangle_buffer, PyArrayObject *__pyx_v_barycentric_weight, int __pyx_v_nver, int __pyx_v_ntri, int __pyx_v_h, int __pyx_v_w); /* proto */ +static PyObject *__pyx_pf_16mesh_core_cython_4render_colors_core(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_image, PyArrayObject *__pyx_v_vertices, PyArrayObject *__pyx_v_triangles, PyArrayObject *__pyx_v_colors, PyArrayObject *__pyx_v_depth_buffer, int __pyx_v_nver, int __pyx_v_ntri, int __pyx_v_h, int __pyx_v_w, int __pyx_v_c); /* proto */ +static PyObject *__pyx_pf_16mesh_core_cython_6render_texture_core(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_image, PyArrayObject *__pyx_v_vertices, PyArrayObject *__pyx_v_triangles, PyArrayObject *__pyx_v_texture, PyArrayObject *__pyx_v_tex_coords, PyArrayObject *__pyx_v_tex_triangles, PyArrayObject *__pyx_v_depth_buffer, int __pyx_v_nver, int __pyx_v_tex_nver, int __pyx_v_ntri, int __pyx_v_h, int __pyx_v_w, int __pyx_v_c, int __pyx_v_tex_h, int __pyx_v_tex_w, int __pyx_v_tex_c, int __pyx_v_mapping_type); /* proto */ +static PyObject *__pyx_pf_16mesh_core_cython_8write_obj_with_colors_texture_core(CYTHON_UNUSED PyObject *__pyx_self, std::string __pyx_v_filename, std::string __pyx_v_mtl_name, PyArrayObject *__pyx_v_vertices, PyArrayObject *__pyx_v_triangles, PyArrayObject *__pyx_v_colors, PyArrayObject *__pyx_v_uv_coords, int __pyx_v_nver, int __pyx_v_ntri, int __pyx_v_ntexver); /* proto */ +static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */ +static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info); /* proto */ +static PyObject *__pyx_tuple_; +static PyObject *__pyx_tuple__2; +static PyObject *__pyx_tuple__3; +static PyObject *__pyx_tuple__4; +static PyObject *__pyx_tuple__5; +static PyObject *__pyx_tuple__6; +static PyObject *__pyx_tuple__7; +static PyObject *__pyx_tuple__8; +static PyObject *__pyx_tuple__9; +static PyObject *__pyx_tuple__10; +static PyObject *__pyx_tuple__12; +static PyObject *__pyx_tuple__14; +static PyObject *__pyx_tuple__16; +static PyObject *__pyx_tuple__18; +static PyObject *__pyx_codeobj__11; +static PyObject *__pyx_codeobj__13; +static PyObject *__pyx_codeobj__15; +static PyObject *__pyx_codeobj__17; +static PyObject *__pyx_codeobj__19; +/* Late includes */ + +/* "mesh_core_cython.pyx":40 + * int nver, int ntri, int ntexver) + * + * def get_normal_core(np.ndarray[float, ndim=2, mode = "c"] normal not None, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] tri_normal not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_16mesh_core_cython_1get_normal_core(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static PyMethodDef __pyx_mdef_16mesh_core_cython_1get_normal_core = {"get_normal_core", (PyCFunction)__pyx_pw_16mesh_core_cython_1get_normal_core, METH_VARARGS|METH_KEYWORDS, 0}; +static PyObject *__pyx_pw_16mesh_core_cython_1get_normal_core(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyArrayObject *__pyx_v_normal = 0; + PyArrayObject *__pyx_v_tri_normal = 0; + PyArrayObject *__pyx_v_triangles = 0; + int __pyx_v_ntri; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("get_normal_core (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_normal,&__pyx_n_s_tri_normal,&__pyx_n_s_triangles,&__pyx_n_s_ntri,0}; + PyObject* values[4] = {0,0,0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_normal)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_tri_normal)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("get_normal_core", 1, 4, 4, 1); __PYX_ERR(0, 40, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_triangles)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("get_normal_core", 1, 4, 4, 2); __PYX_ERR(0, 40, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ntri)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("get_normal_core", 1, 4, 4, 3); __PYX_ERR(0, 40, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "get_normal_core") < 0)) __PYX_ERR(0, 40, __pyx_L3_error) + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 4) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + } + __pyx_v_normal = ((PyArrayObject *)values[0]); + __pyx_v_tri_normal = ((PyArrayObject *)values[1]); + __pyx_v_triangles = ((PyArrayObject *)values[2]); + __pyx_v_ntri = __Pyx_PyInt_As_int(values[3]); if (unlikely((__pyx_v_ntri == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 43, __pyx_L3_error) + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("get_normal_core", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 40, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("mesh_core_cython.get_normal_core", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_normal), __pyx_ptype_5numpy_ndarray, 0, "normal", 0))) __PYX_ERR(0, 40, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_tri_normal), __pyx_ptype_5numpy_ndarray, 0, "tri_normal", 0))) __PYX_ERR(0, 41, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_triangles), __pyx_ptype_5numpy_ndarray, 0, "triangles", 0))) __PYX_ERR(0, 42, __pyx_L1_error) + __pyx_r = __pyx_pf_16mesh_core_cython_get_normal_core(__pyx_self, __pyx_v_normal, __pyx_v_tri_normal, __pyx_v_triangles, __pyx_v_ntri); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_16mesh_core_cython_get_normal_core(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_normal, PyArrayObject *__pyx_v_tri_normal, PyArrayObject *__pyx_v_triangles, int __pyx_v_ntri) { + __Pyx_LocalBuf_ND __pyx_pybuffernd_normal; + __Pyx_Buffer __pyx_pybuffer_normal; + __Pyx_LocalBuf_ND __pyx_pybuffernd_tri_normal; + __Pyx_Buffer __pyx_pybuffer_tri_normal; + __Pyx_LocalBuf_ND __pyx_pybuffernd_triangles; + __Pyx_Buffer __pyx_pybuffer_triangles; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("get_normal_core", 0); + __pyx_pybuffer_normal.pybuffer.buf = NULL; + __pyx_pybuffer_normal.refcount = 0; + __pyx_pybuffernd_normal.data = NULL; + __pyx_pybuffernd_normal.rcbuffer = &__pyx_pybuffer_normal; + __pyx_pybuffer_tri_normal.pybuffer.buf = NULL; + __pyx_pybuffer_tri_normal.refcount = 0; + __pyx_pybuffernd_tri_normal.data = NULL; + __pyx_pybuffernd_tri_normal.rcbuffer = &__pyx_pybuffer_tri_normal; + __pyx_pybuffer_triangles.pybuffer.buf = NULL; + __pyx_pybuffer_triangles.refcount = 0; + __pyx_pybuffernd_triangles.data = NULL; + __pyx_pybuffernd_triangles.rcbuffer = &__pyx_pybuffer_triangles; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_normal.rcbuffer->pybuffer, (PyObject*)__pyx_v_normal, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 40, __pyx_L1_error) + } + __pyx_pybuffernd_normal.diminfo[0].strides = __pyx_pybuffernd_normal.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_normal.diminfo[0].shape = __pyx_pybuffernd_normal.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_normal.diminfo[1].strides = __pyx_pybuffernd_normal.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_normal.diminfo[1].shape = __pyx_pybuffernd_normal.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_tri_normal.rcbuffer->pybuffer, (PyObject*)__pyx_v_tri_normal, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 40, __pyx_L1_error) + } + __pyx_pybuffernd_tri_normal.diminfo[0].strides = __pyx_pybuffernd_tri_normal.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_tri_normal.diminfo[0].shape = __pyx_pybuffernd_tri_normal.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_tri_normal.diminfo[1].strides = __pyx_pybuffernd_tri_normal.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_tri_normal.diminfo[1].shape = __pyx_pybuffernd_tri_normal.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer, (PyObject*)__pyx_v_triangles, &__Pyx_TypeInfo_int, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 40, __pyx_L1_error) + } + __pyx_pybuffernd_triangles.diminfo[0].strides = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_triangles.diminfo[0].shape = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_triangles.diminfo[1].strides = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_triangles.diminfo[1].shape = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.shape[1]; + + /* "mesh_core_cython.pyx":45 + * int ntri + * ): + * _get_normal_core( # <<<<<<<<<<<<<< + * np.PyArray_DATA(normal), np.PyArray_DATA(tri_normal), np.PyArray_DATA(triangles), + * ntri) + */ + _get_normal_core(((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_normal))), ((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_tri_normal))), ((int *)PyArray_DATA(((PyArrayObject *)__pyx_v_triangles))), __pyx_v_ntri); + + /* "mesh_core_cython.pyx":40 + * int nver, int ntri, int ntexver) + * + * def get_normal_core(np.ndarray[float, ndim=2, mode = "c"] normal not None, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] tri_normal not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_normal.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tri_normal.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer); + __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} + __Pyx_AddTraceback("mesh_core_cython.get_normal_core", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + goto __pyx_L2; + __pyx_L0:; + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_normal.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tri_normal.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer); + __pyx_L2:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "mesh_core_cython.pyx":49 + * ntri) + * + * def rasterize_triangles_core( # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_16mesh_core_cython_3rasterize_triangles_core(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static PyMethodDef __pyx_mdef_16mesh_core_cython_3rasterize_triangles_core = {"rasterize_triangles_core", (PyCFunction)__pyx_pw_16mesh_core_cython_3rasterize_triangles_core, METH_VARARGS|METH_KEYWORDS, 0}; +static PyObject *__pyx_pw_16mesh_core_cython_3rasterize_triangles_core(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyArrayObject *__pyx_v_vertices = 0; + PyArrayObject *__pyx_v_triangles = 0; + PyArrayObject *__pyx_v_depth_buffer = 0; + PyArrayObject *__pyx_v_triangle_buffer = 0; + PyArrayObject *__pyx_v_barycentric_weight = 0; + int __pyx_v_nver; + int __pyx_v_ntri; + int __pyx_v_h; + int __pyx_v_w; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("rasterize_triangles_core (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_vertices,&__pyx_n_s_triangles,&__pyx_n_s_depth_buffer,&__pyx_n_s_triangle_buffer,&__pyx_n_s_barycentric_weight,&__pyx_n_s_nver,&__pyx_n_s_ntri,&__pyx_n_s_h,&__pyx_n_s_w,0}; + PyObject* values[9] = {0,0,0,0,0,0,0,0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8); + CYTHON_FALLTHROUGH; + case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7); + CYTHON_FALLTHROUGH; + case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6); + CYTHON_FALLTHROUGH; + case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5); + CYTHON_FALLTHROUGH; + case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_vertices)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_triangles)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("rasterize_triangles_core", 1, 9, 9, 1); __PYX_ERR(0, 49, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_depth_buffer)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("rasterize_triangles_core", 1, 9, 9, 2); __PYX_ERR(0, 49, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_triangle_buffer)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("rasterize_triangles_core", 1, 9, 9, 3); __PYX_ERR(0, 49, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 4: + if (likely((values[4] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_barycentric_weight)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("rasterize_triangles_core", 1, 9, 9, 4); __PYX_ERR(0, 49, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 5: + if (likely((values[5] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_nver)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("rasterize_triangles_core", 1, 9, 9, 5); __PYX_ERR(0, 49, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 6: + if (likely((values[6] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ntri)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("rasterize_triangles_core", 1, 9, 9, 6); __PYX_ERR(0, 49, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 7: + if (likely((values[7] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_h)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("rasterize_triangles_core", 1, 9, 9, 7); __PYX_ERR(0, 49, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 8: + if (likely((values[8] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_w)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("rasterize_triangles_core", 1, 9, 9, 8); __PYX_ERR(0, 49, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "rasterize_triangles_core") < 0)) __PYX_ERR(0, 49, __pyx_L3_error) + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 9) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + values[4] = PyTuple_GET_ITEM(__pyx_args, 4); + values[5] = PyTuple_GET_ITEM(__pyx_args, 5); + values[6] = PyTuple_GET_ITEM(__pyx_args, 6); + values[7] = PyTuple_GET_ITEM(__pyx_args, 7); + values[8] = PyTuple_GET_ITEM(__pyx_args, 8); + } + __pyx_v_vertices = ((PyArrayObject *)values[0]); + __pyx_v_triangles = ((PyArrayObject *)values[1]); + __pyx_v_depth_buffer = ((PyArrayObject *)values[2]); + __pyx_v_triangle_buffer = ((PyArrayObject *)values[3]); + __pyx_v_barycentric_weight = ((PyArrayObject *)values[4]); + __pyx_v_nver = __Pyx_PyInt_As_int(values[5]); if (unlikely((__pyx_v_nver == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 55, __pyx_L3_error) + __pyx_v_ntri = __Pyx_PyInt_As_int(values[6]); if (unlikely((__pyx_v_ntri == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 55, __pyx_L3_error) + __pyx_v_h = __Pyx_PyInt_As_int(values[7]); if (unlikely((__pyx_v_h == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 56, __pyx_L3_error) + __pyx_v_w = __Pyx_PyInt_As_int(values[8]); if (unlikely((__pyx_v_w == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 56, __pyx_L3_error) + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("rasterize_triangles_core", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 49, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("mesh_core_cython.rasterize_triangles_core", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_vertices), __pyx_ptype_5numpy_ndarray, 0, "vertices", 0))) __PYX_ERR(0, 50, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_triangles), __pyx_ptype_5numpy_ndarray, 0, "triangles", 0))) __PYX_ERR(0, 51, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_depth_buffer), __pyx_ptype_5numpy_ndarray, 0, "depth_buffer", 0))) __PYX_ERR(0, 52, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_triangle_buffer), __pyx_ptype_5numpy_ndarray, 0, "triangle_buffer", 0))) __PYX_ERR(0, 53, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_barycentric_weight), __pyx_ptype_5numpy_ndarray, 0, "barycentric_weight", 0))) __PYX_ERR(0, 54, __pyx_L1_error) + __pyx_r = __pyx_pf_16mesh_core_cython_2rasterize_triangles_core(__pyx_self, __pyx_v_vertices, __pyx_v_triangles, __pyx_v_depth_buffer, __pyx_v_triangle_buffer, __pyx_v_barycentric_weight, __pyx_v_nver, __pyx_v_ntri, __pyx_v_h, __pyx_v_w); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_16mesh_core_cython_2rasterize_triangles_core(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_vertices, PyArrayObject *__pyx_v_triangles, PyArrayObject *__pyx_v_depth_buffer, PyArrayObject *__pyx_v_triangle_buffer, PyArrayObject *__pyx_v_barycentric_weight, int __pyx_v_nver, int __pyx_v_ntri, int __pyx_v_h, int __pyx_v_w) { + __Pyx_LocalBuf_ND __pyx_pybuffernd_barycentric_weight; + __Pyx_Buffer __pyx_pybuffer_barycentric_weight; + __Pyx_LocalBuf_ND __pyx_pybuffernd_depth_buffer; + __Pyx_Buffer __pyx_pybuffer_depth_buffer; + __Pyx_LocalBuf_ND __pyx_pybuffernd_triangle_buffer; + __Pyx_Buffer __pyx_pybuffer_triangle_buffer; + __Pyx_LocalBuf_ND __pyx_pybuffernd_triangles; + __Pyx_Buffer __pyx_pybuffer_triangles; + __Pyx_LocalBuf_ND __pyx_pybuffernd_vertices; + __Pyx_Buffer __pyx_pybuffer_vertices; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("rasterize_triangles_core", 0); + __pyx_pybuffer_vertices.pybuffer.buf = NULL; + __pyx_pybuffer_vertices.refcount = 0; + __pyx_pybuffernd_vertices.data = NULL; + __pyx_pybuffernd_vertices.rcbuffer = &__pyx_pybuffer_vertices; + __pyx_pybuffer_triangles.pybuffer.buf = NULL; + __pyx_pybuffer_triangles.refcount = 0; + __pyx_pybuffernd_triangles.data = NULL; + __pyx_pybuffernd_triangles.rcbuffer = &__pyx_pybuffer_triangles; + __pyx_pybuffer_depth_buffer.pybuffer.buf = NULL; + __pyx_pybuffer_depth_buffer.refcount = 0; + __pyx_pybuffernd_depth_buffer.data = NULL; + __pyx_pybuffernd_depth_buffer.rcbuffer = &__pyx_pybuffer_depth_buffer; + __pyx_pybuffer_triangle_buffer.pybuffer.buf = NULL; + __pyx_pybuffer_triangle_buffer.refcount = 0; + __pyx_pybuffernd_triangle_buffer.data = NULL; + __pyx_pybuffernd_triangle_buffer.rcbuffer = &__pyx_pybuffer_triangle_buffer; + __pyx_pybuffer_barycentric_weight.pybuffer.buf = NULL; + __pyx_pybuffer_barycentric_weight.refcount = 0; + __pyx_pybuffernd_barycentric_weight.data = NULL; + __pyx_pybuffernd_barycentric_weight.rcbuffer = &__pyx_pybuffer_barycentric_weight; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertices.rcbuffer->pybuffer, (PyObject*)__pyx_v_vertices, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 49, __pyx_L1_error) + } + __pyx_pybuffernd_vertices.diminfo[0].strides = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_vertices.diminfo[0].shape = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_vertices.diminfo[1].strides = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_vertices.diminfo[1].shape = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer, (PyObject*)__pyx_v_triangles, &__Pyx_TypeInfo_int, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 49, __pyx_L1_error) + } + __pyx_pybuffernd_triangles.diminfo[0].strides = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_triangles.diminfo[0].shape = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_triangles.diminfo[1].strides = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_triangles.diminfo[1].shape = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer, (PyObject*)__pyx_v_depth_buffer, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 49, __pyx_L1_error) + } + __pyx_pybuffernd_depth_buffer.diminfo[0].strides = __pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_depth_buffer.diminfo[0].shape = __pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_depth_buffer.diminfo[1].strides = __pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_depth_buffer.diminfo[1].shape = __pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_triangle_buffer.rcbuffer->pybuffer, (PyObject*)__pyx_v_triangle_buffer, &__Pyx_TypeInfo_int, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 49, __pyx_L1_error) + } + __pyx_pybuffernd_triangle_buffer.diminfo[0].strides = __pyx_pybuffernd_triangle_buffer.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_triangle_buffer.diminfo[0].shape = __pyx_pybuffernd_triangle_buffer.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_triangle_buffer.diminfo[1].strides = __pyx_pybuffernd_triangle_buffer.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_triangle_buffer.diminfo[1].shape = __pyx_pybuffernd_triangle_buffer.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_barycentric_weight.rcbuffer->pybuffer, (PyObject*)__pyx_v_barycentric_weight, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 49, __pyx_L1_error) + } + __pyx_pybuffernd_barycentric_weight.diminfo[0].strides = __pyx_pybuffernd_barycentric_weight.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_barycentric_weight.diminfo[0].shape = __pyx_pybuffernd_barycentric_weight.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_barycentric_weight.diminfo[1].strides = __pyx_pybuffernd_barycentric_weight.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_barycentric_weight.diminfo[1].shape = __pyx_pybuffernd_barycentric_weight.rcbuffer->pybuffer.shape[1]; + + /* "mesh_core_cython.pyx":58 + * int h, int w + * ): + * _rasterize_triangles_core( # <<<<<<<<<<<<<< + * np.PyArray_DATA(vertices), np.PyArray_DATA(triangles), + * np.PyArray_DATA(depth_buffer), np.PyArray_DATA(triangle_buffer), np.PyArray_DATA(barycentric_weight), + */ + _rasterize_triangles_core(((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_vertices))), ((int *)PyArray_DATA(((PyArrayObject *)__pyx_v_triangles))), ((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_depth_buffer))), ((int *)PyArray_DATA(((PyArrayObject *)__pyx_v_triangle_buffer))), ((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_barycentric_weight))), __pyx_v_nver, __pyx_v_ntri, __pyx_v_h, __pyx_v_w); + + /* "mesh_core_cython.pyx":49 + * ntri) + * + * def rasterize_triangles_core( # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_barycentric_weight.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_triangle_buffer.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertices.rcbuffer->pybuffer); + __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} + __Pyx_AddTraceback("mesh_core_cython.rasterize_triangles_core", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + goto __pyx_L2; + __pyx_L0:; + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_barycentric_weight.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_triangle_buffer.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertices.rcbuffer->pybuffer); + __pyx_L2:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "mesh_core_cython.pyx":64 + * h, w) + * + * def render_colors_core(np.ndarray[float, ndim=3, mode = "c"] image not None, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_16mesh_core_cython_5render_colors_core(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static PyMethodDef __pyx_mdef_16mesh_core_cython_5render_colors_core = {"render_colors_core", (PyCFunction)__pyx_pw_16mesh_core_cython_5render_colors_core, METH_VARARGS|METH_KEYWORDS, 0}; +static PyObject *__pyx_pw_16mesh_core_cython_5render_colors_core(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyArrayObject *__pyx_v_image = 0; + PyArrayObject *__pyx_v_vertices = 0; + PyArrayObject *__pyx_v_triangles = 0; + PyArrayObject *__pyx_v_colors = 0; + PyArrayObject *__pyx_v_depth_buffer = 0; + int __pyx_v_nver; + int __pyx_v_ntri; + int __pyx_v_h; + int __pyx_v_w; + int __pyx_v_c; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("render_colors_core (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_image,&__pyx_n_s_vertices,&__pyx_n_s_triangles,&__pyx_n_s_colors,&__pyx_n_s_depth_buffer,&__pyx_n_s_nver,&__pyx_n_s_ntri,&__pyx_n_s_h,&__pyx_n_s_w,&__pyx_n_s_c,0}; + PyObject* values[10] = {0,0,0,0,0,0,0,0,0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 10: values[9] = PyTuple_GET_ITEM(__pyx_args, 9); + CYTHON_FALLTHROUGH; + case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8); + CYTHON_FALLTHROUGH; + case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7); + CYTHON_FALLTHROUGH; + case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6); + CYTHON_FALLTHROUGH; + case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5); + CYTHON_FALLTHROUGH; + case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_image)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_vertices)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("render_colors_core", 1, 10, 10, 1); __PYX_ERR(0, 64, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_triangles)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("render_colors_core", 1, 10, 10, 2); __PYX_ERR(0, 64, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_colors)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("render_colors_core", 1, 10, 10, 3); __PYX_ERR(0, 64, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 4: + if (likely((values[4] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_depth_buffer)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("render_colors_core", 1, 10, 10, 4); __PYX_ERR(0, 64, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 5: + if (likely((values[5] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_nver)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("render_colors_core", 1, 10, 10, 5); __PYX_ERR(0, 64, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 6: + if (likely((values[6] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ntri)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("render_colors_core", 1, 10, 10, 6); __PYX_ERR(0, 64, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 7: + if (likely((values[7] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_h)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("render_colors_core", 1, 10, 10, 7); __PYX_ERR(0, 64, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 8: + if (likely((values[8] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_w)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("render_colors_core", 1, 10, 10, 8); __PYX_ERR(0, 64, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 9: + if (likely((values[9] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_c)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("render_colors_core", 1, 10, 10, 9); __PYX_ERR(0, 64, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "render_colors_core") < 0)) __PYX_ERR(0, 64, __pyx_L3_error) + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 10) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + values[4] = PyTuple_GET_ITEM(__pyx_args, 4); + values[5] = PyTuple_GET_ITEM(__pyx_args, 5); + values[6] = PyTuple_GET_ITEM(__pyx_args, 6); + values[7] = PyTuple_GET_ITEM(__pyx_args, 7); + values[8] = PyTuple_GET_ITEM(__pyx_args, 8); + values[9] = PyTuple_GET_ITEM(__pyx_args, 9); + } + __pyx_v_image = ((PyArrayObject *)values[0]); + __pyx_v_vertices = ((PyArrayObject *)values[1]); + __pyx_v_triangles = ((PyArrayObject *)values[2]); + __pyx_v_colors = ((PyArrayObject *)values[3]); + __pyx_v_depth_buffer = ((PyArrayObject *)values[4]); + __pyx_v_nver = __Pyx_PyInt_As_int(values[5]); if (unlikely((__pyx_v_nver == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 69, __pyx_L3_error) + __pyx_v_ntri = __Pyx_PyInt_As_int(values[6]); if (unlikely((__pyx_v_ntri == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 69, __pyx_L3_error) + __pyx_v_h = __Pyx_PyInt_As_int(values[7]); if (unlikely((__pyx_v_h == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 70, __pyx_L3_error) + __pyx_v_w = __Pyx_PyInt_As_int(values[8]); if (unlikely((__pyx_v_w == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 70, __pyx_L3_error) + __pyx_v_c = __Pyx_PyInt_As_int(values[9]); if (unlikely((__pyx_v_c == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 70, __pyx_L3_error) + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("render_colors_core", 1, 10, 10, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 64, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("mesh_core_cython.render_colors_core", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_image), __pyx_ptype_5numpy_ndarray, 0, "image", 0))) __PYX_ERR(0, 64, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_vertices), __pyx_ptype_5numpy_ndarray, 0, "vertices", 0))) __PYX_ERR(0, 65, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_triangles), __pyx_ptype_5numpy_ndarray, 0, "triangles", 0))) __PYX_ERR(0, 66, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_colors), __pyx_ptype_5numpy_ndarray, 0, "colors", 0))) __PYX_ERR(0, 67, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_depth_buffer), __pyx_ptype_5numpy_ndarray, 0, "depth_buffer", 0))) __PYX_ERR(0, 68, __pyx_L1_error) + __pyx_r = __pyx_pf_16mesh_core_cython_4render_colors_core(__pyx_self, __pyx_v_image, __pyx_v_vertices, __pyx_v_triangles, __pyx_v_colors, __pyx_v_depth_buffer, __pyx_v_nver, __pyx_v_ntri, __pyx_v_h, __pyx_v_w, __pyx_v_c); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_16mesh_core_cython_4render_colors_core(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_image, PyArrayObject *__pyx_v_vertices, PyArrayObject *__pyx_v_triangles, PyArrayObject *__pyx_v_colors, PyArrayObject *__pyx_v_depth_buffer, int __pyx_v_nver, int __pyx_v_ntri, int __pyx_v_h, int __pyx_v_w, int __pyx_v_c) { + __Pyx_LocalBuf_ND __pyx_pybuffernd_colors; + __Pyx_Buffer __pyx_pybuffer_colors; + __Pyx_LocalBuf_ND __pyx_pybuffernd_depth_buffer; + __Pyx_Buffer __pyx_pybuffer_depth_buffer; + __Pyx_LocalBuf_ND __pyx_pybuffernd_image; + __Pyx_Buffer __pyx_pybuffer_image; + __Pyx_LocalBuf_ND __pyx_pybuffernd_triangles; + __Pyx_Buffer __pyx_pybuffer_triangles; + __Pyx_LocalBuf_ND __pyx_pybuffernd_vertices; + __Pyx_Buffer __pyx_pybuffer_vertices; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("render_colors_core", 0); + __pyx_pybuffer_image.pybuffer.buf = NULL; + __pyx_pybuffer_image.refcount = 0; + __pyx_pybuffernd_image.data = NULL; + __pyx_pybuffernd_image.rcbuffer = &__pyx_pybuffer_image; + __pyx_pybuffer_vertices.pybuffer.buf = NULL; + __pyx_pybuffer_vertices.refcount = 0; + __pyx_pybuffernd_vertices.data = NULL; + __pyx_pybuffernd_vertices.rcbuffer = &__pyx_pybuffer_vertices; + __pyx_pybuffer_triangles.pybuffer.buf = NULL; + __pyx_pybuffer_triangles.refcount = 0; + __pyx_pybuffernd_triangles.data = NULL; + __pyx_pybuffernd_triangles.rcbuffer = &__pyx_pybuffer_triangles; + __pyx_pybuffer_colors.pybuffer.buf = NULL; + __pyx_pybuffer_colors.refcount = 0; + __pyx_pybuffernd_colors.data = NULL; + __pyx_pybuffernd_colors.rcbuffer = &__pyx_pybuffer_colors; + __pyx_pybuffer_depth_buffer.pybuffer.buf = NULL; + __pyx_pybuffer_depth_buffer.refcount = 0; + __pyx_pybuffernd_depth_buffer.data = NULL; + __pyx_pybuffernd_depth_buffer.rcbuffer = &__pyx_pybuffer_depth_buffer; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_image.rcbuffer->pybuffer, (PyObject*)__pyx_v_image, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 3, 0, __pyx_stack) == -1)) __PYX_ERR(0, 64, __pyx_L1_error) + } + __pyx_pybuffernd_image.diminfo[0].strides = __pyx_pybuffernd_image.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_image.diminfo[0].shape = __pyx_pybuffernd_image.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_image.diminfo[1].strides = __pyx_pybuffernd_image.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_image.diminfo[1].shape = __pyx_pybuffernd_image.rcbuffer->pybuffer.shape[1]; __pyx_pybuffernd_image.diminfo[2].strides = __pyx_pybuffernd_image.rcbuffer->pybuffer.strides[2]; __pyx_pybuffernd_image.diminfo[2].shape = __pyx_pybuffernd_image.rcbuffer->pybuffer.shape[2]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertices.rcbuffer->pybuffer, (PyObject*)__pyx_v_vertices, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 64, __pyx_L1_error) + } + __pyx_pybuffernd_vertices.diminfo[0].strides = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_vertices.diminfo[0].shape = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_vertices.diminfo[1].strides = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_vertices.diminfo[1].shape = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer, (PyObject*)__pyx_v_triangles, &__Pyx_TypeInfo_int, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 64, __pyx_L1_error) + } + __pyx_pybuffernd_triangles.diminfo[0].strides = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_triangles.diminfo[0].shape = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_triangles.diminfo[1].strides = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_triangles.diminfo[1].shape = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_colors.rcbuffer->pybuffer, (PyObject*)__pyx_v_colors, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 64, __pyx_L1_error) + } + __pyx_pybuffernd_colors.diminfo[0].strides = __pyx_pybuffernd_colors.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_colors.diminfo[0].shape = __pyx_pybuffernd_colors.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_colors.diminfo[1].strides = __pyx_pybuffernd_colors.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_colors.diminfo[1].shape = __pyx_pybuffernd_colors.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer, (PyObject*)__pyx_v_depth_buffer, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 64, __pyx_L1_error) + } + __pyx_pybuffernd_depth_buffer.diminfo[0].strides = __pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_depth_buffer.diminfo[0].shape = __pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_depth_buffer.diminfo[1].strides = __pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_depth_buffer.diminfo[1].shape = __pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer.shape[1]; + + /* "mesh_core_cython.pyx":72 + * int h, int w, int c + * ): + * _render_colors_core( # <<<<<<<<<<<<<< + * np.PyArray_DATA(image), np.PyArray_DATA(vertices), np.PyArray_DATA(triangles), + * np.PyArray_DATA(colors), + */ + _render_colors_core(((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_image))), ((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_vertices))), ((int *)PyArray_DATA(((PyArrayObject *)__pyx_v_triangles))), ((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_colors))), ((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_depth_buffer))), __pyx_v_nver, __pyx_v_ntri, __pyx_v_h, __pyx_v_w, __pyx_v_c); + + /* "mesh_core_cython.pyx":64 + * h, w) + * + * def render_colors_core(np.ndarray[float, ndim=3, mode = "c"] image not None, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_colors.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_image.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertices.rcbuffer->pybuffer); + __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} + __Pyx_AddTraceback("mesh_core_cython.render_colors_core", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + goto __pyx_L2; + __pyx_L0:; + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_colors.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_image.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertices.rcbuffer->pybuffer); + __pyx_L2:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "mesh_core_cython.pyx":79 + * h, w, c) + * + * def render_texture_core(np.ndarray[float, ndim=3, mode = "c"] image not None, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_16mesh_core_cython_7render_texture_core(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static PyMethodDef __pyx_mdef_16mesh_core_cython_7render_texture_core = {"render_texture_core", (PyCFunction)__pyx_pw_16mesh_core_cython_7render_texture_core, METH_VARARGS|METH_KEYWORDS, 0}; +static PyObject *__pyx_pw_16mesh_core_cython_7render_texture_core(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyArrayObject *__pyx_v_image = 0; + PyArrayObject *__pyx_v_vertices = 0; + PyArrayObject *__pyx_v_triangles = 0; + PyArrayObject *__pyx_v_texture = 0; + PyArrayObject *__pyx_v_tex_coords = 0; + PyArrayObject *__pyx_v_tex_triangles = 0; + PyArrayObject *__pyx_v_depth_buffer = 0; + int __pyx_v_nver; + int __pyx_v_tex_nver; + int __pyx_v_ntri; + int __pyx_v_h; + int __pyx_v_w; + int __pyx_v_c; + int __pyx_v_tex_h; + int __pyx_v_tex_w; + int __pyx_v_tex_c; + int __pyx_v_mapping_type; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("render_texture_core (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_image,&__pyx_n_s_vertices,&__pyx_n_s_triangles,&__pyx_n_s_texture,&__pyx_n_s_tex_coords,&__pyx_n_s_tex_triangles,&__pyx_n_s_depth_buffer,&__pyx_n_s_nver,&__pyx_n_s_tex_nver,&__pyx_n_s_ntri,&__pyx_n_s_h,&__pyx_n_s_w,&__pyx_n_s_c,&__pyx_n_s_tex_h,&__pyx_n_s_tex_w,&__pyx_n_s_tex_c,&__pyx_n_s_mapping_type,0}; + PyObject* values[17] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 17: values[16] = PyTuple_GET_ITEM(__pyx_args, 16); + CYTHON_FALLTHROUGH; + case 16: values[15] = PyTuple_GET_ITEM(__pyx_args, 15); + CYTHON_FALLTHROUGH; + case 15: values[14] = PyTuple_GET_ITEM(__pyx_args, 14); + CYTHON_FALLTHROUGH; + case 14: values[13] = PyTuple_GET_ITEM(__pyx_args, 13); + CYTHON_FALLTHROUGH; + case 13: values[12] = PyTuple_GET_ITEM(__pyx_args, 12); + CYTHON_FALLTHROUGH; + case 12: values[11] = PyTuple_GET_ITEM(__pyx_args, 11); + CYTHON_FALLTHROUGH; + case 11: values[10] = PyTuple_GET_ITEM(__pyx_args, 10); + CYTHON_FALLTHROUGH; + case 10: values[9] = PyTuple_GET_ITEM(__pyx_args, 9); + CYTHON_FALLTHROUGH; + case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8); + CYTHON_FALLTHROUGH; + case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7); + CYTHON_FALLTHROUGH; + case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6); + CYTHON_FALLTHROUGH; + case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5); + CYTHON_FALLTHROUGH; + case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_image)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_vertices)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 1); __PYX_ERR(0, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_triangles)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 2); __PYX_ERR(0, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_texture)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 3); __PYX_ERR(0, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 4: + if (likely((values[4] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_tex_coords)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 4); __PYX_ERR(0, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 5: + if (likely((values[5] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_tex_triangles)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 5); __PYX_ERR(0, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 6: + if (likely((values[6] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_depth_buffer)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 6); __PYX_ERR(0, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 7: + if (likely((values[7] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_nver)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 7); __PYX_ERR(0, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 8: + if (likely((values[8] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_tex_nver)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 8); __PYX_ERR(0, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 9: + if (likely((values[9] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ntri)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 9); __PYX_ERR(0, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 10: + if (likely((values[10] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_h)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 10); __PYX_ERR(0, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 11: + if (likely((values[11] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_w)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 11); __PYX_ERR(0, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 12: + if (likely((values[12] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_c)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 12); __PYX_ERR(0, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 13: + if (likely((values[13] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_tex_h)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 13); __PYX_ERR(0, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 14: + if (likely((values[14] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_tex_w)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 14); __PYX_ERR(0, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 15: + if (likely((values[15] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_tex_c)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 15); __PYX_ERR(0, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 16: + if (likely((values[16] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_mapping_type)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 16); __PYX_ERR(0, 79, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "render_texture_core") < 0)) __PYX_ERR(0, 79, __pyx_L3_error) + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 17) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + values[4] = PyTuple_GET_ITEM(__pyx_args, 4); + values[5] = PyTuple_GET_ITEM(__pyx_args, 5); + values[6] = PyTuple_GET_ITEM(__pyx_args, 6); + values[7] = PyTuple_GET_ITEM(__pyx_args, 7); + values[8] = PyTuple_GET_ITEM(__pyx_args, 8); + values[9] = PyTuple_GET_ITEM(__pyx_args, 9); + values[10] = PyTuple_GET_ITEM(__pyx_args, 10); + values[11] = PyTuple_GET_ITEM(__pyx_args, 11); + values[12] = PyTuple_GET_ITEM(__pyx_args, 12); + values[13] = PyTuple_GET_ITEM(__pyx_args, 13); + values[14] = PyTuple_GET_ITEM(__pyx_args, 14); + values[15] = PyTuple_GET_ITEM(__pyx_args, 15); + values[16] = PyTuple_GET_ITEM(__pyx_args, 16); + } + __pyx_v_image = ((PyArrayObject *)values[0]); + __pyx_v_vertices = ((PyArrayObject *)values[1]); + __pyx_v_triangles = ((PyArrayObject *)values[2]); + __pyx_v_texture = ((PyArrayObject *)values[3]); + __pyx_v_tex_coords = ((PyArrayObject *)values[4]); + __pyx_v_tex_triangles = ((PyArrayObject *)values[5]); + __pyx_v_depth_buffer = ((PyArrayObject *)values[6]); + __pyx_v_nver = __Pyx_PyInt_As_int(values[7]); if (unlikely((__pyx_v_nver == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 86, __pyx_L3_error) + __pyx_v_tex_nver = __Pyx_PyInt_As_int(values[8]); if (unlikely((__pyx_v_tex_nver == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 86, __pyx_L3_error) + __pyx_v_ntri = __Pyx_PyInt_As_int(values[9]); if (unlikely((__pyx_v_ntri == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 86, __pyx_L3_error) + __pyx_v_h = __Pyx_PyInt_As_int(values[10]); if (unlikely((__pyx_v_h == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 87, __pyx_L3_error) + __pyx_v_w = __Pyx_PyInt_As_int(values[11]); if (unlikely((__pyx_v_w == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 87, __pyx_L3_error) + __pyx_v_c = __Pyx_PyInt_As_int(values[12]); if (unlikely((__pyx_v_c == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 87, __pyx_L3_error) + __pyx_v_tex_h = __Pyx_PyInt_As_int(values[13]); if (unlikely((__pyx_v_tex_h == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 88, __pyx_L3_error) + __pyx_v_tex_w = __Pyx_PyInt_As_int(values[14]); if (unlikely((__pyx_v_tex_w == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 88, __pyx_L3_error) + __pyx_v_tex_c = __Pyx_PyInt_As_int(values[15]); if (unlikely((__pyx_v_tex_c == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 88, __pyx_L3_error) + __pyx_v_mapping_type = __Pyx_PyInt_As_int(values[16]); if (unlikely((__pyx_v_mapping_type == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 89, __pyx_L3_error) + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 79, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("mesh_core_cython.render_texture_core", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_image), __pyx_ptype_5numpy_ndarray, 0, "image", 0))) __PYX_ERR(0, 79, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_vertices), __pyx_ptype_5numpy_ndarray, 0, "vertices", 0))) __PYX_ERR(0, 80, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_triangles), __pyx_ptype_5numpy_ndarray, 0, "triangles", 0))) __PYX_ERR(0, 81, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_texture), __pyx_ptype_5numpy_ndarray, 0, "texture", 0))) __PYX_ERR(0, 82, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_tex_coords), __pyx_ptype_5numpy_ndarray, 0, "tex_coords", 0))) __PYX_ERR(0, 83, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_tex_triangles), __pyx_ptype_5numpy_ndarray, 0, "tex_triangles", 0))) __PYX_ERR(0, 84, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_depth_buffer), __pyx_ptype_5numpy_ndarray, 0, "depth_buffer", 0))) __PYX_ERR(0, 85, __pyx_L1_error) + __pyx_r = __pyx_pf_16mesh_core_cython_6render_texture_core(__pyx_self, __pyx_v_image, __pyx_v_vertices, __pyx_v_triangles, __pyx_v_texture, __pyx_v_tex_coords, __pyx_v_tex_triangles, __pyx_v_depth_buffer, __pyx_v_nver, __pyx_v_tex_nver, __pyx_v_ntri, __pyx_v_h, __pyx_v_w, __pyx_v_c, __pyx_v_tex_h, __pyx_v_tex_w, __pyx_v_tex_c, __pyx_v_mapping_type); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_16mesh_core_cython_6render_texture_core(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_image, PyArrayObject *__pyx_v_vertices, PyArrayObject *__pyx_v_triangles, PyArrayObject *__pyx_v_texture, PyArrayObject *__pyx_v_tex_coords, PyArrayObject *__pyx_v_tex_triangles, PyArrayObject *__pyx_v_depth_buffer, int __pyx_v_nver, int __pyx_v_tex_nver, int __pyx_v_ntri, int __pyx_v_h, int __pyx_v_w, int __pyx_v_c, int __pyx_v_tex_h, int __pyx_v_tex_w, int __pyx_v_tex_c, int __pyx_v_mapping_type) { + __Pyx_LocalBuf_ND __pyx_pybuffernd_depth_buffer; + __Pyx_Buffer __pyx_pybuffer_depth_buffer; + __Pyx_LocalBuf_ND __pyx_pybuffernd_image; + __Pyx_Buffer __pyx_pybuffer_image; + __Pyx_LocalBuf_ND __pyx_pybuffernd_tex_coords; + __Pyx_Buffer __pyx_pybuffer_tex_coords; + __Pyx_LocalBuf_ND __pyx_pybuffernd_tex_triangles; + __Pyx_Buffer __pyx_pybuffer_tex_triangles; + __Pyx_LocalBuf_ND __pyx_pybuffernd_texture; + __Pyx_Buffer __pyx_pybuffer_texture; + __Pyx_LocalBuf_ND __pyx_pybuffernd_triangles; + __Pyx_Buffer __pyx_pybuffer_triangles; + __Pyx_LocalBuf_ND __pyx_pybuffernd_vertices; + __Pyx_Buffer __pyx_pybuffer_vertices; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("render_texture_core", 0); + __pyx_pybuffer_image.pybuffer.buf = NULL; + __pyx_pybuffer_image.refcount = 0; + __pyx_pybuffernd_image.data = NULL; + __pyx_pybuffernd_image.rcbuffer = &__pyx_pybuffer_image; + __pyx_pybuffer_vertices.pybuffer.buf = NULL; + __pyx_pybuffer_vertices.refcount = 0; + __pyx_pybuffernd_vertices.data = NULL; + __pyx_pybuffernd_vertices.rcbuffer = &__pyx_pybuffer_vertices; + __pyx_pybuffer_triangles.pybuffer.buf = NULL; + __pyx_pybuffer_triangles.refcount = 0; + __pyx_pybuffernd_triangles.data = NULL; + __pyx_pybuffernd_triangles.rcbuffer = &__pyx_pybuffer_triangles; + __pyx_pybuffer_texture.pybuffer.buf = NULL; + __pyx_pybuffer_texture.refcount = 0; + __pyx_pybuffernd_texture.data = NULL; + __pyx_pybuffernd_texture.rcbuffer = &__pyx_pybuffer_texture; + __pyx_pybuffer_tex_coords.pybuffer.buf = NULL; + __pyx_pybuffer_tex_coords.refcount = 0; + __pyx_pybuffernd_tex_coords.data = NULL; + __pyx_pybuffernd_tex_coords.rcbuffer = &__pyx_pybuffer_tex_coords; + __pyx_pybuffer_tex_triangles.pybuffer.buf = NULL; + __pyx_pybuffer_tex_triangles.refcount = 0; + __pyx_pybuffernd_tex_triangles.data = NULL; + __pyx_pybuffernd_tex_triangles.rcbuffer = &__pyx_pybuffer_tex_triangles; + __pyx_pybuffer_depth_buffer.pybuffer.buf = NULL; + __pyx_pybuffer_depth_buffer.refcount = 0; + __pyx_pybuffernd_depth_buffer.data = NULL; + __pyx_pybuffernd_depth_buffer.rcbuffer = &__pyx_pybuffer_depth_buffer; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_image.rcbuffer->pybuffer, (PyObject*)__pyx_v_image, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 3, 0, __pyx_stack) == -1)) __PYX_ERR(0, 79, __pyx_L1_error) + } + __pyx_pybuffernd_image.diminfo[0].strides = __pyx_pybuffernd_image.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_image.diminfo[0].shape = __pyx_pybuffernd_image.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_image.diminfo[1].strides = __pyx_pybuffernd_image.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_image.diminfo[1].shape = __pyx_pybuffernd_image.rcbuffer->pybuffer.shape[1]; __pyx_pybuffernd_image.diminfo[2].strides = __pyx_pybuffernd_image.rcbuffer->pybuffer.strides[2]; __pyx_pybuffernd_image.diminfo[2].shape = __pyx_pybuffernd_image.rcbuffer->pybuffer.shape[2]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertices.rcbuffer->pybuffer, (PyObject*)__pyx_v_vertices, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 79, __pyx_L1_error) + } + __pyx_pybuffernd_vertices.diminfo[0].strides = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_vertices.diminfo[0].shape = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_vertices.diminfo[1].strides = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_vertices.diminfo[1].shape = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer, (PyObject*)__pyx_v_triangles, &__Pyx_TypeInfo_int, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 79, __pyx_L1_error) + } + __pyx_pybuffernd_triangles.diminfo[0].strides = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_triangles.diminfo[0].shape = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_triangles.diminfo[1].strides = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_triangles.diminfo[1].shape = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_texture.rcbuffer->pybuffer, (PyObject*)__pyx_v_texture, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 3, 0, __pyx_stack) == -1)) __PYX_ERR(0, 79, __pyx_L1_error) + } + __pyx_pybuffernd_texture.diminfo[0].strides = __pyx_pybuffernd_texture.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_texture.diminfo[0].shape = __pyx_pybuffernd_texture.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_texture.diminfo[1].strides = __pyx_pybuffernd_texture.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_texture.diminfo[1].shape = __pyx_pybuffernd_texture.rcbuffer->pybuffer.shape[1]; __pyx_pybuffernd_texture.diminfo[2].strides = __pyx_pybuffernd_texture.rcbuffer->pybuffer.strides[2]; __pyx_pybuffernd_texture.diminfo[2].shape = __pyx_pybuffernd_texture.rcbuffer->pybuffer.shape[2]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_tex_coords.rcbuffer->pybuffer, (PyObject*)__pyx_v_tex_coords, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 79, __pyx_L1_error) + } + __pyx_pybuffernd_tex_coords.diminfo[0].strides = __pyx_pybuffernd_tex_coords.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_tex_coords.diminfo[0].shape = __pyx_pybuffernd_tex_coords.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_tex_coords.diminfo[1].strides = __pyx_pybuffernd_tex_coords.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_tex_coords.diminfo[1].shape = __pyx_pybuffernd_tex_coords.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_tex_triangles.rcbuffer->pybuffer, (PyObject*)__pyx_v_tex_triangles, &__Pyx_TypeInfo_int, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 79, __pyx_L1_error) + } + __pyx_pybuffernd_tex_triangles.diminfo[0].strides = __pyx_pybuffernd_tex_triangles.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_tex_triangles.diminfo[0].shape = __pyx_pybuffernd_tex_triangles.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_tex_triangles.diminfo[1].strides = __pyx_pybuffernd_tex_triangles.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_tex_triangles.diminfo[1].shape = __pyx_pybuffernd_tex_triangles.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer, (PyObject*)__pyx_v_depth_buffer, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 79, __pyx_L1_error) + } + __pyx_pybuffernd_depth_buffer.diminfo[0].strides = __pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_depth_buffer.diminfo[0].shape = __pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_depth_buffer.diminfo[1].strides = __pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_depth_buffer.diminfo[1].shape = __pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer.shape[1]; + + /* "mesh_core_cython.pyx":91 + * int mapping_type + * ): + * _render_texture_core( # <<<<<<<<<<<<<< + * np.PyArray_DATA(image), np.PyArray_DATA(vertices), np.PyArray_DATA(triangles), + * np.PyArray_DATA(texture), np.PyArray_DATA(tex_coords), np.PyArray_DATA(tex_triangles), + */ + _render_texture_core(((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_image))), ((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_vertices))), ((int *)PyArray_DATA(((PyArrayObject *)__pyx_v_triangles))), ((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_texture))), ((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_tex_coords))), ((int *)PyArray_DATA(((PyArrayObject *)__pyx_v_tex_triangles))), ((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_depth_buffer))), __pyx_v_nver, __pyx_v_tex_nver, __pyx_v_ntri, __pyx_v_h, __pyx_v_w, __pyx_v_c, __pyx_v_tex_h, __pyx_v_tex_w, __pyx_v_tex_c, __pyx_v_mapping_type); + + /* "mesh_core_cython.pyx":79 + * h, w, c) + * + * def render_texture_core(np.ndarray[float, ndim=3, mode = "c"] image not None, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_image.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tex_coords.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tex_triangles.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_texture.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertices.rcbuffer->pybuffer); + __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} + __Pyx_AddTraceback("mesh_core_cython.render_texture_core", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + goto __pyx_L2; + __pyx_L0:; + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_image.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tex_coords.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tex_triangles.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_texture.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertices.rcbuffer->pybuffer); + __pyx_L2:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "mesh_core_cython.pyx":100 + * mapping_type) + * + * def write_obj_with_colors_texture_core(string filename, string mtl_name, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_16mesh_core_cython_9write_obj_with_colors_texture_core(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static PyMethodDef __pyx_mdef_16mesh_core_cython_9write_obj_with_colors_texture_core = {"write_obj_with_colors_texture_core", (PyCFunction)__pyx_pw_16mesh_core_cython_9write_obj_with_colors_texture_core, METH_VARARGS|METH_KEYWORDS, 0}; +static PyObject *__pyx_pw_16mesh_core_cython_9write_obj_with_colors_texture_core(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + std::string __pyx_v_filename; + std::string __pyx_v_mtl_name; + PyArrayObject *__pyx_v_vertices = 0; + PyArrayObject *__pyx_v_triangles = 0; + PyArrayObject *__pyx_v_colors = 0; + PyArrayObject *__pyx_v_uv_coords = 0; + int __pyx_v_nver; + int __pyx_v_ntri; + int __pyx_v_ntexver; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("write_obj_with_colors_texture_core (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_filename,&__pyx_n_s_mtl_name,&__pyx_n_s_vertices,&__pyx_n_s_triangles,&__pyx_n_s_colors,&__pyx_n_s_uv_coords,&__pyx_n_s_nver,&__pyx_n_s_ntri,&__pyx_n_s_ntexver,0}; + PyObject* values[9] = {0,0,0,0,0,0,0,0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8); + CYTHON_FALLTHROUGH; + case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7); + CYTHON_FALLTHROUGH; + case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6); + CYTHON_FALLTHROUGH; + case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5); + CYTHON_FALLTHROUGH; + case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_filename)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_mtl_name)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("write_obj_with_colors_texture_core", 1, 9, 9, 1); __PYX_ERR(0, 100, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_vertices)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("write_obj_with_colors_texture_core", 1, 9, 9, 2); __PYX_ERR(0, 100, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_triangles)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("write_obj_with_colors_texture_core", 1, 9, 9, 3); __PYX_ERR(0, 100, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 4: + if (likely((values[4] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_colors)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("write_obj_with_colors_texture_core", 1, 9, 9, 4); __PYX_ERR(0, 100, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 5: + if (likely((values[5] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_uv_coords)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("write_obj_with_colors_texture_core", 1, 9, 9, 5); __PYX_ERR(0, 100, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 6: + if (likely((values[6] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_nver)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("write_obj_with_colors_texture_core", 1, 9, 9, 6); __PYX_ERR(0, 100, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 7: + if (likely((values[7] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ntri)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("write_obj_with_colors_texture_core", 1, 9, 9, 7); __PYX_ERR(0, 100, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 8: + if (likely((values[8] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ntexver)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("write_obj_with_colors_texture_core", 1, 9, 9, 8); __PYX_ERR(0, 100, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "write_obj_with_colors_texture_core") < 0)) __PYX_ERR(0, 100, __pyx_L3_error) + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 9) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + values[4] = PyTuple_GET_ITEM(__pyx_args, 4); + values[5] = PyTuple_GET_ITEM(__pyx_args, 5); + values[6] = PyTuple_GET_ITEM(__pyx_args, 6); + values[7] = PyTuple_GET_ITEM(__pyx_args, 7); + values[8] = PyTuple_GET_ITEM(__pyx_args, 8); + } + __pyx_v_filename = __pyx_convert_string_from_py_std__in_string(values[0]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 100, __pyx_L3_error) + __pyx_v_mtl_name = __pyx_convert_string_from_py_std__in_string(values[1]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 100, __pyx_L3_error) + __pyx_v_vertices = ((PyArrayObject *)values[2]); + __pyx_v_triangles = ((PyArrayObject *)values[3]); + __pyx_v_colors = ((PyArrayObject *)values[4]); + __pyx_v_uv_coords = ((PyArrayObject *)values[5]); + __pyx_v_nver = __Pyx_PyInt_As_int(values[6]); if (unlikely((__pyx_v_nver == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 105, __pyx_L3_error) + __pyx_v_ntri = __Pyx_PyInt_As_int(values[7]); if (unlikely((__pyx_v_ntri == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 105, __pyx_L3_error) + __pyx_v_ntexver = __Pyx_PyInt_As_int(values[8]); if (unlikely((__pyx_v_ntexver == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 105, __pyx_L3_error) + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("write_obj_with_colors_texture_core", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 100, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("mesh_core_cython.write_obj_with_colors_texture_core", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_vertices), __pyx_ptype_5numpy_ndarray, 0, "vertices", 0))) __PYX_ERR(0, 101, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_triangles), __pyx_ptype_5numpy_ndarray, 0, "triangles", 0))) __PYX_ERR(0, 102, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_colors), __pyx_ptype_5numpy_ndarray, 0, "colors", 0))) __PYX_ERR(0, 103, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_uv_coords), __pyx_ptype_5numpy_ndarray, 0, "uv_coords", 0))) __PYX_ERR(0, 104, __pyx_L1_error) + __pyx_r = __pyx_pf_16mesh_core_cython_8write_obj_with_colors_texture_core(__pyx_self, __pyx_v_filename, __pyx_v_mtl_name, __pyx_v_vertices, __pyx_v_triangles, __pyx_v_colors, __pyx_v_uv_coords, __pyx_v_nver, __pyx_v_ntri, __pyx_v_ntexver); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_16mesh_core_cython_8write_obj_with_colors_texture_core(CYTHON_UNUSED PyObject *__pyx_self, std::string __pyx_v_filename, std::string __pyx_v_mtl_name, PyArrayObject *__pyx_v_vertices, PyArrayObject *__pyx_v_triangles, PyArrayObject *__pyx_v_colors, PyArrayObject *__pyx_v_uv_coords, int __pyx_v_nver, int __pyx_v_ntri, int __pyx_v_ntexver) { + __Pyx_LocalBuf_ND __pyx_pybuffernd_colors; + __Pyx_Buffer __pyx_pybuffer_colors; + __Pyx_LocalBuf_ND __pyx_pybuffernd_triangles; + __Pyx_Buffer __pyx_pybuffer_triangles; + __Pyx_LocalBuf_ND __pyx_pybuffernd_uv_coords; + __Pyx_Buffer __pyx_pybuffer_uv_coords; + __Pyx_LocalBuf_ND __pyx_pybuffernd_vertices; + __Pyx_Buffer __pyx_pybuffer_vertices; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("write_obj_with_colors_texture_core", 0); + __pyx_pybuffer_vertices.pybuffer.buf = NULL; + __pyx_pybuffer_vertices.refcount = 0; + __pyx_pybuffernd_vertices.data = NULL; + __pyx_pybuffernd_vertices.rcbuffer = &__pyx_pybuffer_vertices; + __pyx_pybuffer_triangles.pybuffer.buf = NULL; + __pyx_pybuffer_triangles.refcount = 0; + __pyx_pybuffernd_triangles.data = NULL; + __pyx_pybuffernd_triangles.rcbuffer = &__pyx_pybuffer_triangles; + __pyx_pybuffer_colors.pybuffer.buf = NULL; + __pyx_pybuffer_colors.refcount = 0; + __pyx_pybuffernd_colors.data = NULL; + __pyx_pybuffernd_colors.rcbuffer = &__pyx_pybuffer_colors; + __pyx_pybuffer_uv_coords.pybuffer.buf = NULL; + __pyx_pybuffer_uv_coords.refcount = 0; + __pyx_pybuffernd_uv_coords.data = NULL; + __pyx_pybuffernd_uv_coords.rcbuffer = &__pyx_pybuffer_uv_coords; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertices.rcbuffer->pybuffer, (PyObject*)__pyx_v_vertices, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 100, __pyx_L1_error) + } + __pyx_pybuffernd_vertices.diminfo[0].strides = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_vertices.diminfo[0].shape = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_vertices.diminfo[1].strides = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_vertices.diminfo[1].shape = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer, (PyObject*)__pyx_v_triangles, &__Pyx_TypeInfo_int, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 100, __pyx_L1_error) + } + __pyx_pybuffernd_triangles.diminfo[0].strides = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_triangles.diminfo[0].shape = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_triangles.diminfo[1].strides = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_triangles.diminfo[1].shape = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_colors.rcbuffer->pybuffer, (PyObject*)__pyx_v_colors, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 100, __pyx_L1_error) + } + __pyx_pybuffernd_colors.diminfo[0].strides = __pyx_pybuffernd_colors.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_colors.diminfo[0].shape = __pyx_pybuffernd_colors.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_colors.diminfo[1].strides = __pyx_pybuffernd_colors.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_colors.diminfo[1].shape = __pyx_pybuffernd_colors.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_uv_coords.rcbuffer->pybuffer, (PyObject*)__pyx_v_uv_coords, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 100, __pyx_L1_error) + } + __pyx_pybuffernd_uv_coords.diminfo[0].strides = __pyx_pybuffernd_uv_coords.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_uv_coords.diminfo[0].shape = __pyx_pybuffernd_uv_coords.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_uv_coords.diminfo[1].strides = __pyx_pybuffernd_uv_coords.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_uv_coords.diminfo[1].shape = __pyx_pybuffernd_uv_coords.rcbuffer->pybuffer.shape[1]; + + /* "mesh_core_cython.pyx":107 + * int nver, int ntri, int ntexver + * ): + * _write_obj_with_colors_texture(filename, mtl_name, # <<<<<<<<<<<<<< + * np.PyArray_DATA(vertices), np.PyArray_DATA(triangles), np.PyArray_DATA(colors), np.PyArray_DATA(uv_coords), + * nver, ntri, ntexver) + */ + _write_obj_with_colors_texture(__pyx_v_filename, __pyx_v_mtl_name, ((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_vertices))), ((int *)PyArray_DATA(((PyArrayObject *)__pyx_v_triangles))), ((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_colors))), ((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_uv_coords))), __pyx_v_nver, __pyx_v_ntri, __pyx_v_ntexver); + + /* "mesh_core_cython.pyx":100 + * mapping_type) + * + * def write_obj_with_colors_texture_core(string filename, string mtl_name, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_colors.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_uv_coords.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertices.rcbuffer->pybuffer); + __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} + __Pyx_AddTraceback("mesh_core_cython.write_obj_with_colors_texture_core", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + goto __pyx_L2; + __pyx_L0:; + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_colors.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_uv_coords.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertices.rcbuffer->pybuffer); + __pyx_L2:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":215 + * # experimental exception made for __getbuffer__ and __releasebuffer__ + * # -- the details of this may change. + * def __getbuffer__(ndarray self, Py_buffer* info, int flags): # <<<<<<<<<<<<<< + * # This implementation of getbuffer is geared towards Cython + * # requirements, and does not yet fulfill the PEP. + */ + +/* Python wrapper */ +static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/ +static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0); + __pyx_r = __pyx_pf_5numpy_7ndarray___getbuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { + int __pyx_v_i; + int __pyx_v_ndim; + int __pyx_v_endian_detector; + int __pyx_v_little_endian; + int __pyx_v_t; + char *__pyx_v_f; + PyArray_Descr *__pyx_v_descr = 0; + int __pyx_v_offset; + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + int __pyx_t_5; + int __pyx_t_6; + PyObject *__pyx_t_7 = NULL; + char *__pyx_t_8; + if (__pyx_v_info == NULL) { + PyErr_SetString(PyExc_BufferError, "PyObject_GetBuffer: view==NULL argument is obsolete"); + return -1; + } + __Pyx_RefNannySetupContext("__getbuffer__", 0); + __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(__pyx_v_info->obj); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":222 + * + * cdef int i, ndim + * cdef int endian_detector = 1 # <<<<<<<<<<<<<< + * cdef bint little_endian = ((&endian_detector)[0] != 0) + * + */ + __pyx_v_endian_detector = 1; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":223 + * cdef int i, ndim + * cdef int endian_detector = 1 + * cdef bint little_endian = ((&endian_detector)[0] != 0) # <<<<<<<<<<<<<< + * + * ndim = PyArray_NDIM(self) + */ + __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":225 + * cdef bint little_endian = ((&endian_detector)[0] != 0) + * + * ndim = PyArray_NDIM(self) # <<<<<<<<<<<<<< + * + * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) + */ + __pyx_v_ndim = PyArray_NDIM(__pyx_v_self); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":227 + * ndim = PyArray_NDIM(self) + * + * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) # <<<<<<<<<<<<<< + * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): + * raise ValueError(u"ndarray is not C contiguous") + */ + __pyx_t_2 = (((__pyx_v_flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS) != 0); + if (__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L4_bool_binop_done; + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":228 + * + * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) + * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): # <<<<<<<<<<<<<< + * raise ValueError(u"ndarray is not C contiguous") + * + */ + __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_C_CONTIGUOUS) != 0)) != 0); + __pyx_t_1 = __pyx_t_2; + __pyx_L4_bool_binop_done:; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":227 + * ndim = PyArray_NDIM(self) + * + * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) # <<<<<<<<<<<<<< + * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): + * raise ValueError(u"ndarray is not C contiguous") + */ + if (unlikely(__pyx_t_1)) { + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":229 + * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) + * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): + * raise ValueError(u"ndarray is not C contiguous") # <<<<<<<<<<<<<< + * + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) + */ + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 229, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(1, 229, __pyx_L1_error) + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":227 + * ndim = PyArray_NDIM(self) + * + * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) # <<<<<<<<<<<<<< + * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): + * raise ValueError(u"ndarray is not C contiguous") + */ + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":231 + * raise ValueError(u"ndarray is not C contiguous") + * + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) # <<<<<<<<<<<<<< + * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): + * raise ValueError(u"ndarray is not Fortran contiguous") + */ + __pyx_t_2 = (((__pyx_v_flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS) != 0); + if (__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L7_bool_binop_done; + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":232 + * + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) + * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): # <<<<<<<<<<<<<< + * raise ValueError(u"ndarray is not Fortran contiguous") + * + */ + __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_F_CONTIGUOUS) != 0)) != 0); + __pyx_t_1 = __pyx_t_2; + __pyx_L7_bool_binop_done:; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":231 + * raise ValueError(u"ndarray is not C contiguous") + * + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) # <<<<<<<<<<<<<< + * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): + * raise ValueError(u"ndarray is not Fortran contiguous") + */ + if (unlikely(__pyx_t_1)) { + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":233 + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) + * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): + * raise ValueError(u"ndarray is not Fortran contiguous") # <<<<<<<<<<<<<< + * + * info.buf = PyArray_DATA(self) + */ + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 233, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(1, 233, __pyx_L1_error) + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":231 + * raise ValueError(u"ndarray is not C contiguous") + * + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) # <<<<<<<<<<<<<< + * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): + * raise ValueError(u"ndarray is not Fortran contiguous") + */ + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":235 + * raise ValueError(u"ndarray is not Fortran contiguous") + * + * info.buf = PyArray_DATA(self) # <<<<<<<<<<<<<< + * info.ndim = ndim + * if sizeof(npy_intp) != sizeof(Py_ssize_t): + */ + __pyx_v_info->buf = PyArray_DATA(__pyx_v_self); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":236 + * + * info.buf = PyArray_DATA(self) + * info.ndim = ndim # <<<<<<<<<<<<<< + * if sizeof(npy_intp) != sizeof(Py_ssize_t): + * # Allocate new buffer for strides and shape info. + */ + __pyx_v_info->ndim = __pyx_v_ndim; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":237 + * info.buf = PyArray_DATA(self) + * info.ndim = ndim + * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< + * # Allocate new buffer for strides and shape info. + * # This is allocated as one block, strides first. + */ + __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0); + if (__pyx_t_1) { + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":240 + * # Allocate new buffer for strides and shape info. + * # This is allocated as one block, strides first. + * info.strides = PyObject_Malloc(sizeof(Py_ssize_t) * 2 * ndim) # <<<<<<<<<<<<<< + * info.shape = info.strides + ndim + * for i in range(ndim): + */ + __pyx_v_info->strides = ((Py_ssize_t *)PyObject_Malloc((((sizeof(Py_ssize_t)) * 2) * ((size_t)__pyx_v_ndim)))); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":241 + * # This is allocated as one block, strides first. + * info.strides = PyObject_Malloc(sizeof(Py_ssize_t) * 2 * ndim) + * info.shape = info.strides + ndim # <<<<<<<<<<<<<< + * for i in range(ndim): + * info.strides[i] = PyArray_STRIDES(self)[i] + */ + __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":242 + * info.strides = PyObject_Malloc(sizeof(Py_ssize_t) * 2 * ndim) + * info.shape = info.strides + ndim + * for i in range(ndim): # <<<<<<<<<<<<<< + * info.strides[i] = PyArray_STRIDES(self)[i] + * info.shape[i] = PyArray_DIMS(self)[i] + */ + __pyx_t_4 = __pyx_v_ndim; + __pyx_t_5 = __pyx_t_4; + for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) { + __pyx_v_i = __pyx_t_6; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":243 + * info.shape = info.strides + ndim + * for i in range(ndim): + * info.strides[i] = PyArray_STRIDES(self)[i] # <<<<<<<<<<<<<< + * info.shape[i] = PyArray_DIMS(self)[i] + * else: + */ + (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":244 + * for i in range(ndim): + * info.strides[i] = PyArray_STRIDES(self)[i] + * info.shape[i] = PyArray_DIMS(self)[i] # <<<<<<<<<<<<<< + * else: + * info.strides = PyArray_STRIDES(self) + */ + (__pyx_v_info->shape[__pyx_v_i]) = (PyArray_DIMS(__pyx_v_self)[__pyx_v_i]); + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":237 + * info.buf = PyArray_DATA(self) + * info.ndim = ndim + * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< + * # Allocate new buffer for strides and shape info. + * # This is allocated as one block, strides first. + */ + goto __pyx_L9; + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":246 + * info.shape[i] = PyArray_DIMS(self)[i] + * else: + * info.strides = PyArray_STRIDES(self) # <<<<<<<<<<<<<< + * info.shape = PyArray_DIMS(self) + * info.suboffsets = NULL + */ + /*else*/ { + __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self)); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":247 + * else: + * info.strides = PyArray_STRIDES(self) + * info.shape = PyArray_DIMS(self) # <<<<<<<<<<<<<< + * info.suboffsets = NULL + * info.itemsize = PyArray_ITEMSIZE(self) + */ + __pyx_v_info->shape = ((Py_ssize_t *)PyArray_DIMS(__pyx_v_self)); + } + __pyx_L9:; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":248 + * info.strides = PyArray_STRIDES(self) + * info.shape = PyArray_DIMS(self) + * info.suboffsets = NULL # <<<<<<<<<<<<<< + * info.itemsize = PyArray_ITEMSIZE(self) + * info.readonly = not PyArray_ISWRITEABLE(self) + */ + __pyx_v_info->suboffsets = NULL; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":249 + * info.shape = PyArray_DIMS(self) + * info.suboffsets = NULL + * info.itemsize = PyArray_ITEMSIZE(self) # <<<<<<<<<<<<<< + * info.readonly = not PyArray_ISWRITEABLE(self) + * + */ + __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":250 + * info.suboffsets = NULL + * info.itemsize = PyArray_ITEMSIZE(self) + * info.readonly = not PyArray_ISWRITEABLE(self) # <<<<<<<<<<<<<< + * + * cdef int t + */ + __pyx_v_info->readonly = (!(PyArray_ISWRITEABLE(__pyx_v_self) != 0)); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":253 + * + * cdef int t + * cdef char* f = NULL # <<<<<<<<<<<<<< + * cdef dtype descr = self.descr + * cdef int offset + */ + __pyx_v_f = NULL; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":254 + * cdef int t + * cdef char* f = NULL + * cdef dtype descr = self.descr # <<<<<<<<<<<<<< + * cdef int offset + * + */ + __pyx_t_3 = ((PyObject *)__pyx_v_self->descr); + __Pyx_INCREF(__pyx_t_3); + __pyx_v_descr = ((PyArray_Descr *)__pyx_t_3); + __pyx_t_3 = 0; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":257 + * cdef int offset + * + * info.obj = self # <<<<<<<<<<<<<< + * + * if not PyDataType_HASFIELDS(descr): + */ + __Pyx_INCREF(((PyObject *)__pyx_v_self)); + __Pyx_GIVEREF(((PyObject *)__pyx_v_self)); + __Pyx_GOTREF(__pyx_v_info->obj); + __Pyx_DECREF(__pyx_v_info->obj); + __pyx_v_info->obj = ((PyObject *)__pyx_v_self); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":259 + * info.obj = self + * + * if not PyDataType_HASFIELDS(descr): # <<<<<<<<<<<<<< + * t = descr.type_num + * if ((descr.byteorder == c'>' and little_endian) or + */ + __pyx_t_1 = ((!(PyDataType_HASFIELDS(__pyx_v_descr) != 0)) != 0); + if (__pyx_t_1) { + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":260 + * + * if not PyDataType_HASFIELDS(descr): + * t = descr.type_num # <<<<<<<<<<<<<< + * if ((descr.byteorder == c'>' and little_endian) or + * (descr.byteorder == c'<' and not little_endian)): + */ + __pyx_t_4 = __pyx_v_descr->type_num; + __pyx_v_t = __pyx_t_4; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":261 + * if not PyDataType_HASFIELDS(descr): + * t = descr.type_num + * if ((descr.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< + * (descr.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") + */ + __pyx_t_2 = ((__pyx_v_descr->byteorder == '>') != 0); + if (!__pyx_t_2) { + goto __pyx_L15_next_or; + } else { + } + __pyx_t_2 = (__pyx_v_little_endian != 0); + if (!__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L14_bool_binop_done; + } + __pyx_L15_next_or:; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":262 + * t = descr.type_num + * if ((descr.byteorder == c'>' and little_endian) or + * (descr.byteorder == c'<' and not little_endian)): # <<<<<<<<<<<<<< + * raise ValueError(u"Non-native byte order not supported") + * if t == NPY_BYTE: f = "b" + */ + __pyx_t_2 = ((__pyx_v_descr->byteorder == '<') != 0); + if (__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L14_bool_binop_done; + } + __pyx_t_2 = ((!(__pyx_v_little_endian != 0)) != 0); + __pyx_t_1 = __pyx_t_2; + __pyx_L14_bool_binop_done:; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":261 + * if not PyDataType_HASFIELDS(descr): + * t = descr.type_num + * if ((descr.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< + * (descr.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") + */ + if (unlikely(__pyx_t_1)) { + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":263 + * if ((descr.byteorder == c'>' and little_endian) or + * (descr.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< + * if t == NPY_BYTE: f = "b" + * elif t == NPY_UBYTE: f = "B" + */ + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 263, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(1, 263, __pyx_L1_error) + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":261 + * if not PyDataType_HASFIELDS(descr): + * t = descr.type_num + * if ((descr.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< + * (descr.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") + */ + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":264 + * (descr.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") + * if t == NPY_BYTE: f = "b" # <<<<<<<<<<<<<< + * elif t == NPY_UBYTE: f = "B" + * elif t == NPY_SHORT: f = "h" + */ + switch (__pyx_v_t) { + case NPY_BYTE: + __pyx_v_f = ((char *)"b"); + break; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":265 + * raise ValueError(u"Non-native byte order not supported") + * if t == NPY_BYTE: f = "b" + * elif t == NPY_UBYTE: f = "B" # <<<<<<<<<<<<<< + * elif t == NPY_SHORT: f = "h" + * elif t == NPY_USHORT: f = "H" + */ + case NPY_UBYTE: + __pyx_v_f = ((char *)"B"); + break; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":266 + * if t == NPY_BYTE: f = "b" + * elif t == NPY_UBYTE: f = "B" + * elif t == NPY_SHORT: f = "h" # <<<<<<<<<<<<<< + * elif t == NPY_USHORT: f = "H" + * elif t == NPY_INT: f = "i" + */ + case NPY_SHORT: + __pyx_v_f = ((char *)"h"); + break; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":267 + * elif t == NPY_UBYTE: f = "B" + * elif t == NPY_SHORT: f = "h" + * elif t == NPY_USHORT: f = "H" # <<<<<<<<<<<<<< + * elif t == NPY_INT: f = "i" + * elif t == NPY_UINT: f = "I" + */ + case NPY_USHORT: + __pyx_v_f = ((char *)"H"); + break; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":268 + * elif t == NPY_SHORT: f = "h" + * elif t == NPY_USHORT: f = "H" + * elif t == NPY_INT: f = "i" # <<<<<<<<<<<<<< + * elif t == NPY_UINT: f = "I" + * elif t == NPY_LONG: f = "l" + */ + case NPY_INT: + __pyx_v_f = ((char *)"i"); + break; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":269 + * elif t == NPY_USHORT: f = "H" + * elif t == NPY_INT: f = "i" + * elif t == NPY_UINT: f = "I" # <<<<<<<<<<<<<< + * elif t == NPY_LONG: f = "l" + * elif t == NPY_ULONG: f = "L" + */ + case NPY_UINT: + __pyx_v_f = ((char *)"I"); + break; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":270 + * elif t == NPY_INT: f = "i" + * elif t == NPY_UINT: f = "I" + * elif t == NPY_LONG: f = "l" # <<<<<<<<<<<<<< + * elif t == NPY_ULONG: f = "L" + * elif t == NPY_LONGLONG: f = "q" + */ + case NPY_LONG: + __pyx_v_f = ((char *)"l"); + break; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":271 + * elif t == NPY_UINT: f = "I" + * elif t == NPY_LONG: f = "l" + * elif t == NPY_ULONG: f = "L" # <<<<<<<<<<<<<< + * elif t == NPY_LONGLONG: f = "q" + * elif t == NPY_ULONGLONG: f = "Q" + */ + case NPY_ULONG: + __pyx_v_f = ((char *)"L"); + break; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":272 + * elif t == NPY_LONG: f = "l" + * elif t == NPY_ULONG: f = "L" + * elif t == NPY_LONGLONG: f = "q" # <<<<<<<<<<<<<< + * elif t == NPY_ULONGLONG: f = "Q" + * elif t == NPY_FLOAT: f = "f" + */ + case NPY_LONGLONG: + __pyx_v_f = ((char *)"q"); + break; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":273 + * elif t == NPY_ULONG: f = "L" + * elif t == NPY_LONGLONG: f = "q" + * elif t == NPY_ULONGLONG: f = "Q" # <<<<<<<<<<<<<< + * elif t == NPY_FLOAT: f = "f" + * elif t == NPY_DOUBLE: f = "d" + */ + case NPY_ULONGLONG: + __pyx_v_f = ((char *)"Q"); + break; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":274 + * elif t == NPY_LONGLONG: f = "q" + * elif t == NPY_ULONGLONG: f = "Q" + * elif t == NPY_FLOAT: f = "f" # <<<<<<<<<<<<<< + * elif t == NPY_DOUBLE: f = "d" + * elif t == NPY_LONGDOUBLE: f = "g" + */ + case NPY_FLOAT: + __pyx_v_f = ((char *)"f"); + break; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":275 + * elif t == NPY_ULONGLONG: f = "Q" + * elif t == NPY_FLOAT: f = "f" + * elif t == NPY_DOUBLE: f = "d" # <<<<<<<<<<<<<< + * elif t == NPY_LONGDOUBLE: f = "g" + * elif t == NPY_CFLOAT: f = "Zf" + */ + case NPY_DOUBLE: + __pyx_v_f = ((char *)"d"); + break; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":276 + * elif t == NPY_FLOAT: f = "f" + * elif t == NPY_DOUBLE: f = "d" + * elif t == NPY_LONGDOUBLE: f = "g" # <<<<<<<<<<<<<< + * elif t == NPY_CFLOAT: f = "Zf" + * elif t == NPY_CDOUBLE: f = "Zd" + */ + case NPY_LONGDOUBLE: + __pyx_v_f = ((char *)"g"); + break; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":277 + * elif t == NPY_DOUBLE: f = "d" + * elif t == NPY_LONGDOUBLE: f = "g" + * elif t == NPY_CFLOAT: f = "Zf" # <<<<<<<<<<<<<< + * elif t == NPY_CDOUBLE: f = "Zd" + * elif t == NPY_CLONGDOUBLE: f = "Zg" + */ + case NPY_CFLOAT: + __pyx_v_f = ((char *)"Zf"); + break; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":278 + * elif t == NPY_LONGDOUBLE: f = "g" + * elif t == NPY_CFLOAT: f = "Zf" + * elif t == NPY_CDOUBLE: f = "Zd" # <<<<<<<<<<<<<< + * elif t == NPY_CLONGDOUBLE: f = "Zg" + * elif t == NPY_OBJECT: f = "O" + */ + case NPY_CDOUBLE: + __pyx_v_f = ((char *)"Zd"); + break; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":279 + * elif t == NPY_CFLOAT: f = "Zf" + * elif t == NPY_CDOUBLE: f = "Zd" + * elif t == NPY_CLONGDOUBLE: f = "Zg" # <<<<<<<<<<<<<< + * elif t == NPY_OBJECT: f = "O" + * else: + */ + case NPY_CLONGDOUBLE: + __pyx_v_f = ((char *)"Zg"); + break; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":280 + * elif t == NPY_CDOUBLE: f = "Zd" + * elif t == NPY_CLONGDOUBLE: f = "Zg" + * elif t == NPY_OBJECT: f = "O" # <<<<<<<<<<<<<< + * else: + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) + */ + case NPY_OBJECT: + __pyx_v_f = ((char *)"O"); + break; + default: + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":282 + * elif t == NPY_OBJECT: f = "O" + * else: + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) # <<<<<<<<<<<<<< + * info.format = f + * return + */ + __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 282, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_7 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_t_3); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 282, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_ValueError, __pyx_t_7); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 282, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(1, 282, __pyx_L1_error) + break; + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":283 + * else: + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) + * info.format = f # <<<<<<<<<<<<<< + * return + * else: + */ + __pyx_v_info->format = __pyx_v_f; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":284 + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) + * info.format = f + * return # <<<<<<<<<<<<<< + * else: + * info.format = PyObject_Malloc(_buffer_format_string_len) + */ + __pyx_r = 0; + goto __pyx_L0; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":259 + * info.obj = self + * + * if not PyDataType_HASFIELDS(descr): # <<<<<<<<<<<<<< + * t = descr.type_num + * if ((descr.byteorder == c'>' and little_endian) or + */ + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":286 + * return + * else: + * info.format = PyObject_Malloc(_buffer_format_string_len) # <<<<<<<<<<<<<< + * info.format[0] = c'^' # Native data types, manual alignment + * offset = 0 + */ + /*else*/ { + __pyx_v_info->format = ((char *)PyObject_Malloc(0xFF)); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":287 + * else: + * info.format = PyObject_Malloc(_buffer_format_string_len) + * info.format[0] = c'^' # Native data types, manual alignment # <<<<<<<<<<<<<< + * offset = 0 + * f = _util_dtypestring(descr, info.format + 1, + */ + (__pyx_v_info->format[0]) = '^'; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":288 + * info.format = PyObject_Malloc(_buffer_format_string_len) + * info.format[0] = c'^' # Native data types, manual alignment + * offset = 0 # <<<<<<<<<<<<<< + * f = _util_dtypestring(descr, info.format + 1, + * info.format + _buffer_format_string_len, + */ + __pyx_v_offset = 0; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":289 + * info.format[0] = c'^' # Native data types, manual alignment + * offset = 0 + * f = _util_dtypestring(descr, info.format + 1, # <<<<<<<<<<<<<< + * info.format + _buffer_format_string_len, + * &offset) + */ + __pyx_t_8 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 0xFF), (&__pyx_v_offset)); if (unlikely(__pyx_t_8 == ((char *)NULL))) __PYX_ERR(1, 289, __pyx_L1_error) + __pyx_v_f = __pyx_t_8; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":292 + * info.format + _buffer_format_string_len, + * &offset) + * f[0] = c'\0' # Terminate format string # <<<<<<<<<<<<<< + * + * def __releasebuffer__(ndarray self, Py_buffer* info): + */ + (__pyx_v_f[0]) = '\x00'; + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":215 + * # experimental exception made for __getbuffer__ and __releasebuffer__ + * # -- the details of this may change. + * def __getbuffer__(ndarray self, Py_buffer* info, int flags): # <<<<<<<<<<<<<< + * # This implementation of getbuffer is geared towards Cython + * # requirements, and does not yet fulfill the PEP. + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("numpy.ndarray.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + if (__pyx_v_info->obj != NULL) { + __Pyx_GOTREF(__pyx_v_info->obj); + __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = 0; + } + goto __pyx_L2; + __pyx_L0:; + if (__pyx_v_info->obj == Py_None) { + __Pyx_GOTREF(__pyx_v_info->obj); + __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = 0; + } + __pyx_L2:; + __Pyx_XDECREF((PyObject *)__pyx_v_descr); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":294 + * f[0] = c'\0' # Terminate format string + * + * def __releasebuffer__(ndarray self, Py_buffer* info): # <<<<<<<<<<<<<< + * if PyArray_HASFIELDS(self): + * PyObject_Free(info.format) + */ + +/* Python wrapper */ +static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info); /*proto*/ +static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__releasebuffer__ (wrapper)", 0); + __pyx_pf_5numpy_7ndarray_2__releasebuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); +} + +static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info) { + __Pyx_RefNannyDeclarations + int __pyx_t_1; + __Pyx_RefNannySetupContext("__releasebuffer__", 0); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":295 + * + * def __releasebuffer__(ndarray self, Py_buffer* info): + * if PyArray_HASFIELDS(self): # <<<<<<<<<<<<<< + * PyObject_Free(info.format) + * if sizeof(npy_intp) != sizeof(Py_ssize_t): + */ + __pyx_t_1 = (PyArray_HASFIELDS(__pyx_v_self) != 0); + if (__pyx_t_1) { + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":296 + * def __releasebuffer__(ndarray self, Py_buffer* info): + * if PyArray_HASFIELDS(self): + * PyObject_Free(info.format) # <<<<<<<<<<<<<< + * if sizeof(npy_intp) != sizeof(Py_ssize_t): + * PyObject_Free(info.strides) + */ + PyObject_Free(__pyx_v_info->format); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":295 + * + * def __releasebuffer__(ndarray self, Py_buffer* info): + * if PyArray_HASFIELDS(self): # <<<<<<<<<<<<<< + * PyObject_Free(info.format) + * if sizeof(npy_intp) != sizeof(Py_ssize_t): + */ + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":297 + * if PyArray_HASFIELDS(self): + * PyObject_Free(info.format) + * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< + * PyObject_Free(info.strides) + * # info.shape was stored after info.strides in the same block + */ + __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0); + if (__pyx_t_1) { + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":298 + * PyObject_Free(info.format) + * if sizeof(npy_intp) != sizeof(Py_ssize_t): + * PyObject_Free(info.strides) # <<<<<<<<<<<<<< + * # info.shape was stored after info.strides in the same block + * + */ + PyObject_Free(__pyx_v_info->strides); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":297 + * if PyArray_HASFIELDS(self): + * PyObject_Free(info.format) + * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< + * PyObject_Free(info.strides) + * # info.shape was stored after info.strides in the same block + */ + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":294 + * f[0] = c'\0' # Terminate format string + * + * def __releasebuffer__(ndarray self, Py_buffer* info): # <<<<<<<<<<<<<< + * if PyArray_HASFIELDS(self): + * PyObject_Free(info.format) + */ + + /* function exit code */ + __Pyx_RefNannyFinishContext(); +} + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":775 + * ctypedef npy_cdouble complex_t + * + * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(1, a) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":776 + * + * cdef inline object PyArray_MultiIterNew1(a): + * return PyArray_MultiIterNew(1, a) # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew2(a, b): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 776, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":775 + * ctypedef npy_cdouble complex_t + * + * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(1, a) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":778 + * return PyArray_MultiIterNew(1, a) + * + * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(2, a, b) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":779 + * + * cdef inline object PyArray_MultiIterNew2(a, b): + * return PyArray_MultiIterNew(2, a, b) # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew3(a, b, c): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 779, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":778 + * return PyArray_MultiIterNew(1, a) + * + * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(2, a, b) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":781 + * return PyArray_MultiIterNew(2, a, b) + * + * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(3, a, b, c) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":782 + * + * cdef inline object PyArray_MultiIterNew3(a, b, c): + * return PyArray_MultiIterNew(3, a, b, c) # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew4(a, b, c, d): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 782, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":781 + * return PyArray_MultiIterNew(2, a, b) + * + * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(3, a, b, c) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew3", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":784 + * return PyArray_MultiIterNew(3, a, b, c) + * + * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(4, a, b, c, d) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":785 + * + * cdef inline object PyArray_MultiIterNew4(a, b, c, d): + * return PyArray_MultiIterNew(4, a, b, c, d) # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 785, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":784 + * return PyArray_MultiIterNew(3, a, b, c) + * + * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(4, a, b, c, d) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew4", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":787 + * return PyArray_MultiIterNew(4, a, b, c, d) + * + * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(5, a, b, c, d, e) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":788 + * + * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): + * return PyArray_MultiIterNew(5, a, b, c, d, e) # <<<<<<<<<<<<<< + * + * cdef inline tuple PyDataType_SHAPE(dtype d): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 788, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":787 + * return PyArray_MultiIterNew(4, a, b, c, d) + * + * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(5, a, b, c, d, e) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew5", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":790 + * return PyArray_MultiIterNew(5, a, b, c, d, e) + * + * cdef inline tuple PyDataType_SHAPE(dtype d): # <<<<<<<<<<<<<< + * if PyDataType_HASSUBARRAY(d): + * return d.subarray.shape + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyDataType_SHAPE(PyArray_Descr *__pyx_v_d) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + __Pyx_RefNannySetupContext("PyDataType_SHAPE", 0); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":791 + * + * cdef inline tuple PyDataType_SHAPE(dtype d): + * if PyDataType_HASSUBARRAY(d): # <<<<<<<<<<<<<< + * return d.subarray.shape + * else: + */ + __pyx_t_1 = (PyDataType_HASSUBARRAY(__pyx_v_d) != 0); + if (__pyx_t_1) { + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":792 + * cdef inline tuple PyDataType_SHAPE(dtype d): + * if PyDataType_HASSUBARRAY(d): + * return d.subarray.shape # <<<<<<<<<<<<<< + * else: + * return () + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(((PyObject*)__pyx_v_d->subarray->shape)); + __pyx_r = ((PyObject*)__pyx_v_d->subarray->shape); + goto __pyx_L0; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":791 + * + * cdef inline tuple PyDataType_SHAPE(dtype d): + * if PyDataType_HASSUBARRAY(d): # <<<<<<<<<<<<<< + * return d.subarray.shape + * else: + */ + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":794 + * return d.subarray.shape + * else: + * return () # <<<<<<<<<<<<<< + * + * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: + */ + /*else*/ { + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_empty_tuple); + __pyx_r = __pyx_empty_tuple; + goto __pyx_L0; + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":790 + * return PyArray_MultiIterNew(5, a, b, c, d, e) + * + * cdef inline tuple PyDataType_SHAPE(dtype d): # <<<<<<<<<<<<<< + * if PyDataType_HASSUBARRAY(d): + * return d.subarray.shape + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":796 + * return () + * + * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<< + * # Recursive utility function used in __getbuffer__ to get format + * # string. The new location in the format string is returned. + */ + +static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx_v_descr, char *__pyx_v_f, char *__pyx_v_end, int *__pyx_v_offset) { + PyArray_Descr *__pyx_v_child = 0; + int __pyx_v_endian_detector; + int __pyx_v_little_endian; + PyObject *__pyx_v_fields = 0; + PyObject *__pyx_v_childname = NULL; + PyObject *__pyx_v_new_offset = NULL; + PyObject *__pyx_v_t = NULL; + char *__pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_t_5; + int __pyx_t_6; + int __pyx_t_7; + long __pyx_t_8; + char *__pyx_t_9; + __Pyx_RefNannySetupContext("_util_dtypestring", 0); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":801 + * + * cdef dtype child + * cdef int endian_detector = 1 # <<<<<<<<<<<<<< + * cdef bint little_endian = ((&endian_detector)[0] != 0) + * cdef tuple fields + */ + __pyx_v_endian_detector = 1; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":802 + * cdef dtype child + * cdef int endian_detector = 1 + * cdef bint little_endian = ((&endian_detector)[0] != 0) # <<<<<<<<<<<<<< + * cdef tuple fields + * + */ + __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":805 + * cdef tuple fields + * + * for childname in descr.names: # <<<<<<<<<<<<<< + * fields = descr.fields[childname] + * child, new_offset = fields + */ + if (unlikely(__pyx_v_descr->names == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); + __PYX_ERR(1, 805, __pyx_L1_error) + } + __pyx_t_1 = __pyx_v_descr->names; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0; + for (;;) { + if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(1, 805, __pyx_L1_error) + #else + __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 805, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + #endif + __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3); + __pyx_t_3 = 0; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":806 + * + * for childname in descr.names: + * fields = descr.fields[childname] # <<<<<<<<<<<<<< + * child, new_offset = fields + * + */ + if (unlikely(__pyx_v_descr->fields == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 806, __pyx_L1_error) + } + __pyx_t_3 = __Pyx_PyDict_GetItem(__pyx_v_descr->fields, __pyx_v_childname); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 806, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (!(likely(PyTuple_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_t_3)->tp_name), 0))) __PYX_ERR(1, 806, __pyx_L1_error) + __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3)); + __pyx_t_3 = 0; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":807 + * for childname in descr.names: + * fields = descr.fields[childname] + * child, new_offset = fields # <<<<<<<<<<<<<< + * + * if (end - f) - (new_offset - offset[0]) < 15: + */ + if (likely(__pyx_v_fields != Py_None)) { + PyObject* sequence = __pyx_v_fields; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(1, 807, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx_t_4); + #else + __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 807, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 807, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + } else { + __Pyx_RaiseNoneNotIterableError(); __PYX_ERR(1, 807, __pyx_L1_error) + } + if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_dtype))))) __PYX_ERR(1, 807, __pyx_L1_error) + __Pyx_XDECREF_SET(__pyx_v_child, ((PyArray_Descr *)__pyx_t_3)); + __pyx_t_3 = 0; + __Pyx_XDECREF_SET(__pyx_v_new_offset, __pyx_t_4); + __pyx_t_4 = 0; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":809 + * child, new_offset = fields + * + * if (end - f) - (new_offset - offset[0]) < 15: # <<<<<<<<<<<<<< + * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") + * + */ + __pyx_t_4 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 809, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyNumber_Subtract(__pyx_v_new_offset, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 809, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 809, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = ((((__pyx_v_end - __pyx_v_f) - ((int)__pyx_t_5)) < 15) != 0); + if (unlikely(__pyx_t_6)) { + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":810 + * + * if (end - f) - (new_offset - offset[0]) < 15: + * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<< + * + * if ((child.byteorder == c'>' and little_endian) or + */ + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 810, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(1, 810, __pyx_L1_error) + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":809 + * child, new_offset = fields + * + * if (end - f) - (new_offset - offset[0]) < 15: # <<<<<<<<<<<<<< + * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") + * + */ + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":812 + * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") + * + * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< + * (child.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") + */ + __pyx_t_7 = ((__pyx_v_child->byteorder == '>') != 0); + if (!__pyx_t_7) { + goto __pyx_L8_next_or; + } else { + } + __pyx_t_7 = (__pyx_v_little_endian != 0); + if (!__pyx_t_7) { + } else { + __pyx_t_6 = __pyx_t_7; + goto __pyx_L7_bool_binop_done; + } + __pyx_L8_next_or:; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":813 + * + * if ((child.byteorder == c'>' and little_endian) or + * (child.byteorder == c'<' and not little_endian)): # <<<<<<<<<<<<<< + * raise ValueError(u"Non-native byte order not supported") + * # One could encode it in the format string and have Cython + */ + __pyx_t_7 = ((__pyx_v_child->byteorder == '<') != 0); + if (__pyx_t_7) { + } else { + __pyx_t_6 = __pyx_t_7; + goto __pyx_L7_bool_binop_done; + } + __pyx_t_7 = ((!(__pyx_v_little_endian != 0)) != 0); + __pyx_t_6 = __pyx_t_7; + __pyx_L7_bool_binop_done:; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":812 + * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") + * + * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< + * (child.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") + */ + if (unlikely(__pyx_t_6)) { + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":814 + * if ((child.byteorder == c'>' and little_endian) or + * (child.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< + * # One could encode it in the format string and have Cython + * # complain instead, BUT: < and > in format strings also imply + */ + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 814, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(1, 814, __pyx_L1_error) + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":812 + * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") + * + * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< + * (child.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") + */ + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":824 + * + * # Output padding bytes + * while offset[0] < new_offset: # <<<<<<<<<<<<<< + * f[0] = 120 # "x"; pad byte + * f += 1 + */ + while (1) { + __pyx_t_3 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 824, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_v_new_offset, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 824, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 824, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (!__pyx_t_6) break; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":825 + * # Output padding bytes + * while offset[0] < new_offset: + * f[0] = 120 # "x"; pad byte # <<<<<<<<<<<<<< + * f += 1 + * offset[0] += 1 + */ + (__pyx_v_f[0]) = 0x78; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":826 + * while offset[0] < new_offset: + * f[0] = 120 # "x"; pad byte + * f += 1 # <<<<<<<<<<<<<< + * offset[0] += 1 + * + */ + __pyx_v_f = (__pyx_v_f + 1); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":827 + * f[0] = 120 # "x"; pad byte + * f += 1 + * offset[0] += 1 # <<<<<<<<<<<<<< + * + * offset[0] += child.itemsize + */ + __pyx_t_8 = 0; + (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + 1); + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":829 + * offset[0] += 1 + * + * offset[0] += child.itemsize # <<<<<<<<<<<<<< + * + * if not PyDataType_HASFIELDS(child): + */ + __pyx_t_8 = 0; + (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + __pyx_v_child->elsize); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":831 + * offset[0] += child.itemsize + * + * if not PyDataType_HASFIELDS(child): # <<<<<<<<<<<<<< + * t = child.type_num + * if end - f < 5: + */ + __pyx_t_6 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0); + if (__pyx_t_6) { + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":832 + * + * if not PyDataType_HASFIELDS(child): + * t = child.type_num # <<<<<<<<<<<<<< + * if end - f < 5: + * raise RuntimeError(u"Format string allocated too short.") + */ + __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_child->type_num); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 832, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4); + __pyx_t_4 = 0; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":833 + * if not PyDataType_HASFIELDS(child): + * t = child.type_num + * if end - f < 5: # <<<<<<<<<<<<<< + * raise RuntimeError(u"Format string allocated too short.") + * + */ + __pyx_t_6 = (((__pyx_v_end - __pyx_v_f) < 5) != 0); + if (unlikely(__pyx_t_6)) { + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":834 + * t = child.type_num + * if end - f < 5: + * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<< + * + * # Until ticket #99 is fixed, use integers to avoid warnings + */ + __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 834, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_Raise(__pyx_t_4, 0, 0, 0); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __PYX_ERR(1, 834, __pyx_L1_error) + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":833 + * if not PyDataType_HASFIELDS(child): + * t = child.type_num + * if end - f < 5: # <<<<<<<<<<<<<< + * raise RuntimeError(u"Format string allocated too short.") + * + */ + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":837 + * + * # Until ticket #99 is fixed, use integers to avoid warnings + * if t == NPY_BYTE: f[0] = 98 #"b" # <<<<<<<<<<<<<< + * elif t == NPY_UBYTE: f[0] = 66 #"B" + * elif t == NPY_SHORT: f[0] = 104 #"h" + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_BYTE); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 837, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 837, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 837, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 98; + goto __pyx_L15; + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":838 + * # Until ticket #99 is fixed, use integers to avoid warnings + * if t == NPY_BYTE: f[0] = 98 #"b" + * elif t == NPY_UBYTE: f[0] = 66 #"B" # <<<<<<<<<<<<<< + * elif t == NPY_SHORT: f[0] = 104 #"h" + * elif t == NPY_USHORT: f[0] = 72 #"H" + */ + __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_UBYTE); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 838, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 838, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 838, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 66; + goto __pyx_L15; + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":839 + * if t == NPY_BYTE: f[0] = 98 #"b" + * elif t == NPY_UBYTE: f[0] = 66 #"B" + * elif t == NPY_SHORT: f[0] = 104 #"h" # <<<<<<<<<<<<<< + * elif t == NPY_USHORT: f[0] = 72 #"H" + * elif t == NPY_INT: f[0] = 105 #"i" + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_SHORT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 839, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 839, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 839, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 0x68; + goto __pyx_L15; + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":840 + * elif t == NPY_UBYTE: f[0] = 66 #"B" + * elif t == NPY_SHORT: f[0] = 104 #"h" + * elif t == NPY_USHORT: f[0] = 72 #"H" # <<<<<<<<<<<<<< + * elif t == NPY_INT: f[0] = 105 #"i" + * elif t == NPY_UINT: f[0] = 73 #"I" + */ + __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_USHORT); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 840, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 840, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 840, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 72; + goto __pyx_L15; + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":841 + * elif t == NPY_SHORT: f[0] = 104 #"h" + * elif t == NPY_USHORT: f[0] = 72 #"H" + * elif t == NPY_INT: f[0] = 105 #"i" # <<<<<<<<<<<<<< + * elif t == NPY_UINT: f[0] = 73 #"I" + * elif t == NPY_LONG: f[0] = 108 #"l" + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_INT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 841, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 841, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 841, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 0x69; + goto __pyx_L15; + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":842 + * elif t == NPY_USHORT: f[0] = 72 #"H" + * elif t == NPY_INT: f[0] = 105 #"i" + * elif t == NPY_UINT: f[0] = 73 #"I" # <<<<<<<<<<<<<< + * elif t == NPY_LONG: f[0] = 108 #"l" + * elif t == NPY_ULONG: f[0] = 76 #"L" + */ + __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_UINT); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 842, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 842, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 842, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 73; + goto __pyx_L15; + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":843 + * elif t == NPY_INT: f[0] = 105 #"i" + * elif t == NPY_UINT: f[0] = 73 #"I" + * elif t == NPY_LONG: f[0] = 108 #"l" # <<<<<<<<<<<<<< + * elif t == NPY_ULONG: f[0] = 76 #"L" + * elif t == NPY_LONGLONG: f[0] = 113 #"q" + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_LONG); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 843, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 843, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 843, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 0x6C; + goto __pyx_L15; + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":844 + * elif t == NPY_UINT: f[0] = 73 #"I" + * elif t == NPY_LONG: f[0] = 108 #"l" + * elif t == NPY_ULONG: f[0] = 76 #"L" # <<<<<<<<<<<<<< + * elif t == NPY_LONGLONG: f[0] = 113 #"q" + * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" + */ + __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_ULONG); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 844, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 844, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 844, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 76; + goto __pyx_L15; + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":845 + * elif t == NPY_LONG: f[0] = 108 #"l" + * elif t == NPY_ULONG: f[0] = 76 #"L" + * elif t == NPY_LONGLONG: f[0] = 113 #"q" # <<<<<<<<<<<<<< + * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" + * elif t == NPY_FLOAT: f[0] = 102 #"f" + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_LONGLONG); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 845, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 845, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 845, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 0x71; + goto __pyx_L15; + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":846 + * elif t == NPY_ULONG: f[0] = 76 #"L" + * elif t == NPY_LONGLONG: f[0] = 113 #"q" + * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" # <<<<<<<<<<<<<< + * elif t == NPY_FLOAT: f[0] = 102 #"f" + * elif t == NPY_DOUBLE: f[0] = 100 #"d" + */ + __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_ULONGLONG); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 846, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 846, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 846, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 81; + goto __pyx_L15; + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":847 + * elif t == NPY_LONGLONG: f[0] = 113 #"q" + * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" + * elif t == NPY_FLOAT: f[0] = 102 #"f" # <<<<<<<<<<<<<< + * elif t == NPY_DOUBLE: f[0] = 100 #"d" + * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_FLOAT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 847, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 847, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 847, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 0x66; + goto __pyx_L15; + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":848 + * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" + * elif t == NPY_FLOAT: f[0] = 102 #"f" + * elif t == NPY_DOUBLE: f[0] = 100 #"d" # <<<<<<<<<<<<<< + * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" + * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf + */ + __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_DOUBLE); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 848, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 848, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 848, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 0x64; + goto __pyx_L15; + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":849 + * elif t == NPY_FLOAT: f[0] = 102 #"f" + * elif t == NPY_DOUBLE: f[0] = 100 #"d" + * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" # <<<<<<<<<<<<<< + * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf + * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_LONGDOUBLE); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 849, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 849, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 849, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 0x67; + goto __pyx_L15; + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":850 + * elif t == NPY_DOUBLE: f[0] = 100 #"d" + * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" + * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf # <<<<<<<<<<<<<< + * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd + * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg + */ + __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_CFLOAT); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 850, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 850, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 850, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 90; + (__pyx_v_f[1]) = 0x66; + __pyx_v_f = (__pyx_v_f + 1); + goto __pyx_L15; + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":851 + * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" + * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf + * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd # <<<<<<<<<<<<<< + * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg + * elif t == NPY_OBJECT: f[0] = 79 #"O" + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_CDOUBLE); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 851, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 851, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 851, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 90; + (__pyx_v_f[1]) = 0x64; + __pyx_v_f = (__pyx_v_f + 1); + goto __pyx_L15; + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":852 + * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf + * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd + * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg # <<<<<<<<<<<<<< + * elif t == NPY_OBJECT: f[0] = 79 #"O" + * else: + */ + __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_CLONGDOUBLE); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 852, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 852, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 852, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 90; + (__pyx_v_f[1]) = 0x67; + __pyx_v_f = (__pyx_v_f + 1); + goto __pyx_L15; + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":853 + * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd + * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg + * elif t == NPY_OBJECT: f[0] = 79 #"O" # <<<<<<<<<<<<<< + * else: + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_OBJECT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 853, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 853, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 853, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (likely(__pyx_t_6)) { + (__pyx_v_f[0]) = 79; + goto __pyx_L15; + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":855 + * elif t == NPY_OBJECT: f[0] = 79 #"O" + * else: + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) # <<<<<<<<<<<<<< + * f += 1 + * else: + */ + /*else*/ { + __pyx_t_3 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_v_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 855, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_ValueError, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 855, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_Raise(__pyx_t_4, 0, 0, 0); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __PYX_ERR(1, 855, __pyx_L1_error) + } + __pyx_L15:; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":856 + * else: + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) + * f += 1 # <<<<<<<<<<<<<< + * else: + * # Cython ignores struct boundary information ("T{...}"), + */ + __pyx_v_f = (__pyx_v_f + 1); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":831 + * offset[0] += child.itemsize + * + * if not PyDataType_HASFIELDS(child): # <<<<<<<<<<<<<< + * t = child.type_num + * if end - f < 5: + */ + goto __pyx_L13; + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":860 + * # Cython ignores struct boundary information ("T{...}"), + * # so don't output it + * f = _util_dtypestring(child, f, end, offset) # <<<<<<<<<<<<<< + * return f + * + */ + /*else*/ { + __pyx_t_9 = __pyx_f_5numpy__util_dtypestring(__pyx_v_child, __pyx_v_f, __pyx_v_end, __pyx_v_offset); if (unlikely(__pyx_t_9 == ((char *)NULL))) __PYX_ERR(1, 860, __pyx_L1_error) + __pyx_v_f = __pyx_t_9; + } + __pyx_L13:; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":805 + * cdef tuple fields + * + * for childname in descr.names: # <<<<<<<<<<<<<< + * fields = descr.fields[childname] + * child, new_offset = fields + */ + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":861 + * # so don't output it + * f = _util_dtypestring(child, f, end, offset) + * return f # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = __pyx_v_f; + goto __pyx_L0; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":796 + * return () + * + * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<< + * # Recursive utility function used in __getbuffer__ to get format + * # string. The new location in the format string is returned. + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("numpy._util_dtypestring", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF((PyObject *)__pyx_v_child); + __Pyx_XDECREF(__pyx_v_fields); + __Pyx_XDECREF(__pyx_v_childname); + __Pyx_XDECREF(__pyx_v_new_offset); + __Pyx_XDECREF(__pyx_v_t); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":977 + * + * + * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<< + * cdef PyObject* baseptr + * if base is None: + */ + +static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) { + PyObject *__pyx_v_baseptr; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + __Pyx_RefNannySetupContext("set_array_base", 0); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":979 + * cdef inline void set_array_base(ndarray arr, object base): + * cdef PyObject* baseptr + * if base is None: # <<<<<<<<<<<<<< + * baseptr = NULL + * else: + */ + __pyx_t_1 = (__pyx_v_base == Py_None); + __pyx_t_2 = (__pyx_t_1 != 0); + if (__pyx_t_2) { + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":980 + * cdef PyObject* baseptr + * if base is None: + * baseptr = NULL # <<<<<<<<<<<<<< + * else: + * Py_INCREF(base) # important to do this before decref below! + */ + __pyx_v_baseptr = NULL; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":979 + * cdef inline void set_array_base(ndarray arr, object base): + * cdef PyObject* baseptr + * if base is None: # <<<<<<<<<<<<<< + * baseptr = NULL + * else: + */ + goto __pyx_L3; + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":982 + * baseptr = NULL + * else: + * Py_INCREF(base) # important to do this before decref below! # <<<<<<<<<<<<<< + * baseptr = base + * Py_XDECREF(arr.base) + */ + /*else*/ { + Py_INCREF(__pyx_v_base); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":983 + * else: + * Py_INCREF(base) # important to do this before decref below! + * baseptr = base # <<<<<<<<<<<<<< + * Py_XDECREF(arr.base) + * arr.base = baseptr + */ + __pyx_v_baseptr = ((PyObject *)__pyx_v_base); + } + __pyx_L3:; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":984 + * Py_INCREF(base) # important to do this before decref below! + * baseptr = base + * Py_XDECREF(arr.base) # <<<<<<<<<<<<<< + * arr.base = baseptr + * + */ + Py_XDECREF(__pyx_v_arr->base); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":985 + * baseptr = base + * Py_XDECREF(arr.base) + * arr.base = baseptr # <<<<<<<<<<<<<< + * + * cdef inline object get_array_base(ndarray arr): + */ + __pyx_v_arr->base = __pyx_v_baseptr; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":977 + * + * + * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<< + * cdef PyObject* baseptr + * if base is None: + */ + + /* function exit code */ + __Pyx_RefNannyFinishContext(); +} + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":987 + * arr.base = baseptr + * + * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< + * if arr.base is NULL: + * return None + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + __Pyx_RefNannySetupContext("get_array_base", 0); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":988 + * + * cdef inline object get_array_base(ndarray arr): + * if arr.base is NULL: # <<<<<<<<<<<<<< + * return None + * else: + */ + __pyx_t_1 = ((__pyx_v_arr->base == NULL) != 0); + if (__pyx_t_1) { + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":989 + * cdef inline object get_array_base(ndarray arr): + * if arr.base is NULL: + * return None # <<<<<<<<<<<<<< + * else: + * return arr.base + */ + __Pyx_XDECREF(__pyx_r); + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":988 + * + * cdef inline object get_array_base(ndarray arr): + * if arr.base is NULL: # <<<<<<<<<<<<<< + * return None + * else: + */ + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":991 + * return None + * else: + * return arr.base # <<<<<<<<<<<<<< + * + * + */ + /*else*/ { + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(((PyObject *)__pyx_v_arr->base)); + __pyx_r = ((PyObject *)__pyx_v_arr->base); + goto __pyx_L0; + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":987 + * arr.base = baseptr + * + * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< + * if arr.base is NULL: + * return None + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":996 + * # Versions of the import_* functions which are more suitable for + * # Cython code. + * cdef inline int import_array() except -1: # <<<<<<<<<<<<<< + * try: + * _import_array() + */ + +static CYTHON_INLINE int __pyx_f_5numpy_import_array(void) { + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + __Pyx_RefNannySetupContext("import_array", 0); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":997 + * # Cython code. + * cdef inline int import_array() except -1: + * try: # <<<<<<<<<<<<<< + * _import_array() + * except Exception: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + /*try:*/ { + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":998 + * cdef inline int import_array() except -1: + * try: + * _import_array() # <<<<<<<<<<<<<< + * except Exception: + * raise ImportError("numpy.core.multiarray failed to import") + */ + __pyx_t_4 = _import_array(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 998, __pyx_L3_error) + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":997 + * # Cython code. + * cdef inline int import_array() except -1: + * try: # <<<<<<<<<<<<<< + * _import_array() + * except Exception: + */ + } + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L8_try_end; + __pyx_L3_error:; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":999 + * try: + * _import_array() + * except Exception: # <<<<<<<<<<<<<< + * raise ImportError("numpy.core.multiarray failed to import") + * + */ + __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); + if (__pyx_t_4) { + __Pyx_AddTraceback("numpy.import_array", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(1, 999, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GOTREF(__pyx_t_7); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1000 + * _import_array() + * except Exception: + * raise ImportError("numpy.core.multiarray failed to import") # <<<<<<<<<<<<<< + * + * cdef inline int import_umath() except -1: + */ + __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 1000, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_Raise(__pyx_t_8, 0, 0, 0); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __PYX_ERR(1, 1000, __pyx_L5_except_error) + } + goto __pyx_L5_except_error; + __pyx_L5_except_error:; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":997 + * # Cython code. + * cdef inline int import_array() except -1: + * try: # <<<<<<<<<<<<<< + * _import_array() + * except Exception: + */ + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + goto __pyx_L1_error; + __pyx_L8_try_end:; + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":996 + * # Versions of the import_* functions which are more suitable for + * # Cython code. + * cdef inline int import_array() except -1: # <<<<<<<<<<<<<< + * try: + * _import_array() + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("numpy.import_array", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1002 + * raise ImportError("numpy.core.multiarray failed to import") + * + * cdef inline int import_umath() except -1: # <<<<<<<<<<<<<< + * try: + * _import_umath() + */ + +static CYTHON_INLINE int __pyx_f_5numpy_import_umath(void) { + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + __Pyx_RefNannySetupContext("import_umath", 0); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1003 + * + * cdef inline int import_umath() except -1: + * try: # <<<<<<<<<<<<<< + * _import_umath() + * except Exception: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + /*try:*/ { + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1004 + * cdef inline int import_umath() except -1: + * try: + * _import_umath() # <<<<<<<<<<<<<< + * except Exception: + * raise ImportError("numpy.core.umath failed to import") + */ + __pyx_t_4 = _import_umath(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 1004, __pyx_L3_error) + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1003 + * + * cdef inline int import_umath() except -1: + * try: # <<<<<<<<<<<<<< + * _import_umath() + * except Exception: + */ + } + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L8_try_end; + __pyx_L3_error:; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1005 + * try: + * _import_umath() + * except Exception: # <<<<<<<<<<<<<< + * raise ImportError("numpy.core.umath failed to import") + * + */ + __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); + if (__pyx_t_4) { + __Pyx_AddTraceback("numpy.import_umath", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(1, 1005, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GOTREF(__pyx_t_7); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1006 + * _import_umath() + * except Exception: + * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< + * + * cdef inline int import_ufunc() except -1: + */ + __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 1006, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_Raise(__pyx_t_8, 0, 0, 0); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __PYX_ERR(1, 1006, __pyx_L5_except_error) + } + goto __pyx_L5_except_error; + __pyx_L5_except_error:; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1003 + * + * cdef inline int import_umath() except -1: + * try: # <<<<<<<<<<<<<< + * _import_umath() + * except Exception: + */ + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + goto __pyx_L1_error; + __pyx_L8_try_end:; + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1002 + * raise ImportError("numpy.core.multiarray failed to import") + * + * cdef inline int import_umath() except -1: # <<<<<<<<<<<<<< + * try: + * _import_umath() + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("numpy.import_umath", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1008 + * raise ImportError("numpy.core.umath failed to import") + * + * cdef inline int import_ufunc() except -1: # <<<<<<<<<<<<<< + * try: + * _import_umath() + */ + +static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + __Pyx_RefNannySetupContext("import_ufunc", 0); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1009 + * + * cdef inline int import_ufunc() except -1: + * try: # <<<<<<<<<<<<<< + * _import_umath() + * except Exception: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + /*try:*/ { + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1010 + * cdef inline int import_ufunc() except -1: + * try: + * _import_umath() # <<<<<<<<<<<<<< + * except Exception: + * raise ImportError("numpy.core.umath failed to import") + */ + __pyx_t_4 = _import_umath(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 1010, __pyx_L3_error) + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1009 + * + * cdef inline int import_ufunc() except -1: + * try: # <<<<<<<<<<<<<< + * _import_umath() + * except Exception: + */ + } + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L8_try_end; + __pyx_L3_error:; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1011 + * try: + * _import_umath() + * except Exception: # <<<<<<<<<<<<<< + * raise ImportError("numpy.core.umath failed to import") + */ + __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); + if (__pyx_t_4) { + __Pyx_AddTraceback("numpy.import_ufunc", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(1, 1011, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GOTREF(__pyx_t_7); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1012 + * _import_umath() + * except Exception: + * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< + */ + __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 1012, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_Raise(__pyx_t_8, 0, 0, 0); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __PYX_ERR(1, 1012, __pyx_L5_except_error) + } + goto __pyx_L5_except_error; + __pyx_L5_except_error:; + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1009 + * + * cdef inline int import_ufunc() except -1: + * try: # <<<<<<<<<<<<<< + * _import_umath() + * except Exception: + */ + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + goto __pyx_L1_error; + __pyx_L8_try_end:; + } + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1008 + * raise ImportError("numpy.core.umath failed to import") + * + * cdef inline int import_ufunc() except -1: # <<<<<<<<<<<<<< + * try: + * _import_umath() + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("numpy.import_ufunc", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "string.from_py":13 + * + * @cname("__pyx_convert_string_from_py_std__in_string") + * cdef string __pyx_convert_string_from_py_std__in_string(object o) except *: # <<<<<<<<<<<<<< + * cdef Py_ssize_t length + * cdef const char* data = __Pyx_PyObject_AsStringAndSize(o, &length) + */ + +static std::string __pyx_convert_string_from_py_std__in_string(PyObject *__pyx_v_o) { + Py_ssize_t __pyx_v_length; + char const *__pyx_v_data; + std::string __pyx_r; + __Pyx_RefNannyDeclarations + char const *__pyx_t_1; + __Pyx_RefNannySetupContext("__pyx_convert_string_from_py_std__in_string", 0); + + /* "string.from_py":15 + * cdef string __pyx_convert_string_from_py_std__in_string(object o) except *: + * cdef Py_ssize_t length + * cdef const char* data = __Pyx_PyObject_AsStringAndSize(o, &length) # <<<<<<<<<<<<<< + * return string(data, length) + * + */ + __pyx_t_1 = __Pyx_PyObject_AsStringAndSize(__pyx_v_o, (&__pyx_v_length)); if (unlikely(__pyx_t_1 == ((char const *)NULL))) __PYX_ERR(2, 15, __pyx_L1_error) + __pyx_v_data = __pyx_t_1; + + /* "string.from_py":16 + * cdef Py_ssize_t length + * cdef const char* data = __Pyx_PyObject_AsStringAndSize(o, &length) + * return string(data, length) # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = std::string(__pyx_v_data, __pyx_v_length); + goto __pyx_L0; + + /* "string.from_py":13 + * + * @cname("__pyx_convert_string_from_py_std__in_string") + * cdef string __pyx_convert_string_from_py_std__in_string(object o) except *: # <<<<<<<<<<<<<< + * cdef Py_ssize_t length + * cdef const char* data = __Pyx_PyObject_AsStringAndSize(o, &length) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("string.from_py.__pyx_convert_string_from_py_std__in_string", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_pretend_to_initialize(&__pyx_r); + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyMethodDef __pyx_methods[] = { + {0, 0, 0, 0} +}; + +#if PY_MAJOR_VERSION >= 3 +#if CYTHON_PEP489_MULTI_PHASE_INIT +static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ +static int __pyx_pymod_exec_mesh_core_cython(PyObject* module); /*proto*/ +static PyModuleDef_Slot __pyx_moduledef_slots[] = { + {Py_mod_create, (void*)__pyx_pymod_create}, + {Py_mod_exec, (void*)__pyx_pymod_exec_mesh_core_cython}, + {0, NULL} +}; +#endif + +static struct PyModuleDef __pyx_moduledef = { + PyModuleDef_HEAD_INIT, + "mesh_core_cython", + 0, /* m_doc */ + #if CYTHON_PEP489_MULTI_PHASE_INIT + 0, /* m_size */ + #else + -1, /* m_size */ + #endif + __pyx_methods /* m_methods */, + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_moduledef_slots, /* m_slots */ + #else + NULL, /* m_reload */ + #endif + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ +}; +#endif + +static __Pyx_StringTabEntry __pyx_string_tab[] = { + {&__pyx_kp_u_Format_string_allocated_too_shor, __pyx_k_Format_string_allocated_too_shor, sizeof(__pyx_k_Format_string_allocated_too_shor), 0, 1, 0, 0}, + {&__pyx_kp_u_Format_string_allocated_too_shor_2, __pyx_k_Format_string_allocated_too_shor_2, sizeof(__pyx_k_Format_string_allocated_too_shor_2), 0, 1, 0, 0}, + {&__pyx_n_s_ImportError, __pyx_k_ImportError, sizeof(__pyx_k_ImportError), 0, 0, 1, 1}, + {&__pyx_kp_u_Non_native_byte_order_not_suppor, __pyx_k_Non_native_byte_order_not_suppor, sizeof(__pyx_k_Non_native_byte_order_not_suppor), 0, 1, 0, 0}, + {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1}, + {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1}, + {&__pyx_n_s_barycentric_weight, __pyx_k_barycentric_weight, sizeof(__pyx_k_barycentric_weight), 0, 0, 1, 1}, + {&__pyx_n_s_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 0, 1, 1}, + {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, + {&__pyx_n_s_colors, __pyx_k_colors, sizeof(__pyx_k_colors), 0, 0, 1, 1}, + {&__pyx_n_s_depth_buffer, __pyx_k_depth_buffer, sizeof(__pyx_k_depth_buffer), 0, 0, 1, 1}, + {&__pyx_n_s_filename, __pyx_k_filename, sizeof(__pyx_k_filename), 0, 0, 1, 1}, + {&__pyx_n_s_get_normal_core, __pyx_k_get_normal_core, sizeof(__pyx_k_get_normal_core), 0, 0, 1, 1}, + {&__pyx_n_s_h, __pyx_k_h, sizeof(__pyx_k_h), 0, 0, 1, 1}, + {&__pyx_n_s_image, __pyx_k_image, sizeof(__pyx_k_image), 0, 0, 1, 1}, + {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, + {&__pyx_kp_s_insightface_thirdparty_face3d_me, __pyx_k_insightface_thirdparty_face3d_me, sizeof(__pyx_k_insightface_thirdparty_face3d_me), 0, 0, 1, 0}, + {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, + {&__pyx_n_s_mapping_type, __pyx_k_mapping_type, sizeof(__pyx_k_mapping_type), 0, 0, 1, 1}, + {&__pyx_n_s_mesh_core_cython, __pyx_k_mesh_core_cython, sizeof(__pyx_k_mesh_core_cython), 0, 0, 1, 1}, + {&__pyx_n_s_mtl_name, __pyx_k_mtl_name, sizeof(__pyx_k_mtl_name), 0, 0, 1, 1}, + {&__pyx_kp_u_ndarray_is_not_C_contiguous, __pyx_k_ndarray_is_not_C_contiguous, sizeof(__pyx_k_ndarray_is_not_C_contiguous), 0, 1, 0, 0}, + {&__pyx_kp_u_ndarray_is_not_Fortran_contiguou, __pyx_k_ndarray_is_not_Fortran_contiguou, sizeof(__pyx_k_ndarray_is_not_Fortran_contiguou), 0, 1, 0, 0}, + {&__pyx_n_s_normal, __pyx_k_normal, sizeof(__pyx_k_normal), 0, 0, 1, 1}, + {&__pyx_n_s_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1}, + {&__pyx_n_s_ntexver, __pyx_k_ntexver, sizeof(__pyx_k_ntexver), 0, 0, 1, 1}, + {&__pyx_n_s_ntri, __pyx_k_ntri, sizeof(__pyx_k_ntri), 0, 0, 1, 1}, + {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1}, + {&__pyx_kp_s_numpy_core_multiarray_failed_to, __pyx_k_numpy_core_multiarray_failed_to, sizeof(__pyx_k_numpy_core_multiarray_failed_to), 0, 0, 1, 0}, + {&__pyx_kp_s_numpy_core_umath_failed_to_impor, __pyx_k_numpy_core_umath_failed_to_impor, sizeof(__pyx_k_numpy_core_umath_failed_to_impor), 0, 0, 1, 0}, + {&__pyx_n_s_nver, __pyx_k_nver, sizeof(__pyx_k_nver), 0, 0, 1, 1}, + {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1}, + {&__pyx_n_s_rasterize_triangles_core, __pyx_k_rasterize_triangles_core, sizeof(__pyx_k_rasterize_triangles_core), 0, 0, 1, 1}, + {&__pyx_n_s_render_colors_core, __pyx_k_render_colors_core, sizeof(__pyx_k_render_colors_core), 0, 0, 1, 1}, + {&__pyx_n_s_render_texture_core, __pyx_k_render_texture_core, sizeof(__pyx_k_render_texture_core), 0, 0, 1, 1}, + {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, + {&__pyx_n_s_tex_c, __pyx_k_tex_c, sizeof(__pyx_k_tex_c), 0, 0, 1, 1}, + {&__pyx_n_s_tex_coords, __pyx_k_tex_coords, sizeof(__pyx_k_tex_coords), 0, 0, 1, 1}, + {&__pyx_n_s_tex_h, __pyx_k_tex_h, sizeof(__pyx_k_tex_h), 0, 0, 1, 1}, + {&__pyx_n_s_tex_nver, __pyx_k_tex_nver, sizeof(__pyx_k_tex_nver), 0, 0, 1, 1}, + {&__pyx_n_s_tex_triangles, __pyx_k_tex_triangles, sizeof(__pyx_k_tex_triangles), 0, 0, 1, 1}, + {&__pyx_n_s_tex_w, __pyx_k_tex_w, sizeof(__pyx_k_tex_w), 0, 0, 1, 1}, + {&__pyx_n_s_texture, __pyx_k_texture, sizeof(__pyx_k_texture), 0, 0, 1, 1}, + {&__pyx_n_s_tri_normal, __pyx_k_tri_normal, sizeof(__pyx_k_tri_normal), 0, 0, 1, 1}, + {&__pyx_n_s_triangle_buffer, __pyx_k_triangle_buffer, sizeof(__pyx_k_triangle_buffer), 0, 0, 1, 1}, + {&__pyx_n_s_triangles, __pyx_k_triangles, sizeof(__pyx_k_triangles), 0, 0, 1, 1}, + {&__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_k_unknown_dtype_code_in_numpy_pxd, sizeof(__pyx_k_unknown_dtype_code_in_numpy_pxd), 0, 1, 0, 0}, + {&__pyx_n_s_uv_coords, __pyx_k_uv_coords, sizeof(__pyx_k_uv_coords), 0, 0, 1, 1}, + {&__pyx_n_s_vertices, __pyx_k_vertices, sizeof(__pyx_k_vertices), 0, 0, 1, 1}, + {&__pyx_n_s_w, __pyx_k_w, sizeof(__pyx_k_w), 0, 0, 1, 1}, + {&__pyx_n_s_write_obj_with_colors_texture_co, __pyx_k_write_obj_with_colors_texture_co, sizeof(__pyx_k_write_obj_with_colors_texture_co), 0, 0, 1, 1}, + {0, 0, 0, 0, 0, 0, 0} +}; +static int __Pyx_InitCachedBuiltins(void) { + __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) __PYX_ERR(1, 229, __pyx_L1_error) + __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(1, 242, __pyx_L1_error) + __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) __PYX_ERR(1, 810, __pyx_L1_error) + __pyx_builtin_ImportError = __Pyx_GetBuiltinName(__pyx_n_s_ImportError); if (!__pyx_builtin_ImportError) __PYX_ERR(1, 1000, __pyx_L1_error) + return 0; + __pyx_L1_error:; + return -1; +} + +static int __Pyx_InitCachedConstants(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":229 + * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) + * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): + * raise ValueError(u"ndarray is not C contiguous") # <<<<<<<<<<<<<< + * + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) + */ + __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_C_contiguous); if (unlikely(!__pyx_tuple_)) __PYX_ERR(1, 229, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple_); + __Pyx_GIVEREF(__pyx_tuple_); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":233 + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) + * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): + * raise ValueError(u"ndarray is not Fortran contiguous") # <<<<<<<<<<<<<< + * + * info.buf = PyArray_DATA(self) + */ + __pyx_tuple__2 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_Fortran_contiguou); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(1, 233, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__2); + __Pyx_GIVEREF(__pyx_tuple__2); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":263 + * if ((descr.byteorder == c'>' and little_endian) or + * (descr.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< + * if t == NPY_BYTE: f = "b" + * elif t == NPY_UBYTE: f = "B" + */ + __pyx_tuple__3 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__3)) __PYX_ERR(1, 263, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__3); + __Pyx_GIVEREF(__pyx_tuple__3); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":810 + * + * if (end - f) - (new_offset - offset[0]) < 15: + * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<< + * + * if ((child.byteorder == c'>' and little_endian) or + */ + __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor); if (unlikely(!__pyx_tuple__4)) __PYX_ERR(1, 810, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__4); + __Pyx_GIVEREF(__pyx_tuple__4); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":814 + * if ((child.byteorder == c'>' and little_endian) or + * (child.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< + * # One could encode it in the format string and have Cython + * # complain instead, BUT: < and > in format strings also imply + */ + __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(1, 814, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__5); + __Pyx_GIVEREF(__pyx_tuple__5); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":834 + * t = child.type_num + * if end - f < 5: + * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<< + * + * # Until ticket #99 is fixed, use integers to avoid warnings + */ + __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor_2); if (unlikely(!__pyx_tuple__6)) __PYX_ERR(1, 834, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__6); + __Pyx_GIVEREF(__pyx_tuple__6); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1000 + * _import_array() + * except Exception: + * raise ImportError("numpy.core.multiarray failed to import") # <<<<<<<<<<<<<< + * + * cdef inline int import_umath() except -1: + */ + __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_s_numpy_core_multiarray_failed_to); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(1, 1000, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__7); + __Pyx_GIVEREF(__pyx_tuple__7); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1006 + * _import_umath() + * except Exception: + * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< + * + * cdef inline int import_ufunc() except -1: + */ + __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_s_numpy_core_umath_failed_to_impor); if (unlikely(!__pyx_tuple__8)) __PYX_ERR(1, 1006, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__8); + __Pyx_GIVEREF(__pyx_tuple__8); + + /* "../../../../jack_ssd/home/jack/anaconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1012 + * _import_umath() + * except Exception: + * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< + */ + __pyx_tuple__9 = PyTuple_Pack(1, __pyx_kp_s_numpy_core_umath_failed_to_impor); if (unlikely(!__pyx_tuple__9)) __PYX_ERR(1, 1012, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__9); + __Pyx_GIVEREF(__pyx_tuple__9); + + /* "mesh_core_cython.pyx":40 + * int nver, int ntri, int ntexver) + * + * def get_normal_core(np.ndarray[float, ndim=2, mode = "c"] normal not None, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] tri_normal not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + __pyx_tuple__10 = PyTuple_Pack(4, __pyx_n_s_normal, __pyx_n_s_tri_normal, __pyx_n_s_triangles, __pyx_n_s_ntri); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(0, 40, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__10); + __Pyx_GIVEREF(__pyx_tuple__10); + __pyx_codeobj__11 = (PyObject*)__Pyx_PyCode_New(4, 0, 4, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__10, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_insightface_thirdparty_face3d_me, __pyx_n_s_get_normal_core, 40, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__11)) __PYX_ERR(0, 40, __pyx_L1_error) + + /* "mesh_core_cython.pyx":49 + * ntri) + * + * def rasterize_triangles_core( # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + __pyx_tuple__12 = PyTuple_Pack(9, __pyx_n_s_vertices, __pyx_n_s_triangles, __pyx_n_s_depth_buffer, __pyx_n_s_triangle_buffer, __pyx_n_s_barycentric_weight, __pyx_n_s_nver, __pyx_n_s_ntri, __pyx_n_s_h, __pyx_n_s_w); if (unlikely(!__pyx_tuple__12)) __PYX_ERR(0, 49, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__12); + __Pyx_GIVEREF(__pyx_tuple__12); + __pyx_codeobj__13 = (PyObject*)__Pyx_PyCode_New(9, 0, 9, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__12, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_insightface_thirdparty_face3d_me, __pyx_n_s_rasterize_triangles_core, 49, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__13)) __PYX_ERR(0, 49, __pyx_L1_error) + + /* "mesh_core_cython.pyx":64 + * h, w) + * + * def render_colors_core(np.ndarray[float, ndim=3, mode = "c"] image not None, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + __pyx_tuple__14 = PyTuple_Pack(10, __pyx_n_s_image, __pyx_n_s_vertices, __pyx_n_s_triangles, __pyx_n_s_colors, __pyx_n_s_depth_buffer, __pyx_n_s_nver, __pyx_n_s_ntri, __pyx_n_s_h, __pyx_n_s_w, __pyx_n_s_c); if (unlikely(!__pyx_tuple__14)) __PYX_ERR(0, 64, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__14); + __Pyx_GIVEREF(__pyx_tuple__14); + __pyx_codeobj__15 = (PyObject*)__Pyx_PyCode_New(10, 0, 10, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__14, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_insightface_thirdparty_face3d_me, __pyx_n_s_render_colors_core, 64, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__15)) __PYX_ERR(0, 64, __pyx_L1_error) + + /* "mesh_core_cython.pyx":79 + * h, w, c) + * + * def render_texture_core(np.ndarray[float, ndim=3, mode = "c"] image not None, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + __pyx_tuple__16 = PyTuple_Pack(17, __pyx_n_s_image, __pyx_n_s_vertices, __pyx_n_s_triangles, __pyx_n_s_texture, __pyx_n_s_tex_coords, __pyx_n_s_tex_triangles, __pyx_n_s_depth_buffer, __pyx_n_s_nver, __pyx_n_s_tex_nver, __pyx_n_s_ntri, __pyx_n_s_h, __pyx_n_s_w, __pyx_n_s_c, __pyx_n_s_tex_h, __pyx_n_s_tex_w, __pyx_n_s_tex_c, __pyx_n_s_mapping_type); if (unlikely(!__pyx_tuple__16)) __PYX_ERR(0, 79, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__16); + __Pyx_GIVEREF(__pyx_tuple__16); + __pyx_codeobj__17 = (PyObject*)__Pyx_PyCode_New(17, 0, 17, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__16, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_insightface_thirdparty_face3d_me, __pyx_n_s_render_texture_core, 79, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__17)) __PYX_ERR(0, 79, __pyx_L1_error) + + /* "mesh_core_cython.pyx":100 + * mapping_type) + * + * def write_obj_with_colors_texture_core(string filename, string mtl_name, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + __pyx_tuple__18 = PyTuple_Pack(9, __pyx_n_s_filename, __pyx_n_s_mtl_name, __pyx_n_s_vertices, __pyx_n_s_triangles, __pyx_n_s_colors, __pyx_n_s_uv_coords, __pyx_n_s_nver, __pyx_n_s_ntri, __pyx_n_s_ntexver); if (unlikely(!__pyx_tuple__18)) __PYX_ERR(0, 100, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__18); + __Pyx_GIVEREF(__pyx_tuple__18); + __pyx_codeobj__19 = (PyObject*)__Pyx_PyCode_New(9, 0, 9, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__18, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_insightface_thirdparty_face3d_me, __pyx_n_s_write_obj_with_colors_texture_co, 100, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__19)) __PYX_ERR(0, 100, __pyx_L1_error) + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} + +static int __Pyx_InitGlobals(void) { + if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error); + return 0; + __pyx_L1_error:; + return -1; +} + +static int __Pyx_modinit_global_init_code(void); /*proto*/ +static int __Pyx_modinit_variable_export_code(void); /*proto*/ +static int __Pyx_modinit_function_export_code(void); /*proto*/ +static int __Pyx_modinit_type_init_code(void); /*proto*/ +static int __Pyx_modinit_type_import_code(void); /*proto*/ +static int __Pyx_modinit_variable_import_code(void); /*proto*/ +static int __Pyx_modinit_function_import_code(void); /*proto*/ + +static int __Pyx_modinit_global_init_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); + /*--- Global init code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); + /*--- Variable export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); + /*--- Function export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_init_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); + /*--- Type init code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); + /*--- Type import code ---*/ + __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "type", + #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 + sizeof(PyTypeObject), + #else + sizeof(PyHeapTypeObject), + #endif + 0); if (unlikely(!__pyx_ptype_7cpython_4type_type)) __PYX_ERR(3, 9, __pyx_L1_error) + __pyx_ptype_5numpy_dtype = __Pyx_ImportType("numpy", "dtype", sizeof(PyArray_Descr), 0); if (unlikely(!__pyx_ptype_5numpy_dtype)) __PYX_ERR(1, 164, __pyx_L1_error) + __pyx_ptype_5numpy_flatiter = __Pyx_ImportType("numpy", "flatiter", sizeof(PyArrayIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_flatiter)) __PYX_ERR(1, 186, __pyx_L1_error) + __pyx_ptype_5numpy_broadcast = __Pyx_ImportType("numpy", "broadcast", sizeof(PyArrayMultiIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_broadcast)) __PYX_ERR(1, 190, __pyx_L1_error) + __pyx_ptype_5numpy_ndarray = __Pyx_ImportType("numpy", "ndarray", sizeof(PyArrayObject), 0); if (unlikely(!__pyx_ptype_5numpy_ndarray)) __PYX_ERR(1, 199, __pyx_L1_error) + __pyx_ptype_5numpy_ufunc = __Pyx_ImportType("numpy", "ufunc", sizeof(PyUFuncObject), 0); if (unlikely(!__pyx_ptype_5numpy_ufunc)) __PYX_ERR(1, 872, __pyx_L1_error) + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} + +static int __Pyx_modinit_variable_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); + /*--- Variable import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); + /*--- Function import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + + +#if PY_MAJOR_VERSION < 3 +#ifdef CYTHON_NO_PYINIT_EXPORT +#define __Pyx_PyMODINIT_FUNC void +#else +#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC +#endif +#else +#ifdef CYTHON_NO_PYINIT_EXPORT +#define __Pyx_PyMODINIT_FUNC PyObject * +#else +#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC +#endif +#endif +#ifndef CYTHON_SMALL_CODE +#if defined(__clang__) + #define CYTHON_SMALL_CODE +#elif defined(__GNUC__) + #define CYTHON_SMALL_CODE __attribute__((optimize("Os"))) +#else + #define CYTHON_SMALL_CODE +#endif +#endif + + +#if PY_MAJOR_VERSION < 3 +__Pyx_PyMODINIT_FUNC initmesh_core_cython(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC initmesh_core_cython(void) +#else +__Pyx_PyMODINIT_FUNC PyInit_mesh_core_cython(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC PyInit_mesh_core_cython(void) +#if CYTHON_PEP489_MULTI_PHASE_INIT +{ + return PyModuleDef_Init(&__pyx_moduledef); +} +static int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name) { + PyObject *value = PyObject_GetAttrString(spec, from_name); + int result = 0; + if (likely(value)) { + result = PyDict_SetItemString(moddict, to_name, value); + Py_DECREF(value); + } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } else { + result = -1; + } + return result; +} +static PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { + PyObject *module = NULL, *moddict, *modname; + if (__pyx_m) + return __Pyx_NewRef(__pyx_m); + modname = PyObject_GetAttrString(spec, "name"); + if (unlikely(!modname)) goto bad; + module = PyModule_NewObject(modname); + Py_DECREF(modname); + if (unlikely(!module)) goto bad; + moddict = PyModule_GetDict(module); + if (unlikely(!moddict)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__") < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__") < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__") < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__") < 0)) goto bad; + return module; +bad: + Py_XDECREF(module); + return NULL; +} + + +static int __pyx_pymod_exec_mesh_core_cython(PyObject *__pyx_pyinit_module) +#endif +#endif +{ + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + __Pyx_RefNannyDeclarations + #if CYTHON_PEP489_MULTI_PHASE_INIT + if (__pyx_m && __pyx_m == __pyx_pyinit_module) return 0; + #elif PY_MAJOR_VERSION >= 3 + if (__pyx_m) return __Pyx_NewRef(__pyx_m); + #endif + #if CYTHON_REFNANNY +__Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); +if (!__Pyx_RefNanny) { + PyErr_Clear(); + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); + if (!__Pyx_RefNanny) + Py_FatalError("failed to import 'refnanny' module"); +} +#endif + __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit_mesh_core_cython(void)", 0); + if (__Pyx_check_binary_version() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pyx_CyFunction_USED + if (__pyx_CyFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_FusedFunction_USED + if (__pyx_FusedFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Coroutine_USED + if (__pyx_Coroutine_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Generator_USED + if (__pyx_Generator_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_AsyncGen_USED + if (__pyx_AsyncGen_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_StopAsyncIteration_USED + if (__pyx_StopAsyncIteration_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + /*--- Library function declarations ---*/ + /*--- Threads initialization code ---*/ + #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS + #ifdef WITH_THREAD /* Python build with threading support? */ + PyEval_InitThreads(); + #endif + #endif + /*--- Module creation code ---*/ + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_m = __pyx_pyinit_module; + Py_INCREF(__pyx_m); + #else + #if PY_MAJOR_VERSION < 3 + __pyx_m = Py_InitModule4("mesh_core_cython", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); + #else + __pyx_m = PyModule_Create(&__pyx_moduledef); + #endif + if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_d); + __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_cython_runtime = PyImport_AddModule((char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) + #if CYTHON_COMPILING_IN_PYPY + Py_INCREF(__pyx_b); + #endif + if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error); + /*--- Initialize various global constants etc. ---*/ + if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) + if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + if (__pyx_module_is_main_mesh_core_cython) { + if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + } + #if PY_MAJOR_VERSION >= 3 + { + PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) + if (!PyDict_GetItemString(modules, "mesh_core_cython")) { + if (unlikely(PyDict_SetItemString(modules, "mesh_core_cython", __pyx_m) < 0)) __PYX_ERR(0, 1, __pyx_L1_error) + } + } + #endif + /*--- Builtin init code ---*/ + if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Constants init code ---*/ + if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Global type/function init code ---*/ + (void)__Pyx_modinit_global_init_code(); + (void)__Pyx_modinit_variable_export_code(); + (void)__Pyx_modinit_function_export_code(); + (void)__Pyx_modinit_type_init_code(); + if (unlikely(__Pyx_modinit_type_import_code() != 0)) goto __pyx_L1_error; + (void)__Pyx_modinit_variable_import_code(); + (void)__Pyx_modinit_function_import_code(); + /*--- Execution code ---*/ + #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) + if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + + /* "mesh_core_cython.pyx":1 + * import numpy as np # <<<<<<<<<<<<<< + * cimport numpy as np + * from libcpp.string cimport string + */ + __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "mesh_core_cython.pyx":6 + * + * # use the Numpy-C-API from Cython + * np.import_array() # <<<<<<<<<<<<<< + * + * # cdefine the signature of our c function + */ + __pyx_t_2 = __pyx_f_5numpy_import_array(); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 6, __pyx_L1_error) + + /* "mesh_core_cython.pyx":40 + * int nver, int ntri, int ntexver) + * + * def get_normal_core(np.ndarray[float, ndim=2, mode = "c"] normal not None, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] tri_normal not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_16mesh_core_cython_1get_normal_core, NULL, __pyx_n_s_mesh_core_cython); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 40, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_get_normal_core, __pyx_t_1) < 0) __PYX_ERR(0, 40, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "mesh_core_cython.pyx":49 + * ntri) + * + * def rasterize_triangles_core( # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_16mesh_core_cython_3rasterize_triangles_core, NULL, __pyx_n_s_mesh_core_cython); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 49, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_rasterize_triangles_core, __pyx_t_1) < 0) __PYX_ERR(0, 49, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "mesh_core_cython.pyx":64 + * h, w) + * + * def render_colors_core(np.ndarray[float, ndim=3, mode = "c"] image not None, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_16mesh_core_cython_5render_colors_core, NULL, __pyx_n_s_mesh_core_cython); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 64, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_render_colors_core, __pyx_t_1) < 0) __PYX_ERR(0, 64, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "mesh_core_cython.pyx":79 + * h, w, c) + * + * def render_texture_core(np.ndarray[float, ndim=3, mode = "c"] image not None, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_16mesh_core_cython_7render_texture_core, NULL, __pyx_n_s_mesh_core_cython); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 79, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_render_texture_core, __pyx_t_1) < 0) __PYX_ERR(0, 79, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "mesh_core_cython.pyx":100 + * mapping_type) + * + * def write_obj_with_colors_texture_core(string filename, string mtl_name, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_16mesh_core_cython_9write_obj_with_colors_texture_core, NULL, __pyx_n_s_mesh_core_cython); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 100, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_write_obj_with_colors_texture_co, __pyx_t_1) < 0) __PYX_ERR(0, 100, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "mesh_core_cython.pyx":1 + * import numpy as np # <<<<<<<<<<<<<< + * cimport numpy as np + * from libcpp.string cimport string + */ + __pyx_t_1 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "string.from_py":13 + * + * @cname("__pyx_convert_string_from_py_std__in_string") + * cdef string __pyx_convert_string_from_py_std__in_string(object o) except *: # <<<<<<<<<<<<<< + * cdef Py_ssize_t length + * cdef const char* data = __Pyx_PyObject_AsStringAndSize(o, &length) + */ + + /*--- Wrapped vars code ---*/ + + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + if (__pyx_m) { + if (__pyx_d) { + __Pyx_AddTraceback("init mesh_core_cython", 0, __pyx_lineno, __pyx_filename); + } + Py_DECREF(__pyx_m); __pyx_m = 0; + } else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ImportError, "init mesh_core_cython"); + } + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + #if CYTHON_PEP489_MULTI_PHASE_INIT + return (__pyx_m != NULL) ? 0 : -1; + #elif PY_MAJOR_VERSION >= 3 + return __pyx_m; + #else + return; + #endif +} + +/* --- Runtime support code --- */ +/* Refnanny */ +#if CYTHON_REFNANNY +static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { + PyObject *m = NULL, *p = NULL; + void *r = NULL; + m = PyImport_ImportModule((char *)modname); + if (!m) goto end; + p = PyObject_GetAttrString(m, (char *)"RefNannyAPI"); + if (!p) goto end; + r = PyLong_AsVoidPtr(p); +end: + Py_XDECREF(p); + Py_XDECREF(m); + return (__Pyx_RefNannyAPIStruct *)r; +} +#endif + +/* RaiseArgTupleInvalid */ +static void __Pyx_RaiseArgtupleInvalid( + const char* func_name, + int exact, + Py_ssize_t num_min, + Py_ssize_t num_max, + Py_ssize_t num_found) +{ + Py_ssize_t num_expected; + const char *more_or_less; + if (num_found < num_min) { + num_expected = num_min; + more_or_less = "at least"; + } else { + num_expected = num_max; + more_or_less = "at most"; + } + if (exact) { + more_or_less = "exactly"; + } + PyErr_Format(PyExc_TypeError, + "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", + func_name, more_or_less, num_expected, + (num_expected == 1) ? "" : "s", num_found); +} + +/* RaiseDoubleKeywords */ +static void __Pyx_RaiseDoubleKeywordsError( + const char* func_name, + PyObject* kw_name) +{ + PyErr_Format(PyExc_TypeError, + #if PY_MAJOR_VERSION >= 3 + "%s() got multiple values for keyword argument '%U'", func_name, kw_name); + #else + "%s() got multiple values for keyword argument '%s'", func_name, + PyString_AsString(kw_name)); + #endif +} + +/* ParseKeywords */ +static int __Pyx_ParseOptionalKeywords( + PyObject *kwds, + PyObject **argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + const char* function_name) +{ + PyObject *key = 0, *value = 0; + Py_ssize_t pos = 0; + PyObject*** name; + PyObject*** first_kw_arg = argnames + num_pos_args; + while (PyDict_Next(kwds, &pos, &key, &value)) { + name = first_kw_arg; + while (*name && (**name != key)) name++; + if (*name) { + values[name-argnames] = value; + continue; + } + name = first_kw_arg; + #if PY_MAJOR_VERSION < 3 + if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) { + while (*name) { + if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) + && _PyString_Eq(**name, key)) { + values[name-argnames] = value; + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + if ((**argname == key) || ( + (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) + && _PyString_Eq(**argname, key))) { + goto arg_passed_twice; + } + argname++; + } + } + } else + #endif + if (likely(PyUnicode_Check(key))) { + while (*name) { + int cmp = (**name == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 : + #endif + PyUnicode_Compare(**name, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) { + values[name-argnames] = value; + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + int cmp = (**argname == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 : + #endif + PyUnicode_Compare(**argname, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) goto arg_passed_twice; + argname++; + } + } + } else + goto invalid_keyword_type; + if (kwds2) { + if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; + } else { + goto invalid_keyword; + } + } + return 0; +arg_passed_twice: + __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; +invalid_keyword_type: + PyErr_Format(PyExc_TypeError, + "%.200s() keywords must be strings", function_name); + goto bad; +invalid_keyword: + PyErr_Format(PyExc_TypeError, + #if PY_MAJOR_VERSION < 3 + "%.200s() got an unexpected keyword argument '%.200s'", + function_name, PyString_AsString(key)); + #else + "%s() got an unexpected keyword argument '%U'", + function_name, key); + #endif +bad: + return -1; +} + +/* ArgTypeTest */ +static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact) +{ + if (unlikely(!type)) { + PyErr_SetString(PyExc_SystemError, "Missing type object"); + return 0; + } + else if (exact) { + #if PY_MAJOR_VERSION == 2 + if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1; + #endif + } + else { + if (likely(__Pyx_TypeCheck(obj, type))) return 1; + } + PyErr_Format(PyExc_TypeError, + "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)", + name, type->tp_name, Py_TYPE(obj)->tp_name); + return 0; +} + +/* IsLittleEndian */ +static CYTHON_INLINE int __Pyx_Is_Little_Endian(void) +{ + union { + uint32_t u32; + uint8_t u8[4]; + } S; + S.u32 = 0x01020304; + return S.u8[0] == 4; +} + +/* BufferFormatCheck */ +static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, + __Pyx_BufFmt_StackElem* stack, + __Pyx_TypeInfo* type) { + stack[0].field = &ctx->root; + stack[0].parent_offset = 0; + ctx->root.type = type; + ctx->root.name = "buffer dtype"; + ctx->root.offset = 0; + ctx->head = stack; + ctx->head->field = &ctx->root; + ctx->fmt_offset = 0; + ctx->head->parent_offset = 0; + ctx->new_packmode = '@'; + ctx->enc_packmode = '@'; + ctx->new_count = 1; + ctx->enc_count = 0; + ctx->enc_type = 0; + ctx->is_complex = 0; + ctx->is_valid_array = 0; + ctx->struct_alignment = 0; + while (type->typegroup == 'S') { + ++ctx->head; + ctx->head->field = type->fields; + ctx->head->parent_offset = 0; + type = type->fields->type; + } +} +static int __Pyx_BufFmt_ParseNumber(const char** ts) { + int count; + const char* t = *ts; + if (*t < '0' || *t > '9') { + return -1; + } else { + count = *t++ - '0'; + while (*t >= '0' && *t < '9') { + count *= 10; + count += *t++ - '0'; + } + } + *ts = t; + return count; +} +static int __Pyx_BufFmt_ExpectNumber(const char **ts) { + int number = __Pyx_BufFmt_ParseNumber(ts); + if (number == -1) + PyErr_Format(PyExc_ValueError,\ + "Does not understand character buffer dtype format string ('%c')", **ts); + return number; +} +static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) { + PyErr_Format(PyExc_ValueError, + "Unexpected format string character: '%c'", ch); +} +static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) { + switch (ch) { + case 'c': return "'char'"; + case 'b': return "'signed char'"; + case 'B': return "'unsigned char'"; + case 'h': return "'short'"; + case 'H': return "'unsigned short'"; + case 'i': return "'int'"; + case 'I': return "'unsigned int'"; + case 'l': return "'long'"; + case 'L': return "'unsigned long'"; + case 'q': return "'long long'"; + case 'Q': return "'unsigned long long'"; + case 'f': return (is_complex ? "'complex float'" : "'float'"); + case 'd': return (is_complex ? "'complex double'" : "'double'"); + case 'g': return (is_complex ? "'complex long double'" : "'long double'"); + case 'T': return "a struct"; + case 'O': return "Python object"; + case 'P': return "a pointer"; + case 's': case 'p': return "a string"; + case 0: return "end"; + default: return "unparseable format string"; + } +} +static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) { + switch (ch) { + case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; + case 'h': case 'H': return 2; + case 'i': case 'I': case 'l': case 'L': return 4; + case 'q': case 'Q': return 8; + case 'f': return (is_complex ? 8 : 4); + case 'd': return (is_complex ? 16 : 8); + case 'g': { + PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g').."); + return 0; + } + case 'O': case 'P': return sizeof(void*); + default: + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } +} +static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) { + switch (ch) { + case 'c': case 'b': case 'B': case 's': case 'p': return 1; + case 'h': case 'H': return sizeof(short); + case 'i': case 'I': return sizeof(int); + case 'l': case 'L': return sizeof(long); + #ifdef HAVE_LONG_LONG + case 'q': case 'Q': return sizeof(PY_LONG_LONG); + #endif + case 'f': return sizeof(float) * (is_complex ? 2 : 1); + case 'd': return sizeof(double) * (is_complex ? 2 : 1); + case 'g': return sizeof(long double) * (is_complex ? 2 : 1); + case 'O': case 'P': return sizeof(void*); + default: { + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } + } +} +typedef struct { char c; short x; } __Pyx_st_short; +typedef struct { char c; int x; } __Pyx_st_int; +typedef struct { char c; long x; } __Pyx_st_long; +typedef struct { char c; float x; } __Pyx_st_float; +typedef struct { char c; double x; } __Pyx_st_double; +typedef struct { char c; long double x; } __Pyx_st_longdouble; +typedef struct { char c; void *x; } __Pyx_st_void_p; +#ifdef HAVE_LONG_LONG +typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong; +#endif +static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, CYTHON_UNUSED int is_complex) { + switch (ch) { + case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; + case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short); + case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int); + case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long); +#ifdef HAVE_LONG_LONG + case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG); +#endif + case 'f': return sizeof(__Pyx_st_float) - sizeof(float); + case 'd': return sizeof(__Pyx_st_double) - sizeof(double); + case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double); + case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*); + default: + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } +} +/* These are for computing the padding at the end of the struct to align + on the first member of the struct. This will probably the same as above, + but we don't have any guarantees. + */ +typedef struct { short x; char c; } __Pyx_pad_short; +typedef struct { int x; char c; } __Pyx_pad_int; +typedef struct { long x; char c; } __Pyx_pad_long; +typedef struct { float x; char c; } __Pyx_pad_float; +typedef struct { double x; char c; } __Pyx_pad_double; +typedef struct { long double x; char c; } __Pyx_pad_longdouble; +typedef struct { void *x; char c; } __Pyx_pad_void_p; +#ifdef HAVE_LONG_LONG +typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong; +#endif +static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_complex) { + switch (ch) { + case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; + case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short); + case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int); + case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long); +#ifdef HAVE_LONG_LONG + case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG); +#endif + case 'f': return sizeof(__Pyx_pad_float) - sizeof(float); + case 'd': return sizeof(__Pyx_pad_double) - sizeof(double); + case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double); + case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*); + default: + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } +} +static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) { + switch (ch) { + case 'c': + return 'H'; + case 'b': case 'h': case 'i': + case 'l': case 'q': case 's': case 'p': + return 'I'; + case 'B': case 'H': case 'I': case 'L': case 'Q': + return 'U'; + case 'f': case 'd': case 'g': + return (is_complex ? 'C' : 'R'); + case 'O': + return 'O'; + case 'P': + return 'P'; + default: { + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } + } +} +static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) { + if (ctx->head == NULL || ctx->head->field == &ctx->root) { + const char* expected; + const char* quote; + if (ctx->head == NULL) { + expected = "end"; + quote = ""; + } else { + expected = ctx->head->field->type->name; + quote = "'"; + } + PyErr_Format(PyExc_ValueError, + "Buffer dtype mismatch, expected %s%s%s but got %s", + quote, expected, quote, + __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex)); + } else { + __Pyx_StructField* field = ctx->head->field; + __Pyx_StructField* parent = (ctx->head - 1)->field; + PyErr_Format(PyExc_ValueError, + "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'", + field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex), + parent->type->name, field->name); + } +} +static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) { + char group; + size_t size, offset, arraysize = 1; + if (ctx->enc_type == 0) return 0; + if (ctx->head->field->type->arraysize[0]) { + int i, ndim = 0; + if (ctx->enc_type == 's' || ctx->enc_type == 'p') { + ctx->is_valid_array = ctx->head->field->type->ndim == 1; + ndim = 1; + if (ctx->enc_count != ctx->head->field->type->arraysize[0]) { + PyErr_Format(PyExc_ValueError, + "Expected a dimension of size %zu, got %zu", + ctx->head->field->type->arraysize[0], ctx->enc_count); + return -1; + } + } + if (!ctx->is_valid_array) { + PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d", + ctx->head->field->type->ndim, ndim); + return -1; + } + for (i = 0; i < ctx->head->field->type->ndim; i++) { + arraysize *= ctx->head->field->type->arraysize[i]; + } + ctx->is_valid_array = 0; + ctx->enc_count = 1; + } + group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex); + do { + __Pyx_StructField* field = ctx->head->field; + __Pyx_TypeInfo* type = field->type; + if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') { + size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex); + } else { + size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex); + } + if (ctx->enc_packmode == '@') { + size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex); + size_t align_mod_offset; + if (align_at == 0) return -1; + align_mod_offset = ctx->fmt_offset % align_at; + if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset; + if (ctx->struct_alignment == 0) + ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type, + ctx->is_complex); + } + if (type->size != size || type->typegroup != group) { + if (type->typegroup == 'C' && type->fields != NULL) { + size_t parent_offset = ctx->head->parent_offset + field->offset; + ++ctx->head; + ctx->head->field = type->fields; + ctx->head->parent_offset = parent_offset; + continue; + } + if ((type->typegroup == 'H' || group == 'H') && type->size == size) { + } else { + __Pyx_BufFmt_RaiseExpected(ctx); + return -1; + } + } + offset = ctx->head->parent_offset + field->offset; + if (ctx->fmt_offset != offset) { + PyErr_Format(PyExc_ValueError, + "Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected", + (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset); + return -1; + } + ctx->fmt_offset += size; + if (arraysize) + ctx->fmt_offset += (arraysize - 1) * size; + --ctx->enc_count; + while (1) { + if (field == &ctx->root) { + ctx->head = NULL; + if (ctx->enc_count != 0) { + __Pyx_BufFmt_RaiseExpected(ctx); + return -1; + } + break; + } + ctx->head->field = ++field; + if (field->type == NULL) { + --ctx->head; + field = ctx->head->field; + continue; + } else if (field->type->typegroup == 'S') { + size_t parent_offset = ctx->head->parent_offset + field->offset; + if (field->type->fields->type == NULL) continue; + field = field->type->fields; + ++ctx->head; + ctx->head->field = field; + ctx->head->parent_offset = parent_offset; + break; + } else { + break; + } + } + } while (ctx->enc_count); + ctx->enc_type = 0; + ctx->is_complex = 0; + return 0; +} +static PyObject * +__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp) +{ + const char *ts = *tsp; + int i = 0, number; + int ndim = ctx->head->field->type->ndim; +; + ++ts; + if (ctx->new_count != 1) { + PyErr_SetString(PyExc_ValueError, + "Cannot handle repeated arrays in format string"); + return NULL; + } + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + while (*ts && *ts != ')') { + switch (*ts) { + case ' ': case '\f': case '\r': case '\n': case '\t': case '\v': continue; + default: break; + } + number = __Pyx_BufFmt_ExpectNumber(&ts); + if (number == -1) return NULL; + if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i]) + return PyErr_Format(PyExc_ValueError, + "Expected a dimension of size %zu, got %d", + ctx->head->field->type->arraysize[i], number); + if (*ts != ',' && *ts != ')') + return PyErr_Format(PyExc_ValueError, + "Expected a comma in format string, got '%c'", *ts); + if (*ts == ',') ts++; + i++; + } + if (i != ndim) + return PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d", + ctx->head->field->type->ndim, i); + if (!*ts) { + PyErr_SetString(PyExc_ValueError, + "Unexpected end of format string, expected ')'"); + return NULL; + } + ctx->is_valid_array = 1; + ctx->new_count = 1; + *tsp = ++ts; + return Py_None; +} +static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) { + int got_Z = 0; + while (1) { + switch(*ts) { + case 0: + if (ctx->enc_type != 0 && ctx->head == NULL) { + __Pyx_BufFmt_RaiseExpected(ctx); + return NULL; + } + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + if (ctx->head != NULL) { + __Pyx_BufFmt_RaiseExpected(ctx); + return NULL; + } + return ts; + case ' ': + case '\r': + case '\n': + ++ts; + break; + case '<': + if (!__Pyx_Is_Little_Endian()) { + PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler"); + return NULL; + } + ctx->new_packmode = '='; + ++ts; + break; + case '>': + case '!': + if (__Pyx_Is_Little_Endian()) { + PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler"); + return NULL; + } + ctx->new_packmode = '='; + ++ts; + break; + case '=': + case '@': + case '^': + ctx->new_packmode = *ts++; + break; + case 'T': + { + const char* ts_after_sub; + size_t i, struct_count = ctx->new_count; + size_t struct_alignment = ctx->struct_alignment; + ctx->new_count = 1; + ++ts; + if (*ts != '{') { + PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'"); + return NULL; + } + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->enc_type = 0; + ctx->enc_count = 0; + ctx->struct_alignment = 0; + ++ts; + ts_after_sub = ts; + for (i = 0; i != struct_count; ++i) { + ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts); + if (!ts_after_sub) return NULL; + } + ts = ts_after_sub; + if (struct_alignment) ctx->struct_alignment = struct_alignment; + } + break; + case '}': + { + size_t alignment = ctx->struct_alignment; + ++ts; + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->enc_type = 0; + if (alignment && ctx->fmt_offset % alignment) { + ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment); + } + } + return ts; + case 'x': + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->fmt_offset += ctx->new_count; + ctx->new_count = 1; + ctx->enc_count = 0; + ctx->enc_type = 0; + ctx->enc_packmode = ctx->new_packmode; + ++ts; + break; + case 'Z': + got_Z = 1; + ++ts; + if (*ts != 'f' && *ts != 'd' && *ts != 'g') { + __Pyx_BufFmt_RaiseUnexpectedChar('Z'); + return NULL; + } + CYTHON_FALLTHROUGH; + case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I': + case 'l': case 'L': case 'q': case 'Q': + case 'f': case 'd': case 'g': + case 'O': case 'p': + if (ctx->enc_type == *ts && got_Z == ctx->is_complex && + ctx->enc_packmode == ctx->new_packmode) { + ctx->enc_count += ctx->new_count; + ctx->new_count = 1; + got_Z = 0; + ++ts; + break; + } + CYTHON_FALLTHROUGH; + case 's': + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->enc_count = ctx->new_count; + ctx->enc_packmode = ctx->new_packmode; + ctx->enc_type = *ts; + ctx->is_complex = got_Z; + ++ts; + ctx->new_count = 1; + got_Z = 0; + break; + case ':': + ++ts; + while(*ts != ':') ++ts; + ++ts; + break; + case '(': + if (!__pyx_buffmt_parse_array(ctx, &ts)) return NULL; + break; + default: + { + int number = __Pyx_BufFmt_ExpectNumber(&ts); + if (number == -1) return NULL; + ctx->new_count = (size_t)number; + } + } + } +} + +/* BufferGetAndValidate */ + static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) { + if (unlikely(info->buf == NULL)) return; + if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL; + __Pyx_ReleaseBuffer(info); +} +static void __Pyx_ZeroBuffer(Py_buffer* buf) { + buf->buf = NULL; + buf->obj = NULL; + buf->strides = __Pyx_zeros; + buf->shape = __Pyx_zeros; + buf->suboffsets = __Pyx_minusones; +} +static int __Pyx__GetBufferAndValidate( + Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags, + int nd, int cast, __Pyx_BufFmt_StackElem* stack) +{ + buf->buf = NULL; + if (unlikely(__Pyx_GetBuffer(obj, buf, flags) == -1)) { + __Pyx_ZeroBuffer(buf); + return -1; + } + if (unlikely(buf->ndim != nd)) { + PyErr_Format(PyExc_ValueError, + "Buffer has wrong number of dimensions (expected %d, got %d)", + nd, buf->ndim); + goto fail; + } + if (!cast) { + __Pyx_BufFmt_Context ctx; + __Pyx_BufFmt_Init(&ctx, stack, dtype); + if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail; + } + if (unlikely((unsigned)buf->itemsize != dtype->size)) { + PyErr_Format(PyExc_ValueError, + "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "d byte%s) does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "d byte%s)", + buf->itemsize, (buf->itemsize > 1) ? "s" : "", + dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : ""); + goto fail; + } + if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones; + return 0; +fail:; + __Pyx_SafeReleaseBuffer(buf); + return -1; +} + +/* PyErrFetchRestore */ + #if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + tmp_type = tstate->curexc_type; + tmp_value = tstate->curexc_value; + tmp_tb = tstate->curexc_traceback; + tstate->curexc_type = type; + tstate->curexc_value = value; + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +} +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + *type = tstate->curexc_type; + *value = tstate->curexc_value; + *tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +} +#endif + +/* PyObjectGetAttrStr */ + #if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro)) + return tp->tp_getattro(obj, attr_name); +#if PY_MAJOR_VERSION < 3 + if (likely(tp->tp_getattr)) + return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); +#endif + return PyObject_GetAttr(obj, attr_name); +} +#endif + +/* GetBuiltinName */ + static PyObject *__Pyx_GetBuiltinName(PyObject *name) { + PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name); + if (unlikely(!result)) { + PyErr_Format(PyExc_NameError, +#if PY_MAJOR_VERSION >= 3 + "name '%U' is not defined", name); +#else + "name '%.200s' is not defined", PyString_AS_STRING(name)); +#endif + } + return result; +} + +/* PyObjectCall */ + #if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *result; + ternaryfunc call = func->ob_type->tp_call; + if (unlikely(!call)) + return PyObject_Call(func, arg, kw); + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + result = (*call)(func, arg, kw); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* RaiseException */ + #if PY_MAJOR_VERSION < 3 +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, + CYTHON_UNUSED PyObject *cause) { + __Pyx_PyThreadState_declare + Py_XINCREF(type); + if (!value || value == Py_None) + value = NULL; + else + Py_INCREF(value); + if (!tb || tb == Py_None) + tb = NULL; + else { + Py_INCREF(tb); + if (!PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto raise_error; + } + } + if (PyType_Check(type)) { +#if CYTHON_COMPILING_IN_PYPY + if (!value) { + Py_INCREF(Py_None); + value = Py_None; + } +#endif + PyErr_NormalizeException(&type, &value, &tb); + } else { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto raise_error; + } + value = type; + type = (PyObject*) Py_TYPE(type); + Py_INCREF(type); + if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto raise_error; + } + } + __Pyx_PyThreadState_assign + __Pyx_ErrRestore(type, value, tb); + return; +raise_error: + Py_XDECREF(value); + Py_XDECREF(type); + Py_XDECREF(tb); + return; +} +#else +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { + PyObject* owned_instance = NULL; + if (tb == Py_None) { + tb = 0; + } else if (tb && !PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto bad; + } + if (value == Py_None) + value = 0; + if (PyExceptionInstance_Check(type)) { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto bad; + } + value = type; + type = (PyObject*) Py_TYPE(value); + } else if (PyExceptionClass_Check(type)) { + PyObject *instance_class = NULL; + if (value && PyExceptionInstance_Check(value)) { + instance_class = (PyObject*) Py_TYPE(value); + if (instance_class != type) { + int is_subclass = PyObject_IsSubclass(instance_class, type); + if (!is_subclass) { + instance_class = NULL; + } else if (unlikely(is_subclass == -1)) { + goto bad; + } else { + type = instance_class; + } + } + } + if (!instance_class) { + PyObject *args; + if (!value) + args = PyTuple_New(0); + else if (PyTuple_Check(value)) { + Py_INCREF(value); + args = value; + } else + args = PyTuple_Pack(1, value); + if (!args) + goto bad; + owned_instance = PyObject_Call(type, args, NULL); + Py_DECREF(args); + if (!owned_instance) + goto bad; + value = owned_instance; + if (!PyExceptionInstance_Check(value)) { + PyErr_Format(PyExc_TypeError, + "calling %R should have returned an instance of " + "BaseException, not %R", + type, Py_TYPE(value)); + goto bad; + } + } + } else { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto bad; + } + if (cause) { + PyObject *fixed_cause; + if (cause == Py_None) { + fixed_cause = NULL; + } else if (PyExceptionClass_Check(cause)) { + fixed_cause = PyObject_CallObject(cause, NULL); + if (fixed_cause == NULL) + goto bad; + } else if (PyExceptionInstance_Check(cause)) { + fixed_cause = cause; + Py_INCREF(fixed_cause); + } else { + PyErr_SetString(PyExc_TypeError, + "exception causes must derive from " + "BaseException"); + goto bad; + } + PyException_SetCause(value, fixed_cause); + } + PyErr_SetObject(type, value); + if (tb) { +#if CYTHON_COMPILING_IN_PYPY + PyObject *tmp_type, *tmp_value, *tmp_tb; + PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); + Py_INCREF(tb); + PyErr_Restore(tmp_type, tmp_value, tb); + Py_XDECREF(tmp_tb); +#else + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject* tmp_tb = tstate->curexc_traceback; + if (tb != tmp_tb) { + Py_INCREF(tb); + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_tb); + } +#endif + } +bad: + Py_XDECREF(owned_instance); + return; +} +#endif + +/* PyCFunctionFastCall */ + #if CYTHON_FAST_PYCCALL +static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, PyObject **args, Py_ssize_t nargs) { + PyCFunctionObject *func = (PyCFunctionObject*)func_obj; + PyCFunction meth = PyCFunction_GET_FUNCTION(func); + PyObject *self = PyCFunction_GET_SELF(func); + int flags = PyCFunction_GET_FLAGS(func); + assert(PyCFunction_Check(func)); + assert(METH_FASTCALL == (flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS))); + assert(nargs >= 0); + assert(nargs == 0 || args != NULL); + /* _PyCFunction_FastCallDict() must not be called with an exception set, + because it may clear it (directly or indirectly) and so the + caller loses its exception */ + assert(!PyErr_Occurred()); + if ((PY_VERSION_HEX < 0x030700A0) || unlikely(flags & METH_KEYWORDS)) { + return (*((__Pyx_PyCFunctionFastWithKeywords)meth)) (self, args, nargs, NULL); + } else { + return (*((__Pyx_PyCFunctionFast)meth)) (self, args, nargs); + } +} +#endif + +/* PyFunctionFastCall */ + #if CYTHON_FAST_PYCALL +#include "frameobject.h" +static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na, + PyObject *globals) { + PyFrameObject *f; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject **fastlocals; + Py_ssize_t i; + PyObject *result; + assert(globals != NULL); + /* XXX Perhaps we should create a specialized + PyFrame_New() that doesn't take locals, but does + take builtins without sanity checking them. + */ + assert(tstate != NULL); + f = PyFrame_New(tstate, co, globals, NULL); + if (f == NULL) { + return NULL; + } + fastlocals = f->f_localsplus; + for (i = 0; i < na; i++) { + Py_INCREF(*args); + fastlocals[i] = *args++; + } + result = PyEval_EvalFrameEx(f,0); + ++tstate->recursion_depth; + Py_DECREF(f); + --tstate->recursion_depth; + return result; +} +#if 1 || PY_VERSION_HEX < 0x030600B1 +static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, int nargs, PyObject *kwargs) { + PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); + PyObject *globals = PyFunction_GET_GLOBALS(func); + PyObject *argdefs = PyFunction_GET_DEFAULTS(func); + PyObject *closure; +#if PY_MAJOR_VERSION >= 3 + PyObject *kwdefs; +#endif + PyObject *kwtuple, **k; + PyObject **d; + Py_ssize_t nd; + Py_ssize_t nk; + PyObject *result; + assert(kwargs == NULL || PyDict_Check(kwargs)); + nk = kwargs ? PyDict_Size(kwargs) : 0; + if (Py_EnterRecursiveCall((char*)" while calling a Python object")) { + return NULL; + } + if ( +#if PY_MAJOR_VERSION >= 3 + co->co_kwonlyargcount == 0 && +#endif + likely(kwargs == NULL || nk == 0) && + co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { + if (argdefs == NULL && co->co_argcount == nargs) { + result = __Pyx_PyFunction_FastCallNoKw(co, args, nargs, globals); + goto done; + } + else if (nargs == 0 && argdefs != NULL + && co->co_argcount == Py_SIZE(argdefs)) { + /* function called with no arguments, but all parameters have + a default value: use default values as arguments .*/ + args = &PyTuple_GET_ITEM(argdefs, 0); + result =__Pyx_PyFunction_FastCallNoKw(co, args, Py_SIZE(argdefs), globals); + goto done; + } + } + if (kwargs != NULL) { + Py_ssize_t pos, i; + kwtuple = PyTuple_New(2 * nk); + if (kwtuple == NULL) { + result = NULL; + goto done; + } + k = &PyTuple_GET_ITEM(kwtuple, 0); + pos = i = 0; + while (PyDict_Next(kwargs, &pos, &k[i], &k[i+1])) { + Py_INCREF(k[i]); + Py_INCREF(k[i+1]); + i += 2; + } + nk = i / 2; + } + else { + kwtuple = NULL; + k = NULL; + } + closure = PyFunction_GET_CLOSURE(func); +#if PY_MAJOR_VERSION >= 3 + kwdefs = PyFunction_GET_KW_DEFAULTS(func); +#endif + if (argdefs != NULL) { + d = &PyTuple_GET_ITEM(argdefs, 0); + nd = Py_SIZE(argdefs); + } + else { + d = NULL; + nd = 0; + } +#if PY_MAJOR_VERSION >= 3 + result = PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL, + args, nargs, + k, (int)nk, + d, (int)nd, kwdefs, closure); +#else + result = PyEval_EvalCodeEx(co, globals, (PyObject *)NULL, + args, nargs, + k, (int)nk, + d, (int)nd, closure); +#endif + Py_XDECREF(kwtuple); +done: + Py_LeaveRecursiveCall(); + return result; +} +#endif +#endif + +/* PyObjectCallMethO */ + #if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { + PyObject *self, *result; + PyCFunction cfunc; + cfunc = PyCFunction_GET_FUNCTION(func); + self = PyCFunction_GET_SELF(func); + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + result = cfunc(self, arg); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectCallOneArg */ + #if CYTHON_COMPILING_IN_CPYTHON +static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) { + PyObject *result; + PyObject *args = PyTuple_New(1); + if (unlikely(!args)) return NULL; + Py_INCREF(arg); + PyTuple_SET_ITEM(args, 0, arg); + result = __Pyx_PyObject_Call(func, args, NULL); + Py_DECREF(args); + return result; +} +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { +#if CYTHON_FAST_PYCALL + if (PyFunction_Check(func)) { + return __Pyx_PyFunction_FastCall(func, &arg, 1); + } +#endif + if (likely(PyCFunction_Check(func))) { + if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) { + return __Pyx_PyObject_CallMethO(func, arg); +#if CYTHON_FAST_PYCCALL + } else if (PyCFunction_GET_FLAGS(func) & METH_FASTCALL) { + return __Pyx_PyCFunction_FastCall(func, &arg, 1); +#endif + } + } + return __Pyx__PyObject_CallOneArg(func, arg); +} +#else +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { + PyObject *result; + PyObject *args = PyTuple_Pack(1, arg); + if (unlikely(!args)) return NULL; + result = __Pyx_PyObject_Call(func, args, NULL); + Py_DECREF(args); + return result; +} +#endif + +/* DictGetItem */ + #if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY +static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) { + PyObject *value; + value = PyDict_GetItemWithError(d, key); + if (unlikely(!value)) { + if (!PyErr_Occurred()) { + PyObject* args = PyTuple_Pack(1, key); + if (likely(args)) + PyErr_SetObject(PyExc_KeyError, args); + Py_XDECREF(args); + } + return NULL; + } + Py_INCREF(value); + return value; +} +#endif + +/* RaiseTooManyValuesToUnpack */ + static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { + PyErr_Format(PyExc_ValueError, + "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected); +} + +/* RaiseNeedMoreValuesToUnpack */ + static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { + PyErr_Format(PyExc_ValueError, + "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack", + index, (index == 1) ? "" : "s"); +} + +/* RaiseNoneIterError */ + static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); +} + +/* ExtTypeTest */ + static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) { + if (unlikely(!type)) { + PyErr_SetString(PyExc_SystemError, "Missing type object"); + return 0; + } + if (likely(__Pyx_TypeCheck(obj, type))) + return 1; + PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s", + Py_TYPE(obj)->tp_name, type->tp_name); + return 0; +} + +/* SaveResetException */ + #if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + #if PY_VERSION_HEX >= 0x030700A2 + *type = tstate->exc_state.exc_type; + *value = tstate->exc_state.exc_value; + *tb = tstate->exc_state.exc_traceback; + #else + *type = tstate->exc_type; + *value = tstate->exc_value; + *tb = tstate->exc_traceback; + #endif + Py_XINCREF(*type); + Py_XINCREF(*value); + Py_XINCREF(*tb); +} +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if PY_VERSION_HEX >= 0x030700A2 + tmp_type = tstate->exc_state.exc_type; + tmp_value = tstate->exc_state.exc_value; + tmp_tb = tstate->exc_state.exc_traceback; + tstate->exc_state.exc_type = type; + tstate->exc_state.exc_value = value; + tstate->exc_state.exc_traceback = tb; + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = type; + tstate->exc_value = value; + tstate->exc_traceback = tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +} +#endif + +/* PyErrExceptionMatches */ + #if CYTHON_FAST_THREAD_STATE +static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(tuple); +#if PY_MAJOR_VERSION >= 3 + for (i=0; icurexc_type; + if (exc_type == err) return 1; + if (unlikely(!exc_type)) return 0; + if (unlikely(PyTuple_Check(err))) + return __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err); + return __Pyx_PyErr_GivenExceptionMatches(exc_type, err); +} +#endif + +/* GetException */ + #if CYTHON_FAST_THREAD_STATE +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) { +#endif + PyObject *local_type, *local_value, *local_tb; +#if CYTHON_FAST_THREAD_STATE + PyObject *tmp_type, *tmp_value, *tmp_tb; + local_type = tstate->curexc_type; + local_value = tstate->curexc_value; + local_tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +#else + PyErr_Fetch(&local_type, &local_value, &local_tb); +#endif + PyErr_NormalizeException(&local_type, &local_value, &local_tb); +#if CYTHON_FAST_THREAD_STATE + if (unlikely(tstate->curexc_type)) +#else + if (unlikely(PyErr_Occurred())) +#endif + goto bad; + #if PY_MAJOR_VERSION >= 3 + if (local_tb) { + if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) + goto bad; + } + #endif + Py_XINCREF(local_tb); + Py_XINCREF(local_type); + Py_XINCREF(local_value); + *type = local_type; + *value = local_value; + *tb = local_tb; +#if CYTHON_FAST_THREAD_STATE + #if PY_VERSION_HEX >= 0x030700A2 + tmp_type = tstate->exc_state.exc_type; + tmp_value = tstate->exc_state.exc_value; + tmp_tb = tstate->exc_state.exc_traceback; + tstate->exc_state.exc_type = local_type; + tstate->exc_state.exc_value = local_value; + tstate->exc_state.exc_traceback = local_tb; + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = local_type; + tstate->exc_value = local_value; + tstate->exc_traceback = local_tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +#else + PyErr_SetExcInfo(local_type, local_value, local_tb); +#endif + return 0; +bad: + *type = 0; + *value = 0; + *tb = 0; + Py_XDECREF(local_type); + Py_XDECREF(local_value); + Py_XDECREF(local_tb); + return -1; +} + +/* Import */ + static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { + PyObject *empty_list = 0; + PyObject *module = 0; + PyObject *global_dict = 0; + PyObject *empty_dict = 0; + PyObject *list; + #if PY_MAJOR_VERSION < 3 + PyObject *py_import; + py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); + if (!py_import) + goto bad; + #endif + if (from_list) + list = from_list; + else { + empty_list = PyList_New(0); + if (!empty_list) + goto bad; + list = empty_list; + } + global_dict = PyModule_GetDict(__pyx_m); + if (!global_dict) + goto bad; + empty_dict = PyDict_New(); + if (!empty_dict) + goto bad; + { + #if PY_MAJOR_VERSION >= 3 + if (level == -1) { + if (strchr(__Pyx_MODULE_NAME, '.')) { + module = PyImport_ImportModuleLevelObject( + name, global_dict, empty_dict, list, 1); + if (!module) { + if (!PyErr_ExceptionMatches(PyExc_ImportError)) + goto bad; + PyErr_Clear(); + } + } + level = 0; + } + #endif + if (!module) { + #if PY_MAJOR_VERSION < 3 + PyObject *py_level = PyInt_FromLong(level); + if (!py_level) + goto bad; + module = PyObject_CallFunctionObjArgs(py_import, + name, global_dict, empty_dict, list, py_level, NULL); + Py_DECREF(py_level); + #else + module = PyImport_ImportModuleLevelObject( + name, global_dict, empty_dict, list, level); + #endif + } + } +bad: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(py_import); + #endif + Py_XDECREF(empty_list); + Py_XDECREF(empty_dict); + return module; +} + +/* CLineInTraceback */ + #ifndef CYTHON_CLINE_IN_TRACEBACK +static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_line) { + PyObject *use_cline; + PyObject *ptype, *pvalue, *ptraceback; +#if CYTHON_COMPILING_IN_CPYTHON + PyObject **cython_runtime_dict; +#endif + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); +#if CYTHON_COMPILING_IN_CPYTHON + cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); + if (likely(cython_runtime_dict)) { + use_cline = __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback); + } else +#endif + { + PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback); + if (use_cline_obj) { + use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True; + Py_DECREF(use_cline_obj); + } else { + PyErr_Clear(); + use_cline = NULL; + } + } + if (!use_cline) { + c_line = 0; + PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); + } + else if (PyObject_Not(use_cline) != 0) { + c_line = 0; + } + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + return c_line; +} +#endif + +/* CodeObjectCache */ + static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { + int start = 0, mid = 0, end = count - 1; + if (end >= 0 && code_line > entries[end].code_line) { + return count; + } + while (start < end) { + mid = start + (end - start) / 2; + if (code_line < entries[mid].code_line) { + end = mid; + } else if (code_line > entries[mid].code_line) { + start = mid + 1; + } else { + return mid; + } + } + if (code_line <= entries[mid].code_line) { + return mid; + } else { + return mid + 1; + } +} +static PyCodeObject *__pyx_find_code_object(int code_line) { + PyCodeObject* code_object; + int pos; + if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { + return NULL; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { + return NULL; + } + code_object = __pyx_code_cache.entries[pos].code_object; + Py_INCREF(code_object); + return code_object; +} +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { + int pos, i; + __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; + if (unlikely(!code_line)) { + return; + } + if (unlikely(!entries)) { + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); + if (likely(entries)) { + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = 64; + __pyx_code_cache.count = 1; + entries[0].code_line = code_line; + entries[0].code_object = code_object; + Py_INCREF(code_object); + } + return; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { + PyCodeObject* tmp = entries[pos].code_object; + entries[pos].code_object = code_object; + Py_DECREF(tmp); + return; + } + if (__pyx_code_cache.count == __pyx_code_cache.max_count) { + int new_max = __pyx_code_cache.max_count + 64; + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( + __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry)); + if (unlikely(!entries)) { + return; + } + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = new_max; + } + for (i=__pyx_code_cache.count; i>pos; i--) { + entries[i] = entries[i-1]; + } + entries[pos].code_line = code_line; + entries[pos].code_object = code_object; + __pyx_code_cache.count++; + Py_INCREF(code_object); +} + +/* AddTraceback */ + #include "compile.h" +#include "frameobject.h" +#include "traceback.h" +static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( + const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyObject *py_srcfile = 0; + PyObject *py_funcname = 0; + #if PY_MAJOR_VERSION < 3 + py_srcfile = PyString_FromString(filename); + #else + py_srcfile = PyUnicode_FromString(filename); + #endif + if (!py_srcfile) goto bad; + if (c_line) { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + #else + py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + #endif + } + else { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromString(funcname); + #else + py_funcname = PyUnicode_FromString(funcname); + #endif + } + if (!py_funcname) goto bad; + py_code = __Pyx_PyCode_New( + 0, + 0, + 0, + 0, + 0, + __pyx_empty_bytes, /*PyObject *code,*/ + __pyx_empty_tuple, /*PyObject *consts,*/ + __pyx_empty_tuple, /*PyObject *names,*/ + __pyx_empty_tuple, /*PyObject *varnames,*/ + __pyx_empty_tuple, /*PyObject *freevars,*/ + __pyx_empty_tuple, /*PyObject *cellvars,*/ + py_srcfile, /*PyObject *filename,*/ + py_funcname, /*PyObject *name,*/ + py_line, + __pyx_empty_bytes /*PyObject *lnotab*/ + ); + Py_DECREF(py_srcfile); + Py_DECREF(py_funcname); + return py_code; +bad: + Py_XDECREF(py_srcfile); + Py_XDECREF(py_funcname); + return NULL; +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyFrameObject *py_frame = 0; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + if (c_line) { + c_line = __Pyx_CLineForTraceback(tstate, c_line); + } + py_code = __pyx_find_code_object(c_line ? -c_line : py_line); + if (!py_code) { + py_code = __Pyx_CreateCodeObjectForTraceback( + funcname, c_line, py_line, filename); + if (!py_code) goto bad; + __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); + } + py_frame = PyFrame_New( + tstate, /*PyThreadState *tstate,*/ + py_code, /*PyCodeObject *code,*/ + __pyx_d, /*PyObject *globals,*/ + 0 /*PyObject *locals*/ + ); + if (!py_frame) goto bad; + __Pyx_PyFrame_SetLineNumber(py_frame, py_line); + PyTraceBack_Here(py_frame); +bad: + Py_XDECREF(py_code); + Py_XDECREF(py_frame); +} + +#if PY_MAJOR_VERSION < 3 +static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) { + if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags); + if (__Pyx_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) return __pyx_pw_5numpy_7ndarray_1__getbuffer__(obj, view, flags); + PyErr_Format(PyExc_TypeError, "'%.200s' does not have the buffer interface", Py_TYPE(obj)->tp_name); + return -1; +} +static void __Pyx_ReleaseBuffer(Py_buffer *view) { + PyObject *obj = view->obj; + if (!obj) return; + if (PyObject_CheckBuffer(obj)) { + PyBuffer_Release(view); + return; + } + if ((0)) {} + else if (__Pyx_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) __pyx_pw_5numpy_7ndarray_3__releasebuffer__(obj, view); + view->obj = NULL; + Py_DECREF(obj); +} +#endif + + + /* CIntFromPyVerify */ + #define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) +#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) +#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ + {\ + func_type value = func_value;\ + if (sizeof(target_type) < sizeof(func_type)) {\ + if (unlikely(value != (func_type) (target_type) value)) {\ + func_type zero = 0;\ + if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ + return (target_type) -1;\ + if (is_unsigned && unlikely(value < zero))\ + goto raise_neg_overflow;\ + else\ + goto raise_overflow;\ + }\ + }\ + return (target_type) value;\ + } + +/* Declarations */ + #if CYTHON_CCOMPLEX + #ifdef __cplusplus + static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { + return ::std::complex< float >(x, y); + } + #else + static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { + return x + y*(__pyx_t_float_complex)_Complex_I; + } + #endif +#else + static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { + __pyx_t_float_complex z; + z.real = x; + z.imag = y; + return z; + } +#endif + +/* Arithmetic */ + #if CYTHON_CCOMPLEX +#else + static CYTHON_INLINE int __Pyx_c_eq_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { + return (a.real == b.real) && (a.imag == b.imag); + } + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sum_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { + __pyx_t_float_complex z; + z.real = a.real + b.real; + z.imag = a.imag + b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_diff_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { + __pyx_t_float_complex z; + z.real = a.real - b.real; + z.imag = a.imag - b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prod_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { + __pyx_t_float_complex z; + z.real = a.real * b.real - a.imag * b.imag; + z.imag = a.real * b.imag + a.imag * b.real; + return z; + } + #if 1 + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quot_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { + if (b.imag == 0) { + return __pyx_t_float_complex_from_parts(a.real / b.real, a.imag / b.real); + } else if (fabsf(b.real) >= fabsf(b.imag)) { + if (b.real == 0 && b.imag == 0) { + return __pyx_t_float_complex_from_parts(a.real / b.real, a.imag / b.imag); + } else { + float r = b.imag / b.real; + float s = 1.0 / (b.real + b.imag * r); + return __pyx_t_float_complex_from_parts( + (a.real + a.imag * r) * s, (a.imag - a.real * r) * s); + } + } else { + float r = b.real / b.imag; + float s = 1.0 / (b.imag + b.real * r); + return __pyx_t_float_complex_from_parts( + (a.real * r + a.imag) * s, (a.imag * r - a.real) * s); + } + } + #else + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quot_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { + if (b.imag == 0) { + return __pyx_t_float_complex_from_parts(a.real / b.real, a.imag / b.real); + } else { + float denom = b.real * b.real + b.imag * b.imag; + return __pyx_t_float_complex_from_parts( + (a.real * b.real + a.imag * b.imag) / denom, + (a.imag * b.real - a.real * b.imag) / denom); + } + } + #endif + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_neg_float(__pyx_t_float_complex a) { + __pyx_t_float_complex z; + z.real = -a.real; + z.imag = -a.imag; + return z; + } + static CYTHON_INLINE int __Pyx_c_is_zero_float(__pyx_t_float_complex a) { + return (a.real == 0) && (a.imag == 0); + } + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conj_float(__pyx_t_float_complex a) { + __pyx_t_float_complex z; + z.real = a.real; + z.imag = -a.imag; + return z; + } + #if 1 + static CYTHON_INLINE float __Pyx_c_abs_float(__pyx_t_float_complex z) { + #if !defined(HAVE_HYPOT) || defined(_MSC_VER) + return sqrtf(z.real*z.real + z.imag*z.imag); + #else + return hypotf(z.real, z.imag); + #endif + } + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_pow_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { + __pyx_t_float_complex z; + float r, lnr, theta, z_r, z_theta; + if (b.imag == 0 && b.real == (int)b.real) { + if (b.real < 0) { + float denom = a.real * a.real + a.imag * a.imag; + a.real = a.real / denom; + a.imag = -a.imag / denom; + b.real = -b.real; + } + switch ((int)b.real) { + case 0: + z.real = 1; + z.imag = 0; + return z; + case 1: + return a; + case 2: + z = __Pyx_c_prod_float(a, a); + return __Pyx_c_prod_float(a, a); + case 3: + z = __Pyx_c_prod_float(a, a); + return __Pyx_c_prod_float(z, a); + case 4: + z = __Pyx_c_prod_float(a, a); + return __Pyx_c_prod_float(z, z); + } + } + if (a.imag == 0) { + if (a.real == 0) { + return a; + } else if (b.imag == 0) { + z.real = powf(a.real, b.real); + z.imag = 0; + return z; + } else if (a.real > 0) { + r = a.real; + theta = 0; + } else { + r = -a.real; + theta = atan2f(0, -1); + } + } else { + r = __Pyx_c_abs_float(a); + theta = atan2f(a.imag, a.real); + } + lnr = logf(r); + z_r = expf(lnr * b.real - theta * b.imag); + z_theta = theta * b.real + lnr * b.imag; + z.real = z_r * cosf(z_theta); + z.imag = z_r * sinf(z_theta); + return z; + } + #endif +#endif + +/* Declarations */ + #if CYTHON_CCOMPLEX + #ifdef __cplusplus + static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { + return ::std::complex< double >(x, y); + } + #else + static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { + return x + y*(__pyx_t_double_complex)_Complex_I; + } + #endif +#else + static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { + __pyx_t_double_complex z; + z.real = x; + z.imag = y; + return z; + } +#endif + +/* Arithmetic */ + #if CYTHON_CCOMPLEX +#else + static CYTHON_INLINE int __Pyx_c_eq_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + return (a.real == b.real) && (a.imag == b.imag); + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + z.real = a.real + b.real; + z.imag = a.imag + b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + z.real = a.real - b.real; + z.imag = a.imag - b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + z.real = a.real * b.real - a.imag * b.imag; + z.imag = a.real * b.imag + a.imag * b.real; + return z; + } + #if 1 + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + if (b.imag == 0) { + return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.real); + } else if (fabs(b.real) >= fabs(b.imag)) { + if (b.real == 0 && b.imag == 0) { + return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.imag); + } else { + double r = b.imag / b.real; + double s = 1.0 / (b.real + b.imag * r); + return __pyx_t_double_complex_from_parts( + (a.real + a.imag * r) * s, (a.imag - a.real * r) * s); + } + } else { + double r = b.real / b.imag; + double s = 1.0 / (b.imag + b.real * r); + return __pyx_t_double_complex_from_parts( + (a.real * r + a.imag) * s, (a.imag * r - a.real) * s); + } + } + #else + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + if (b.imag == 0) { + return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.real); + } else { + double denom = b.real * b.real + b.imag * b.imag; + return __pyx_t_double_complex_from_parts( + (a.real * b.real + a.imag * b.imag) / denom, + (a.imag * b.real - a.real * b.imag) / denom); + } + } + #endif + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg_double(__pyx_t_double_complex a) { + __pyx_t_double_complex z; + z.real = -a.real; + z.imag = -a.imag; + return z; + } + static CYTHON_INLINE int __Pyx_c_is_zero_double(__pyx_t_double_complex a) { + return (a.real == 0) && (a.imag == 0); + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj_double(__pyx_t_double_complex a) { + __pyx_t_double_complex z; + z.real = a.real; + z.imag = -a.imag; + return z; + } + #if 1 + static CYTHON_INLINE double __Pyx_c_abs_double(__pyx_t_double_complex z) { + #if !defined(HAVE_HYPOT) || defined(_MSC_VER) + return sqrt(z.real*z.real + z.imag*z.imag); + #else + return hypot(z.real, z.imag); + #endif + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + double r, lnr, theta, z_r, z_theta; + if (b.imag == 0 && b.real == (int)b.real) { + if (b.real < 0) { + double denom = a.real * a.real + a.imag * a.imag; + a.real = a.real / denom; + a.imag = -a.imag / denom; + b.real = -b.real; + } + switch ((int)b.real) { + case 0: + z.real = 1; + z.imag = 0; + return z; + case 1: + return a; + case 2: + z = __Pyx_c_prod_double(a, a); + return __Pyx_c_prod_double(a, a); + case 3: + z = __Pyx_c_prod_double(a, a); + return __Pyx_c_prod_double(z, a); + case 4: + z = __Pyx_c_prod_double(a, a); + return __Pyx_c_prod_double(z, z); + } + } + if (a.imag == 0) { + if (a.real == 0) { + return a; + } else if (b.imag == 0) { + z.real = pow(a.real, b.real); + z.imag = 0; + return z; + } else if (a.real > 0) { + r = a.real; + theta = 0; + } else { + r = -a.real; + theta = atan2(0, -1); + } + } else { + r = __Pyx_c_abs_double(a); + theta = atan2(a.imag, a.real); + } + lnr = log(r); + z_r = exp(lnr * b.real - theta * b.imag); + z_theta = theta * b.real + lnr * b.imag; + z.real = z_r * cos(z_theta); + z.imag = z_r * sin(z_theta); + return z; + } + #endif +#endif + +/* CIntToPy */ + static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) { + const int neg_one = (int) -1, const_zero = (int) 0; + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(int) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(int) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(int) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(int), + little, !is_unsigned); + } +} + +/* CIntToPy */ + static CYTHON_INLINE PyObject* __Pyx_PyInt_From_enum__NPY_TYPES(enum NPY_TYPES value) { + const enum NPY_TYPES neg_one = (enum NPY_TYPES) -1, const_zero = (enum NPY_TYPES) 0; + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(enum NPY_TYPES) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(enum NPY_TYPES) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(enum NPY_TYPES) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(enum NPY_TYPES) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(enum NPY_TYPES) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(enum NPY_TYPES), + little, !is_unsigned); + } +} + +/* CIntFromPy */ + static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { + const int neg_one = (int) -1, const_zero = (int) 0; + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if (sizeof(int) < sizeof(long)) { + __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (int) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (int) 0; + case 1: __PYX_VERIFY_RETURN_INT(int, digit, digits[0]) + case 2: + if (8 * sizeof(int) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 2 * PyLong_SHIFT) { + return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 3: + if (8 * sizeof(int) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 3 * PyLong_SHIFT) { + return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 4: + if (8 * sizeof(int) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 4 * PyLong_SHIFT) { + return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(int) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (int) 0; + case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, (sdigit) (-(sdigit)digits[0])) + case 1: __PYX_VERIFY_RETURN_INT(int, digit, +digits[0]) + case -2: + if (8 * sizeof(int) - 1 > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 2: + if (8 * sizeof(int) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -3: + if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 3: + if (8 * sizeof(int) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -4: + if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 4: + if (8 * sizeof(int) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { + return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + } +#endif + if (sizeof(int) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { +#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) + PyErr_SetString(PyExc_RuntimeError, + "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); +#else + int val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); + #if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } +#endif + return (int) -1; + } + } else { + int val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (int) -1; + val = __Pyx_PyInt_As_int(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to int"); + return (int) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to int"); + return (int) -1; +} + +/* CIntToPy */ + static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { + const long neg_one = (long) -1, const_zero = (long) 0; + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(long) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(long) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(long) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(long), + little, !is_unsigned); + } +} + +/* CIntFromPy */ + static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { + const long neg_one = (long) -1, const_zero = (long) 0; + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if (sizeof(long) < sizeof(long)) { + __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (long) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (long) 0; + case 1: __PYX_VERIFY_RETURN_INT(long, digit, digits[0]) + case 2: + if (8 * sizeof(long) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 2 * PyLong_SHIFT) { + return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 3: + if (8 * sizeof(long) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 3 * PyLong_SHIFT) { + return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 4: + if (8 * sizeof(long) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 4 * PyLong_SHIFT) { + return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(long) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (long) 0; + case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, (sdigit) (-(sdigit)digits[0])) + case 1: __PYX_VERIFY_RETURN_INT(long, digit, +digits[0]) + case -2: + if (8 * sizeof(long) - 1 > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 2: + if (8 * sizeof(long) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -3: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 3: + if (8 * sizeof(long) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -4: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 4: + if (8 * sizeof(long) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + } +#endif + if (sizeof(long) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { +#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) + PyErr_SetString(PyExc_RuntimeError, + "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); +#else + long val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); + #if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } +#endif + return (long) -1; + } + } else { + long val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (long) -1; + val = __Pyx_PyInt_As_long(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to long"); + return (long) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to long"); + return (long) -1; +} + +/* FastTypeChecks */ + #if CYTHON_COMPILING_IN_CPYTHON +static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { + while (a) { + a = a->tp_base; + if (a == b) + return 1; + } + return b == &PyBaseObject_Type; +} +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (a == b) return 1; + mro = a->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(a, b); +} +#if PY_MAJOR_VERSION == 2 +static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) { + PyObject *exception, *value, *tb; + int res; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&exception, &value, &tb); + res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0; + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + if (!res) { + res = PyObject_IsSubclass(err, exc_type2); + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + } + __Pyx_ErrRestore(exception, value, tb); + return res; +} +#else +static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { + int res = exc_type1 ? __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type1) : 0; + if (!res) { + res = __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); + } + return res; +} +#endif +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject* exc_type) { + if (likely(err == exc_type)) return 1; + if (likely(PyExceptionClass_Check(err))) { + return __Pyx_inner_PyErr_GivenExceptionMatches2(err, NULL, exc_type); + } + return PyErr_GivenExceptionMatches(err, exc_type); +} +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *exc_type1, PyObject *exc_type2) { + if (likely(err == exc_type1 || err == exc_type2)) return 1; + if (likely(PyExceptionClass_Check(err))) { + return __Pyx_inner_PyErr_GivenExceptionMatches2(err, exc_type1, exc_type2); + } + return (PyErr_GivenExceptionMatches(err, exc_type1) || PyErr_GivenExceptionMatches(err, exc_type2)); +} +#endif + +/* CheckBinaryVersion */ + static int __Pyx_check_binary_version(void) { + char ctversion[4], rtversion[4]; + PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION); + PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion()); + if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) { + char message[200]; + PyOS_snprintf(message, sizeof(message), + "compiletime version %s of module '%.100s' " + "does not match runtime version %s", + ctversion, __Pyx_MODULE_NAME, rtversion); + return PyErr_WarnEx(NULL, message, 1); + } + return 0; +} + +/* ModuleImport */ + #ifndef __PYX_HAVE_RT_ImportModule +#define __PYX_HAVE_RT_ImportModule +static PyObject *__Pyx_ImportModule(const char *name) { + PyObject *py_name = 0; + PyObject *py_module = 0; + py_name = __Pyx_PyIdentifier_FromString(name); + if (!py_name) + goto bad; + py_module = PyImport_Import(py_name); + Py_DECREF(py_name); + return py_module; +bad: + Py_XDECREF(py_name); + return 0; +} +#endif + +/* TypeImport */ + #ifndef __PYX_HAVE_RT_ImportType +#define __PYX_HAVE_RT_ImportType +static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, + size_t size, int strict) +{ + PyObject *py_module = 0; + PyObject *result = 0; + PyObject *py_name = 0; + char warning[200]; + Py_ssize_t basicsize; +#ifdef Py_LIMITED_API + PyObject *py_basicsize; +#endif + py_module = __Pyx_ImportModule(module_name); + if (!py_module) + goto bad; + py_name = __Pyx_PyIdentifier_FromString(class_name); + if (!py_name) + goto bad; + result = PyObject_GetAttr(py_module, py_name); + Py_DECREF(py_name); + py_name = 0; + Py_DECREF(py_module); + py_module = 0; + if (!result) + goto bad; + if (!PyType_Check(result)) { + PyErr_Format(PyExc_TypeError, + "%.200s.%.200s is not a type object", + module_name, class_name); + goto bad; + } +#ifndef Py_LIMITED_API + basicsize = ((PyTypeObject *)result)->tp_basicsize; +#else + py_basicsize = PyObject_GetAttrString(result, "__basicsize__"); + if (!py_basicsize) + goto bad; + basicsize = PyLong_AsSsize_t(py_basicsize); + Py_DECREF(py_basicsize); + py_basicsize = 0; + if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred()) + goto bad; +#endif + if (!strict && (size_t)basicsize > size) { + PyOS_snprintf(warning, sizeof(warning), + "%s.%s size changed, may indicate binary incompatibility. Expected %zd, got %zd", + module_name, class_name, basicsize, size); + if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad; + } + else if ((size_t)basicsize != size) { + PyErr_Format(PyExc_ValueError, + "%.200s.%.200s has the wrong size, try recompiling. Expected %zd, got %zd", + module_name, class_name, basicsize, size); + goto bad; + } + return (PyTypeObject *)result; +bad: + Py_XDECREF(py_module); + Py_XDECREF(result); + return NULL; +} +#endif + +/* InitStrings */ + static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { + while (t->p) { + #if PY_MAJOR_VERSION < 3 + if (t->is_unicode) { + *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); + } else if (t->intern) { + *t->p = PyString_InternFromString(t->s); + } else { + *t->p = PyString_FromStringAndSize(t->s, t->n - 1); + } + #else + if (t->is_unicode | t->is_str) { + if (t->intern) { + *t->p = PyUnicode_InternFromString(t->s); + } else if (t->encoding) { + *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); + } else { + *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); + } + } else { + *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); + } + #endif + if (!*t->p) + return -1; + if (PyObject_Hash(*t->p) == -1) + return -1; + ++t; + } + return 0; +} + +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { + return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str)); +} +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { + Py_ssize_t ignore; + return __Pyx_PyObject_AsStringAndSize(o, &ignore); +} +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +#if !CYTHON_PEP393_ENABLED +static const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + char* defenc_c; + PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); + if (!defenc) return NULL; + defenc_c = PyBytes_AS_STRING(defenc); +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + { + char* end = defenc_c + PyBytes_GET_SIZE(defenc); + char* c; + for (c = defenc_c; c < end; c++) { + if ((unsigned char) (*c) >= 128) { + PyUnicode_AsASCIIString(o); + return NULL; + } + } + } +#endif + *length = PyBytes_GET_SIZE(defenc); + return defenc_c; +} +#else +static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + if (likely(PyUnicode_IS_ASCII(o))) { + *length = PyUnicode_GET_LENGTH(o); + return PyUnicode_AsUTF8(o); + } else { + PyUnicode_AsASCIIString(o); + return NULL; + } +#else + return PyUnicode_AsUTF8AndSize(o, length); +#endif +} +#endif +#endif +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT + if ( +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + __Pyx_sys_getdefaultencoding_not_ascii && +#endif + PyUnicode_Check(o)) { + return __Pyx_PyUnicode_AsStringAndSize(o, length); + } else +#endif +#if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) + if (PyByteArray_Check(o)) { + *length = PyByteArray_GET_SIZE(o); + return PyByteArray_AS_STRING(o); + } else +#endif + { + char* result; + int r = PyBytes_AsStringAndSize(o, &result, length); + if (unlikely(r < 0)) { + return NULL; + } else { + return result; + } + } +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { + int is_true = x == Py_True; + if (is_true | (x == Py_False) | (x == Py_None)) return is_true; + else return PyObject_IsTrue(x); +} +static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { +#if PY_MAJOR_VERSION >= 3 + if (PyLong_Check(result)) { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "__int__ returned non-int (type %.200s). " + "The ability to return an instance of a strict subclass of int " + "is deprecated, and may be removed in a future version of Python.", + Py_TYPE(result)->tp_name)) { + Py_DECREF(result); + return NULL; + } + return result; + } +#endif + PyErr_Format(PyExc_TypeError, + "__%.4s__ returned non-%.4s (type %.200s)", + type_name, type_name, Py_TYPE(result)->tp_name); + Py_DECREF(result); + return NULL; +} +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { +#if CYTHON_USE_TYPE_SLOTS + PyNumberMethods *m; +#endif + const char *name = NULL; + PyObject *res = NULL; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x) || PyLong_Check(x))) +#else + if (likely(PyLong_Check(x))) +#endif + return __Pyx_NewRef(x); +#if CYTHON_USE_TYPE_SLOTS + m = Py_TYPE(x)->tp_as_number; + #if PY_MAJOR_VERSION < 3 + if (m && m->nb_int) { + name = "int"; + res = m->nb_int(x); + } + else if (m && m->nb_long) { + name = "long"; + res = m->nb_long(x); + } + #else + if (likely(m && m->nb_int)) { + name = "int"; + res = m->nb_int(x); + } + #endif +#else + if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { + res = PyNumber_Int(x); + } +#endif + if (likely(res)) { +#if PY_MAJOR_VERSION < 3 + if (unlikely(!PyInt_Check(res) && !PyLong_Check(res))) { +#else + if (unlikely(!PyLong_CheckExact(res))) { +#endif + return __Pyx_PyNumber_IntOrLongWrongResultType(res, name); + } + } + else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); + } + return res; +} +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { + Py_ssize_t ival; + PyObject *x; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(b))) { + if (sizeof(Py_ssize_t) >= sizeof(long)) + return PyInt_AS_LONG(b); + else + return PyInt_AsSsize_t(x); + } +#endif + if (likely(PyLong_CheckExact(b))) { + #if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)b)->ob_digit; + const Py_ssize_t size = Py_SIZE(b); + if (likely(__Pyx_sst_abs(size) <= 1)) { + ival = likely(size) ? digits[0] : 0; + if (size == -1) ival = -ival; + return ival; + } else { + switch (size) { + case 2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + } + } + #endif + return PyLong_AsSsize_t(b); + } + x = PyNumber_Index(b); + if (!x) return -1; + ival = PyInt_AsSsize_t(x); + Py_DECREF(x); + return ival; +} +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { + return PyInt_FromSize_t(ival); +} + + +#endif /* Py_PYTHON_H */ diff --git a/src/utils/dependencies/insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.cpp b/src/utils/dependencies/insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.cpp new file mode 100644 index 0000000..04a15dd --- /dev/null +++ b/src/utils/dependencies/insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.cpp @@ -0,0 +1,11757 @@ +/* Generated by Cython 3.0.9 */ + +/* BEGIN: Cython Metadata +{ + "distutils": { + "depends": [ + "insightface/thirdparty/face3d/mesh/cython/mesh_core.h" + ], + "include_dirs": [ + "insightface/thirdparty/face3d/mesh/cython" + ], + "language": "c++", + "name": "insightface.thirdparty.face3d.mesh.cython.mesh_core_cython", + "sources": [ + "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx", + "insightface/thirdparty/face3d/mesh/cython/mesh_core.cpp" + ] + }, + "module_name": "insightface.thirdparty.face3d.mesh.cython.mesh_core_cython" +} +END: Cython Metadata */ + +#ifndef PY_SSIZE_T_CLEAN +#define PY_SSIZE_T_CLEAN +#endif /* PY_SSIZE_T_CLEAN */ +#if defined(CYTHON_LIMITED_API) && 0 + #ifndef Py_LIMITED_API + #if CYTHON_LIMITED_API+0 > 0x03030000 + #define Py_LIMITED_API CYTHON_LIMITED_API + #else + #define Py_LIMITED_API 0x03030000 + #endif + #endif +#endif + +#include "Python.h" +#ifndef Py_PYTHON_H + #error Python headers needed to compile C extensions, please install development version of Python. +#elif PY_VERSION_HEX < 0x02070000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) + #error Cython requires Python 2.7+ or Python 3.3+. +#else +#if defined(CYTHON_LIMITED_API) && CYTHON_LIMITED_API +#define __PYX_EXTRA_ABI_MODULE_NAME "limited" +#else +#define __PYX_EXTRA_ABI_MODULE_NAME "" +#endif +#define CYTHON_ABI "3_0_9" __PYX_EXTRA_ABI_MODULE_NAME +#define __PYX_ABI_MODULE_NAME "_cython_" CYTHON_ABI +#define __PYX_TYPE_MODULE_PREFIX __PYX_ABI_MODULE_NAME "." +#define CYTHON_HEX_VERSION 0x030009F0 +#define CYTHON_FUTURE_DIVISION 1 +#include +#ifndef offsetof + #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) +#endif +#if !defined(_WIN32) && !defined(WIN32) && !defined(MS_WINDOWS) + #ifndef __stdcall + #define __stdcall + #endif + #ifndef __cdecl + #define __cdecl + #endif + #ifndef __fastcall + #define __fastcall + #endif +#endif +#ifndef DL_IMPORT + #define DL_IMPORT(t) t +#endif +#ifndef DL_EXPORT + #define DL_EXPORT(t) t +#endif +#define __PYX_COMMA , +#ifndef HAVE_LONG_LONG + #define HAVE_LONG_LONG +#endif +#ifndef PY_LONG_LONG + #define PY_LONG_LONG LONG_LONG +#endif +#ifndef Py_HUGE_VAL + #define Py_HUGE_VAL HUGE_VAL +#endif +#define __PYX_LIMITED_VERSION_HEX PY_VERSION_HEX +#if defined(GRAALVM_PYTHON) + /* For very preliminary testing purposes. Most variables are set the same as PyPy. + The existence of this section does not imply that anything works or is even tested */ + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 1 + #define CYTHON_COMPILING_IN_NOGIL 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #if PY_VERSION_HEX < 0x03050000 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS (PY_MAJOR_VERSION >= 3) + #endif + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif +#elif defined(PYPY_VERSION) + #define CYTHON_COMPILING_IN_PYPY 1 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_NOGIL 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #ifndef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #endif + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #if PY_VERSION_HEX < 0x03050000 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS (PY_MAJOR_VERSION >= 3) + #endif + #if PY_VERSION_HEX < 0x03090000 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #elif !defined(CYTHON_PEP489_MULTI_PHASE_INIT) + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1 && PYPY_VERSION_NUM >= 0x07030C00) + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif +#elif defined(CYTHON_LIMITED_API) + #ifdef Py_LIMITED_API + #undef __PYX_LIMITED_VERSION_HEX + #define __PYX_LIMITED_VERSION_HEX Py_LIMITED_API + #endif + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 1 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_NOGIL 0 + #undef CYTHON_CLINE_IN_TRACEBACK + #define CYTHON_CLINE_IN_TRACEBACK 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 1 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #ifndef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #endif + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 1 + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #endif + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif +#elif defined(Py_GIL_DISABLED) || defined(Py_NOGIL) + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_NOGIL 1 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #ifndef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 1 + #endif + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 +#else + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 1 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_NOGIL 0 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #ifndef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #endif + #ifndef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 1 + #endif + #if PY_MAJOR_VERSION < 3 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #ifndef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 1 + #endif + #ifndef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 1 + #endif + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #if PY_VERSION_HEX < 0x030300F0 || PY_VERSION_HEX >= 0x030B00A2 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #elif !defined(CYTHON_USE_UNICODE_WRITER) + #define CYTHON_USE_UNICODE_WRITER 1 + #endif + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #ifndef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 1 + #endif + #ifndef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL (PY_MAJOR_VERSION < 3 || PY_VERSION_HEX >= 0x03060000 && PY_VERSION_HEX < 0x030C00A6) + #endif + #ifndef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL (PY_VERSION_HEX >= 0x030700A1) + #endif + #ifndef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 1 + #endif + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #if PY_VERSION_HEX < 0x03050000 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #elif !defined(CYTHON_PEP489_MULTI_PHASE_INIT) + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #ifndef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #endif + #if PY_VERSION_HEX < 0x030400a1 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #elif !defined(CYTHON_USE_TP_FINALIZE) + #define CYTHON_USE_TP_FINALIZE 1 + #endif + #if PY_VERSION_HEX < 0x030600B1 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #elif !defined(CYTHON_USE_DICT_VERSIONS) + #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX < 0x030C00A5) + #endif + #if PY_VERSION_HEX < 0x030700A3 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #elif !defined(CYTHON_USE_EXC_INFO_STACK) + #define CYTHON_USE_EXC_INFO_STACK 1 + #endif + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 1 + #endif +#endif +#if !defined(CYTHON_FAST_PYCCALL) +#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) +#endif +#if !defined(CYTHON_VECTORCALL) +#define CYTHON_VECTORCALL (CYTHON_FAST_PYCCALL && PY_VERSION_HEX >= 0x030800B1) +#endif +#define CYTHON_BACKPORT_VECTORCALL (CYTHON_METH_FASTCALL && PY_VERSION_HEX < 0x030800B1) +#if CYTHON_USE_PYLONG_INTERNALS + #if PY_MAJOR_VERSION < 3 + #include "longintrepr.h" + #endif + #undef SHIFT + #undef BASE + #undef MASK + #ifdef SIZEOF_VOID_P + enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; + #endif +#endif +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif +#ifndef __has_cpp_attribute + #define __has_cpp_attribute(x) 0 +#endif +#ifndef CYTHON_RESTRICT + #if defined(__GNUC__) + #define CYTHON_RESTRICT __restrict__ + #elif defined(_MSC_VER) && _MSC_VER >= 1400 + #define CYTHON_RESTRICT __restrict + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_RESTRICT restrict + #else + #define CYTHON_RESTRICT + #endif +#endif +#ifndef CYTHON_UNUSED + #if defined(__cplusplus) + /* for clang __has_cpp_attribute(maybe_unused) is true even before C++17 + * but leads to warnings with -pedantic, since it is a C++17 feature */ + #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) + #if __has_cpp_attribute(maybe_unused) + #define CYTHON_UNUSED [[maybe_unused]] + #endif + #endif + #endif +#endif +#ifndef CYTHON_UNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_UNUSED_VAR +# if defined(__cplusplus) + template void CYTHON_UNUSED_VAR( const T& ) { } +# else +# define CYTHON_UNUSED_VAR(x) (void)(x) +# endif +#endif +#ifndef CYTHON_MAYBE_UNUSED_VAR + #define CYTHON_MAYBE_UNUSED_VAR(x) CYTHON_UNUSED_VAR(x) +#endif +#ifndef CYTHON_NCP_UNUSED +# if CYTHON_COMPILING_IN_CPYTHON +# define CYTHON_NCP_UNUSED +# else +# define CYTHON_NCP_UNUSED CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_USE_CPP_STD_MOVE + #if defined(__cplusplus) && (\ + __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)) + #define CYTHON_USE_CPP_STD_MOVE 1 + #else + #define CYTHON_USE_CPP_STD_MOVE 0 + #endif +#endif +#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) +#ifdef _MSC_VER + #ifndef _MSC_STDINT_H_ + #if _MSC_VER < 1300 + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; + #else + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; + #endif + #endif + #if _MSC_VER < 1300 + #ifdef _WIN64 + typedef unsigned long long __pyx_uintptr_t; + #else + typedef unsigned int __pyx_uintptr_t; + #endif + #else + #ifdef _WIN64 + typedef unsigned __int64 __pyx_uintptr_t; + #else + typedef unsigned __int32 __pyx_uintptr_t; + #endif + #endif +#else + #include + typedef uintptr_t __pyx_uintptr_t; +#endif +#ifndef CYTHON_FALLTHROUGH + #if defined(__cplusplus) + /* for clang __has_cpp_attribute(fallthrough) is true even before C++17 + * but leads to warnings with -pedantic, since it is a C++17 feature */ + #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) + #if __has_cpp_attribute(fallthrough) + #define CYTHON_FALLTHROUGH [[fallthrough]] + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_cpp_attribute(clang::fallthrough) + #define CYTHON_FALLTHROUGH [[clang::fallthrough]] + #elif __has_cpp_attribute(gnu::fallthrough) + #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] + #endif + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_attribute(fallthrough) + #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) + #else + #define CYTHON_FALLTHROUGH + #endif + #endif + #if defined(__clang__) && defined(__apple_build_version__) + #if __apple_build_version__ < 7000000 + #undef CYTHON_FALLTHROUGH + #define CYTHON_FALLTHROUGH + #endif + #endif +#endif +#ifdef __cplusplus + template + struct __PYX_IS_UNSIGNED_IMPL {static const bool value = T(0) < T(-1);}; + #define __PYX_IS_UNSIGNED(type) (__PYX_IS_UNSIGNED_IMPL::value) +#else + #define __PYX_IS_UNSIGNED(type) (((type)-1) > 0) +#endif +#if CYTHON_COMPILING_IN_PYPY == 1 + #define __PYX_NEED_TP_PRINT_SLOT (PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x030A0000) +#else + #define __PYX_NEED_TP_PRINT_SLOT (PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000) +#endif +#define __PYX_REINTERPRET_FUNCION(func_pointer, other_pointer) ((func_pointer)(void(*)(void))(other_pointer)) + +#ifndef __cplusplus + #error "Cython files generated with the C++ option must be compiled with a C++ compiler." +#endif +#ifndef CYTHON_INLINE + #if defined(__clang__) + #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) + #else + #define CYTHON_INLINE inline + #endif +#endif +template +void __Pyx_call_destructor(T& x) { + x.~T(); +} +template +class __Pyx_FakeReference { + public: + __Pyx_FakeReference() : ptr(NULL) { } + __Pyx_FakeReference(const T& ref) : ptr(const_cast(&ref)) { } + T *operator->() { return ptr; } + T *operator&() { return ptr; } + operator T&() { return *ptr; } + template bool operator ==(const U& other) const { return *ptr == other; } + template bool operator !=(const U& other) const { return *ptr != other; } + template bool operator==(const __Pyx_FakeReference& other) const { return *ptr == *other.ptr; } + template bool operator!=(const __Pyx_FakeReference& other) const { return *ptr != *other.ptr; } + private: + T *ptr; +}; + +#define __PYX_BUILD_PY_SSIZE_T "n" +#define CYTHON_FORMAT_SSIZE_T "z" +#if PY_MAJOR_VERSION < 3 + #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" + #define __Pyx_DefaultClassType PyClass_Type + #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#else + #define __Pyx_BUILTIN_MODULE_NAME "builtins" + #define __Pyx_DefaultClassType PyType_Type +#if CYTHON_COMPILING_IN_LIMITED_API + static CYTHON_INLINE PyObject* __Pyx_PyCode_New(int a, int p, int k, int l, int s, int f, + PyObject *code, PyObject *c, PyObject* n, PyObject *v, + PyObject *fv, PyObject *cell, PyObject* fn, + PyObject *name, int fline, PyObject *lnos) { + PyObject *exception_table = NULL; + PyObject *types_module=NULL, *code_type=NULL, *result=NULL; + #if __PYX_LIMITED_VERSION_HEX < 0x030B0000 + PyObject *version_info; + PyObject *py_minor_version = NULL; + #endif + long minor_version = 0; + PyObject *type, *value, *traceback; + PyErr_Fetch(&type, &value, &traceback); + #if __PYX_LIMITED_VERSION_HEX >= 0x030B0000 + minor_version = 11; + #else + if (!(version_info = PySys_GetObject("version_info"))) goto end; + if (!(py_minor_version = PySequence_GetItem(version_info, 1))) goto end; + minor_version = PyLong_AsLong(py_minor_version); + Py_DECREF(py_minor_version); + if (minor_version == -1 && PyErr_Occurred()) goto end; + #endif + if (!(types_module = PyImport_ImportModule("types"))) goto end; + if (!(code_type = PyObject_GetAttrString(types_module, "CodeType"))) goto end; + if (minor_version <= 7) { + (void)p; + result = PyObject_CallFunction(code_type, "iiiiiOOOOOOiOO", a, k, l, s, f, code, + c, n, v, fn, name, fline, lnos, fv, cell); + } else if (minor_version <= 10) { + result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOiOO", a,p, k, l, s, f, code, + c, n, v, fn, name, fline, lnos, fv, cell); + } else { + if (!(exception_table = PyBytes_FromStringAndSize(NULL, 0))) goto end; + result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOOiOO", a,p, k, l, s, f, code, + c, n, v, fn, name, name, fline, lnos, exception_table, fv, cell); + } + end: + Py_XDECREF(code_type); + Py_XDECREF(exception_table); + Py_XDECREF(types_module); + if (type) { + PyErr_Restore(type, value, traceback); + } + return result; + } + #ifndef CO_OPTIMIZED + #define CO_OPTIMIZED 0x0001 + #endif + #ifndef CO_NEWLOCALS + #define CO_NEWLOCALS 0x0002 + #endif + #ifndef CO_VARARGS + #define CO_VARARGS 0x0004 + #endif + #ifndef CO_VARKEYWORDS + #define CO_VARKEYWORDS 0x0008 + #endif + #ifndef CO_ASYNC_GENERATOR + #define CO_ASYNC_GENERATOR 0x0200 + #endif + #ifndef CO_GENERATOR + #define CO_GENERATOR 0x0020 + #endif + #ifndef CO_COROUTINE + #define CO_COROUTINE 0x0080 + #endif +#elif PY_VERSION_HEX >= 0x030B0000 + static CYTHON_INLINE PyCodeObject* __Pyx_PyCode_New(int a, int p, int k, int l, int s, int f, + PyObject *code, PyObject *c, PyObject* n, PyObject *v, + PyObject *fv, PyObject *cell, PyObject* fn, + PyObject *name, int fline, PyObject *lnos) { + PyCodeObject *result; + PyObject *empty_bytes = PyBytes_FromStringAndSize("", 0); + if (!empty_bytes) return NULL; + result = + #if PY_VERSION_HEX >= 0x030C0000 + PyUnstable_Code_NewWithPosOnlyArgs + #else + PyCode_NewWithPosOnlyArgs + #endif + (a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, name, fline, lnos, empty_bytes); + Py_DECREF(empty_bytes); + return result; + } +#elif PY_VERSION_HEX >= 0x030800B2 && !CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_NewWithPosOnlyArgs(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#else + #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#endif +#endif +#if PY_VERSION_HEX >= 0x030900A4 || defined(Py_IS_TYPE) + #define __Pyx_IS_TYPE(ob, type) Py_IS_TYPE(ob, type) +#else + #define __Pyx_IS_TYPE(ob, type) (((const PyObject*)ob)->ob_type == (type)) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_Is) + #define __Pyx_Py_Is(x, y) Py_Is(x, y) +#else + #define __Pyx_Py_Is(x, y) ((x) == (y)) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsNone) + #define __Pyx_Py_IsNone(ob) Py_IsNone(ob) +#else + #define __Pyx_Py_IsNone(ob) __Pyx_Py_Is((ob), Py_None) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsTrue) + #define __Pyx_Py_IsTrue(ob) Py_IsTrue(ob) +#else + #define __Pyx_Py_IsTrue(ob) __Pyx_Py_Is((ob), Py_True) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsFalse) + #define __Pyx_Py_IsFalse(ob) Py_IsFalse(ob) +#else + #define __Pyx_Py_IsFalse(ob) __Pyx_Py_Is((ob), Py_False) +#endif +#define __Pyx_NoneAsNull(obj) (__Pyx_Py_IsNone(obj) ? NULL : (obj)) +#if PY_VERSION_HEX >= 0x030900F0 && !CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyObject_GC_IsFinalized(o) PyObject_GC_IsFinalized(o) +#else + #define __Pyx_PyObject_GC_IsFinalized(o) _PyGC_FINALIZED(o) +#endif +#ifndef CO_COROUTINE + #define CO_COROUTINE 0x80 +#endif +#ifndef CO_ASYNC_GENERATOR + #define CO_ASYNC_GENERATOR 0x200 +#endif +#ifndef Py_TPFLAGS_CHECKTYPES + #define Py_TPFLAGS_CHECKTYPES 0 +#endif +#ifndef Py_TPFLAGS_HAVE_INDEX + #define Py_TPFLAGS_HAVE_INDEX 0 +#endif +#ifndef Py_TPFLAGS_HAVE_NEWBUFFER + #define Py_TPFLAGS_HAVE_NEWBUFFER 0 +#endif +#ifndef Py_TPFLAGS_HAVE_FINALIZE + #define Py_TPFLAGS_HAVE_FINALIZE 0 +#endif +#ifndef Py_TPFLAGS_SEQUENCE + #define Py_TPFLAGS_SEQUENCE 0 +#endif +#ifndef Py_TPFLAGS_MAPPING + #define Py_TPFLAGS_MAPPING 0 +#endif +#ifndef METH_STACKLESS + #define METH_STACKLESS 0 +#endif +#if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) + #ifndef METH_FASTCALL + #define METH_FASTCALL 0x80 + #endif + typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); + typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, + Py_ssize_t nargs, PyObject *kwnames); +#else + #if PY_VERSION_HEX >= 0x030d00A4 + # define __Pyx_PyCFunctionFast PyCFunctionFast + # define __Pyx_PyCFunctionFastWithKeywords PyCFunctionFastWithKeywords + #else + # define __Pyx_PyCFunctionFast _PyCFunctionFast + # define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords + #endif +#endif +#if CYTHON_METH_FASTCALL + #define __Pyx_METH_FASTCALL METH_FASTCALL + #define __Pyx_PyCFunction_FastCall __Pyx_PyCFunctionFast + #define __Pyx_PyCFunction_FastCallWithKeywords __Pyx_PyCFunctionFastWithKeywords +#else + #define __Pyx_METH_FASTCALL METH_VARARGS + #define __Pyx_PyCFunction_FastCall PyCFunction + #define __Pyx_PyCFunction_FastCallWithKeywords PyCFunctionWithKeywords +#endif +#if CYTHON_VECTORCALL + #define __pyx_vectorcallfunc vectorcallfunc + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET PY_VECTORCALL_ARGUMENTS_OFFSET + #define __Pyx_PyVectorcall_NARGS(n) PyVectorcall_NARGS((size_t)(n)) +#elif CYTHON_BACKPORT_VECTORCALL + typedef PyObject *(*__pyx_vectorcallfunc)(PyObject *callable, PyObject *const *args, + size_t nargsf, PyObject *kwnames); + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET ((size_t)1 << (8 * sizeof(size_t) - 1)) + #define __Pyx_PyVectorcall_NARGS(n) ((Py_ssize_t)(((size_t)(n)) & ~__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)) +#else + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET 0 + #define __Pyx_PyVectorcall_NARGS(n) ((Py_ssize_t)(n)) +#endif +#if PY_MAJOR_VERSION >= 0x030900B1 +#define __Pyx_PyCFunction_CheckExact(func) PyCFunction_CheckExact(func) +#else +#define __Pyx_PyCFunction_CheckExact(func) PyCFunction_Check(func) +#endif +#define __Pyx_CyOrPyCFunction_Check(func) PyCFunction_Check(func) +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func) (((PyCFunctionObject*)(func))->m_ml->ml_meth) +#elif !CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func) PyCFunction_GET_FUNCTION(func) +#endif +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_CyOrPyCFunction_GET_FLAGS(func) (((PyCFunctionObject*)(func))->m_ml->ml_flags) +static CYTHON_INLINE PyObject* __Pyx_CyOrPyCFunction_GET_SELF(PyObject *func) { + return (__Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_STATIC) ? NULL : ((PyCFunctionObject*)func)->m_self; +} +#endif +static CYTHON_INLINE int __Pyx__IsSameCFunction(PyObject *func, void *cfunc) { +#if CYTHON_COMPILING_IN_LIMITED_API + return PyCFunction_Check(func) && PyCFunction_GetFunction(func) == (PyCFunction) cfunc; +#else + return PyCFunction_Check(func) && PyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc; +#endif +} +#define __Pyx_IsSameCFunction(func, cfunc) __Pyx__IsSameCFunction(func, cfunc) +#if __PYX_LIMITED_VERSION_HEX < 0x030900B1 + #define __Pyx_PyType_FromModuleAndSpec(m, s, b) ((void)m, PyType_FromSpecWithBases(s, b)) + typedef PyObject *(*__Pyx_PyCMethod)(PyObject *, PyTypeObject *, PyObject *const *, size_t, PyObject *); +#else + #define __Pyx_PyType_FromModuleAndSpec(m, s, b) PyType_FromModuleAndSpec(m, s, b) + #define __Pyx_PyCMethod PyCMethod +#endif +#ifndef METH_METHOD + #define METH_METHOD 0x200 +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) + #define PyObject_Malloc(s) PyMem_Malloc(s) + #define PyObject_Free(p) PyMem_Free(p) + #define PyObject_Realloc(p) PyMem_Realloc(p) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) +#else + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyThreadState_Current PyThreadState_Get() +#elif !CYTHON_FAST_THREAD_STATE + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#elif PY_VERSION_HEX >= 0x030d00A1 + #define __Pyx_PyThreadState_Current PyThreadState_GetUnchecked() +#elif PY_VERSION_HEX >= 0x03060000 + #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() +#elif PY_VERSION_HEX >= 0x03000000 + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#else + #define __Pyx_PyThreadState_Current _PyThreadState_Current +#endif +#if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_INLINE void *__Pyx_PyModule_GetState(PyObject *op) +{ + void *result; + result = PyModule_GetState(op); + if (!result) + Py_FatalError("Couldn't find the module state"); + return result; +} +#endif +#define __Pyx_PyObject_GetSlot(obj, name, func_ctype) __Pyx_PyType_GetSlot(Py_TYPE(obj), name, func_ctype) +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyType_GetSlot(type, name, func_ctype) ((func_ctype) PyType_GetSlot((type), Py_##name)) +#else + #define __Pyx_PyType_GetSlot(type, name, func_ctype) ((type)->name) +#endif +#if PY_VERSION_HEX < 0x030700A2 && !defined(PyThread_tss_create) && !defined(Py_tss_NEEDS_INIT) +#include "pythread.h" +#define Py_tss_NEEDS_INIT 0 +typedef int Py_tss_t; +static CYTHON_INLINE int PyThread_tss_create(Py_tss_t *key) { + *key = PyThread_create_key(); + return 0; +} +static CYTHON_INLINE Py_tss_t * PyThread_tss_alloc(void) { + Py_tss_t *key = (Py_tss_t *)PyObject_Malloc(sizeof(Py_tss_t)); + *key = Py_tss_NEEDS_INIT; + return key; +} +static CYTHON_INLINE void PyThread_tss_free(Py_tss_t *key) { + PyObject_Free(key); +} +static CYTHON_INLINE int PyThread_tss_is_created(Py_tss_t *key) { + return *key != Py_tss_NEEDS_INIT; +} +static CYTHON_INLINE void PyThread_tss_delete(Py_tss_t *key) { + PyThread_delete_key(*key); + *key = Py_tss_NEEDS_INIT; +} +static CYTHON_INLINE int PyThread_tss_set(Py_tss_t *key, void *value) { + return PyThread_set_key_value(*key, value); +} +static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { + return PyThread_get_key_value(*key); +} +#endif +#if PY_MAJOR_VERSION < 3 + #if CYTHON_COMPILING_IN_PYPY + #if PYPY_VERSION_NUM < 0x07030600 + #if defined(__cplusplus) && __cplusplus >= 201402L + [[deprecated("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6")]] + #elif defined(__GNUC__) || defined(__clang__) + __attribute__ ((__deprecated__("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6"))) + #elif defined(_MSC_VER) + __declspec(deprecated("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6")) + #endif + static CYTHON_INLINE int PyGILState_Check(void) { + return 0; + } + #else // PYPY_VERSION_NUM < 0x07030600 + #endif // PYPY_VERSION_NUM < 0x07030600 + #else + static CYTHON_INLINE int PyGILState_Check(void) { + PyThreadState * tstate = _PyThreadState_Current; + return tstate && (tstate == PyGILState_GetThisThreadState()); + } + #endif +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030d0000 || defined(_PyDict_NewPresized) +#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) +#else +#define __Pyx_PyDict_NewPresized(n) PyDict_New() +#endif +#if PY_MAJOR_VERSION >= 3 || CYTHON_FUTURE_DIVISION + #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) +#else + #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX > 0x030600B4 && PY_VERSION_HEX < 0x030d0000 && CYTHON_USE_UNICODE_INTERNALS +#define __Pyx_PyDict_GetItemStrWithError(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) +static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStr(PyObject *dict, PyObject *name) { + PyObject *res = __Pyx_PyDict_GetItemStrWithError(dict, name); + if (res == NULL) PyErr_Clear(); + return res; +} +#elif PY_MAJOR_VERSION >= 3 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07020000) +#define __Pyx_PyDict_GetItemStrWithError PyDict_GetItemWithError +#define __Pyx_PyDict_GetItemStr PyDict_GetItem +#else +static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStrWithError(PyObject *dict, PyObject *name) { +#if CYTHON_COMPILING_IN_PYPY + return PyDict_GetItem(dict, name); +#else + PyDictEntry *ep; + PyDictObject *mp = (PyDictObject*) dict; + long hash = ((PyStringObject *) name)->ob_shash; + assert(hash != -1); + ep = (mp->ma_lookup)(mp, name, hash); + if (ep == NULL) { + return NULL; + } + return ep->me_value; +#endif +} +#define __Pyx_PyDict_GetItemStr PyDict_GetItem +#endif +#if CYTHON_USE_TYPE_SLOTS + #define __Pyx_PyType_GetFlags(tp) (((PyTypeObject *)tp)->tp_flags) + #define __Pyx_PyType_HasFeature(type, feature) ((__Pyx_PyType_GetFlags(type) & (feature)) != 0) + #define __Pyx_PyObject_GetIterNextFunc(obj) (Py_TYPE(obj)->tp_iternext) +#else + #define __Pyx_PyType_GetFlags(tp) (PyType_GetFlags((PyTypeObject *)tp)) + #define __Pyx_PyType_HasFeature(type, feature) PyType_HasFeature(type, feature) + #define __Pyx_PyObject_GetIterNextFunc(obj) PyIter_Next +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_SetItemOnTypeDict(tp, k, v) PyObject_GenericSetAttr((PyObject*)tp, k, v) +#else + #define __Pyx_SetItemOnTypeDict(tp, k, v) PyDict_SetItem(tp->tp_dict, k, v) +#endif +#if CYTHON_USE_TYPE_SPECS && PY_VERSION_HEX >= 0x03080000 +#define __Pyx_PyHeapTypeObject_GC_Del(obj) {\ + PyTypeObject *type = Py_TYPE((PyObject*)obj);\ + assert(__Pyx_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE));\ + PyObject_GC_Del(obj);\ + Py_DECREF(type);\ +} +#else +#define __Pyx_PyHeapTypeObject_GC_Del(obj) PyObject_GC_Del(obj) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define CYTHON_PEP393_ENABLED 1 + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GetLength(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_ReadChar(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((void)u, 1114111U) + #define __Pyx_PyUnicode_KIND(u) ((void)u, (0)) + #define __Pyx_PyUnicode_DATA(u) ((void*)u) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)k, PyUnicode_ReadChar((PyObject*)(d), i)) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GetLength(u)) +#elif PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) + #define CYTHON_PEP393_ENABLED 1 + #if PY_VERSION_HEX >= 0x030C0000 + #define __Pyx_PyUnicode_READY(op) (0) + #else + #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ + 0 : _PyUnicode_Ready((PyObject *)(op))) + #endif + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) + #define __Pyx_PyUnicode_KIND(u) ((int)PyUnicode_KIND(u)) + #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) + #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, (Py_UCS4) ch) + #if PY_VERSION_HEX >= 0x030C0000 + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u)) + #else + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03090000 + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : ((PyCompactUnicodeObject *)(u))->wstr_length)) + #else + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) + #endif + #endif +#else + #define CYTHON_PEP393_ENABLED 0 + #define PyUnicode_1BYTE_KIND 1 + #define PyUnicode_2BYTE_KIND 2 + #define PyUnicode_4BYTE_KIND 4 + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(Py_UNICODE) == 2) ? 65535U : 1114111U) + #define __Pyx_PyUnicode_KIND(u) ((int)sizeof(Py_UNICODE)) + #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((Py_UNICODE*)d)[i] = (Py_UNICODE) ch) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) +#endif +#if CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) +#else + #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ + PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) +#endif +#if CYTHON_COMPILING_IN_PYPY + #if !defined(PyUnicode_DecodeUnicodeEscape) + #define PyUnicode_DecodeUnicodeEscape(s, size, errors) PyUnicode_Decode(s, size, "unicode_escape", errors) + #endif + #if !defined(PyUnicode_Contains) || (PY_MAJOR_VERSION == 2 && PYPY_VERSION_NUM < 0x07030500) + #undef PyUnicode_Contains + #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) + #endif + #if !defined(PyByteArray_Check) + #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) + #endif + #if !defined(PyObject_Format) + #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) + #endif +#endif +#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) +#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) +#else + #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) +#endif +#if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) + #define PyObject_ASCII(o) PyObject_Repr(o) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBaseString_Type PyUnicode_Type + #define PyStringObject PyUnicodeObject + #define PyString_Type PyUnicode_Type + #define PyString_Check PyUnicode_Check + #define PyString_CheckExact PyUnicode_CheckExact +#ifndef PyObject_Unicode + #define PyObject_Unicode PyObject_Str +#endif +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) + #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) +#else + #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) + #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) +#endif +#if CYTHON_COMPILING_IN_CPYTHON + #define __Pyx_PySequence_ListKeepNew(obj)\ + (likely(PyList_CheckExact(obj) && Py_REFCNT(obj) == 1) ? __Pyx_NewRef(obj) : PySequence_List(obj)) +#else + #define __Pyx_PySequence_ListKeepNew(obj) PySequence_List(obj) +#endif +#ifndef PySet_CheckExact + #define PySet_CheckExact(obj) __Pyx_IS_TYPE(obj, &PySet_Type) +#endif +#if PY_VERSION_HEX >= 0x030900A4 + #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SET_SIZE(obj, size) +#else + #define __Pyx_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size) +#endif +#if CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PySequence_ITEM(o, i) PySequence_ITEM(o, i) + #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) + #define __Pyx_PyTuple_SET_ITEM(o, i, v) (PyTuple_SET_ITEM(o, i, v), (0)) + #define __Pyx_PyList_SET_ITEM(o, i, v) (PyList_SET_ITEM(o, i, v), (0)) + #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_GET_SIZE(o) + #define __Pyx_PyList_GET_SIZE(o) PyList_GET_SIZE(o) + #define __Pyx_PySet_GET_SIZE(o) PySet_GET_SIZE(o) + #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_GET_SIZE(o) + #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_GET_SIZE(o) +#else + #define __Pyx_PySequence_ITEM(o, i) PySequence_GetItem(o, i) + #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) + #define __Pyx_PyTuple_SET_ITEM(o, i, v) PyTuple_SetItem(o, i, v) + #define __Pyx_PyList_SET_ITEM(o, i, v) PyList_SetItem(o, i, v) + #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_Size(o) + #define __Pyx_PyList_GET_SIZE(o) PyList_Size(o) + #define __Pyx_PySet_GET_SIZE(o) PySet_Size(o) + #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_Size(o) + #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_Size(o) +#endif +#if __PYX_LIMITED_VERSION_HEX >= 0x030d00A1 + #define __Pyx_PyImport_AddModuleRef(name) PyImport_AddModuleRef(name) +#else + static CYTHON_INLINE PyObject *__Pyx_PyImport_AddModuleRef(const char *name) { + PyObject *module = PyImport_AddModule(name); + Py_XINCREF(module); + return module; + } +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyIntObject PyLongObject + #define PyInt_Type PyLong_Type + #define PyInt_Check(op) PyLong_Check(op) + #define PyInt_CheckExact(op) PyLong_CheckExact(op) + #define __Pyx_Py3Int_Check(op) PyLong_Check(op) + #define __Pyx_Py3Int_CheckExact(op) PyLong_CheckExact(op) + #define PyInt_FromString PyLong_FromString + #define PyInt_FromUnicode PyLong_FromUnicode + #define PyInt_FromLong PyLong_FromLong + #define PyInt_FromSize_t PyLong_FromSize_t + #define PyInt_FromSsize_t PyLong_FromSsize_t + #define PyInt_AsLong PyLong_AsLong + #define PyInt_AS_LONG PyLong_AS_LONG + #define PyInt_AsSsize_t PyLong_AsSsize_t + #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask + #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask + #define PyNumber_Int PyNumber_Long +#else + #define __Pyx_Py3Int_Check(op) (PyLong_Check(op) || PyInt_Check(op)) + #define __Pyx_Py3Int_CheckExact(op) (PyLong_CheckExact(op) || PyInt_CheckExact(op)) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBoolObject PyLongObject +#endif +#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY + #ifndef PyUnicode_InternFromString + #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) + #endif +#endif +#if PY_VERSION_HEX < 0x030200A4 + typedef long Py_hash_t; + #define __Pyx_PyInt_FromHash_t PyInt_FromLong + #define __Pyx_PyInt_AsHash_t __Pyx_PyIndex_AsHash_t +#else + #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t + #define __Pyx_PyInt_AsHash_t __Pyx_PyIndex_AsSsize_t +#endif +#if CYTHON_USE_ASYNC_SLOTS + #if PY_VERSION_HEX >= 0x030500B1 + #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods + #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) + #else + #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) + #endif +#else + #define __Pyx_PyType_AsAsync(obj) NULL +#endif +#ifndef __Pyx_PyAsyncMethodsStruct + typedef struct { + unaryfunc am_await; + unaryfunc am_aiter; + unaryfunc am_anext; + } __Pyx_PyAsyncMethodsStruct; +#endif + +#if defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS) + #if !defined(_USE_MATH_DEFINES) + #define _USE_MATH_DEFINES + #endif +#endif +#include +#ifdef NAN +#define __PYX_NAN() ((float) NAN) +#else +static CYTHON_INLINE float __PYX_NAN() { + float value; + memset(&value, 0xFF, sizeof(value)); + return value; +} +#endif +#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) +#define __Pyx_truncl trunc +#else +#define __Pyx_truncl truncl +#endif + +#define __PYX_MARK_ERR_POS(f_index, lineno) \ + { __pyx_filename = __pyx_f[f_index]; (void)__pyx_filename; __pyx_lineno = lineno; (void)__pyx_lineno; __pyx_clineno = __LINE__; (void)__pyx_clineno; } +#define __PYX_ERR(f_index, lineno, Ln_error) \ + { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; } + +#ifdef CYTHON_EXTERN_C + #undef __PYX_EXTERN_C + #define __PYX_EXTERN_C CYTHON_EXTERN_C +#elif defined(__PYX_EXTERN_C) + #ifdef _MSC_VER + #pragma message ("Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead.") + #else + #warning Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead. + #endif +#else + #define __PYX_EXTERN_C extern "C++" +#endif + +#define __PYX_HAVE__insightface__thirdparty__face3d__mesh__cython__mesh_core_cython +#define __PYX_HAVE_API__insightface__thirdparty__face3d__mesh__cython__mesh_core_cython +/* Early includes */ +#include +#include + + /* Using NumPy API declarations from "numpy/__init__.cython-30.pxd" */ + +#include "numpy/arrayobject.h" +#include "numpy/ndarrayobject.h" +#include "numpy/ndarraytypes.h" +#include "numpy/arrayscalars.h" +#include "numpy/ufuncobject.h" +#include +#include "ios" +#include "new" +#include "stdexcept" +#include "typeinfo" +#include "mesh_core.h" +#ifdef _OPENMP +#include +#endif /* _OPENMP */ + +#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) +#define CYTHON_WITHOUT_ASSERTIONS +#endif + +typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; + const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; + +#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT (PY_MAJOR_VERSION >= 3 && __PYX_DEFAULT_STRING_ENCODING_IS_UTF8) +#define __PYX_DEFAULT_STRING_ENCODING "" +#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString +#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#define __Pyx_uchar_cast(c) ((unsigned char)c) +#define __Pyx_long_cast(x) ((long)x) +#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ + (sizeof(type) < sizeof(Py_ssize_t)) ||\ + (sizeof(type) > sizeof(Py_ssize_t) &&\ + likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX) &&\ + (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ + v == (type)PY_SSIZE_T_MIN))) ||\ + (sizeof(type) == sizeof(Py_ssize_t) &&\ + (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX))) ) +static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { + return (size_t) i < (size_t) limit; +} +#if defined (__cplusplus) && __cplusplus >= 201103L + #include + #define __Pyx_sst_abs(value) std::abs(value) +#elif SIZEOF_INT >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) abs(value) +#elif SIZEOF_LONG >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) labs(value) +#elif defined (_MSC_VER) + #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define __Pyx_sst_abs(value) llabs(value) +#elif defined (__GNUC__) + #define __Pyx_sst_abs(value) __builtin_llabs(value) +#else + #define __Pyx_sst_abs(value) ((value<0) ? -value : value) +#endif +static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s); +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); +static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char*); +#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) +#define __Pyx_PyBytes_FromString PyBytes_FromString +#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); +#if PY_MAJOR_VERSION < 3 + #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#else + #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize +#endif +#define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyObject_AsWritableString(s) ((char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableSString(s) ((signed char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) +#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) +#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) +#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) +#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) +#define __Pyx_PyUnicode_FromOrdinal(o) PyUnicode_FromOrdinal((int)o) +#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode +#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) +#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); +#define __Pyx_PySequence_Tuple(obj)\ + (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); +static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject*); +#if CYTHON_ASSUME_SAFE_MACROS +#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) +#else +#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) +#endif +#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) +#if PY_MAJOR_VERSION >= 3 +#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) +#else +#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) +#endif +#if CYTHON_USE_PYLONG_INTERNALS + #if PY_VERSION_HEX >= 0x030C00A7 + #ifndef _PyLong_SIGN_MASK + #define _PyLong_SIGN_MASK 3 + #endif + #ifndef _PyLong_NON_SIZE_BITS + #define _PyLong_NON_SIZE_BITS 3 + #endif + #define __Pyx_PyLong_Sign(x) (((PyLongObject*)x)->long_value.lv_tag & _PyLong_SIGN_MASK) + #define __Pyx_PyLong_IsNeg(x) ((__Pyx_PyLong_Sign(x) & 2) != 0) + #define __Pyx_PyLong_IsNonNeg(x) (!__Pyx_PyLong_IsNeg(x)) + #define __Pyx_PyLong_IsZero(x) (__Pyx_PyLong_Sign(x) & 1) + #define __Pyx_PyLong_IsPos(x) (__Pyx_PyLong_Sign(x) == 0) + #define __Pyx_PyLong_CompactValueUnsigned(x) (__Pyx_PyLong_Digits(x)[0]) + #define __Pyx_PyLong_DigitCount(x) ((Py_ssize_t) (((PyLongObject*)x)->long_value.lv_tag >> _PyLong_NON_SIZE_BITS)) + #define __Pyx_PyLong_SignedDigitCount(x)\ + ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * __Pyx_PyLong_DigitCount(x)) + #if defined(PyUnstable_Long_IsCompact) && defined(PyUnstable_Long_CompactValue) + #define __Pyx_PyLong_IsCompact(x) PyUnstable_Long_IsCompact((PyLongObject*) x) + #define __Pyx_PyLong_CompactValue(x) PyUnstable_Long_CompactValue((PyLongObject*) x) + #else + #define __Pyx_PyLong_IsCompact(x) (((PyLongObject*)x)->long_value.lv_tag < (2 << _PyLong_NON_SIZE_BITS)) + #define __Pyx_PyLong_CompactValue(x) ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * (Py_ssize_t) __Pyx_PyLong_Digits(x)[0]) + #endif + typedef Py_ssize_t __Pyx_compact_pylong; + typedef size_t __Pyx_compact_upylong; + #else + #define __Pyx_PyLong_IsNeg(x) (Py_SIZE(x) < 0) + #define __Pyx_PyLong_IsNonNeg(x) (Py_SIZE(x) >= 0) + #define __Pyx_PyLong_IsZero(x) (Py_SIZE(x) == 0) + #define __Pyx_PyLong_IsPos(x) (Py_SIZE(x) > 0) + #define __Pyx_PyLong_CompactValueUnsigned(x) ((Py_SIZE(x) == 0) ? 0 : __Pyx_PyLong_Digits(x)[0]) + #define __Pyx_PyLong_DigitCount(x) __Pyx_sst_abs(Py_SIZE(x)) + #define __Pyx_PyLong_SignedDigitCount(x) Py_SIZE(x) + #define __Pyx_PyLong_IsCompact(x) (Py_SIZE(x) == 0 || Py_SIZE(x) == 1 || Py_SIZE(x) == -1) + #define __Pyx_PyLong_CompactValue(x)\ + ((Py_SIZE(x) == 0) ? (sdigit) 0 : ((Py_SIZE(x) < 0) ? -(sdigit)__Pyx_PyLong_Digits(x)[0] : (sdigit)__Pyx_PyLong_Digits(x)[0])) + typedef sdigit __Pyx_compact_pylong; + typedef digit __Pyx_compact_upylong; + #endif + #if PY_VERSION_HEX >= 0x030C00A5 + #define __Pyx_PyLong_Digits(x) (((PyLongObject*)x)->long_value.ob_digit) + #else + #define __Pyx_PyLong_Digits(x) (((PyLongObject*)x)->ob_digit) + #endif +#endif +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII +#include +static int __Pyx_sys_getdefaultencoding_not_ascii; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + PyObject* ascii_chars_u = NULL; + PyObject* ascii_chars_b = NULL; + const char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + if (strcmp(default_encoding_c, "ascii") == 0) { + __Pyx_sys_getdefaultencoding_not_ascii = 0; + } else { + char ascii_chars[128]; + int c; + for (c = 0; c < 128; c++) { + ascii_chars[c] = (char) c; + } + __Pyx_sys_getdefaultencoding_not_ascii = 1; + ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); + if (!ascii_chars_u) goto bad; + ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); + if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { + PyErr_Format( + PyExc_ValueError, + "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", + default_encoding_c); + goto bad; + } + Py_DECREF(ascii_chars_u); + Py_DECREF(ascii_chars_b); + } + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + Py_XDECREF(ascii_chars_u); + Py_XDECREF(ascii_chars_b); + return -1; +} +#endif +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) +#else +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +#include +static char* __PYX_DEFAULT_STRING_ENCODING; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c) + 1); + if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; + strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + return -1; +} +#endif +#endif + + +/* Test for GCC > 2.95 */ +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) + #define likely(x) __builtin_expect(!!(x), 1) + #define unlikely(x) __builtin_expect(!!(x), 0) +#else /* !__GNUC__ or GCC < 2.95 */ + #define likely(x) (x) + #define unlikely(x) (x) +#endif /* __GNUC__ */ +static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } + +#if !CYTHON_USE_MODULE_STATE +static PyObject *__pyx_m = NULL; +#endif +static int __pyx_lineno; +static int __pyx_clineno = 0; +static const char * __pyx_cfilenm = __FILE__; +static const char *__pyx_filename; + +/* Header.proto */ +#if !defined(CYTHON_CCOMPLEX) + #if defined(__cplusplus) + #define CYTHON_CCOMPLEX 1 + #elif (defined(_Complex_I) && !defined(_MSC_VER)) || ((defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) && !defined(__STDC_NO_COMPLEX__) && !defined(_MSC_VER)) + #define CYTHON_CCOMPLEX 1 + #else + #define CYTHON_CCOMPLEX 0 + #endif +#endif +#if CYTHON_CCOMPLEX + #ifdef __cplusplus + #include + #else + #include + #endif +#endif +#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__) + #undef _Complex_I + #define _Complex_I 1.0fj +#endif + +/* #### Code section: filename_table ### */ + +static const char *__pyx_f[] = { + "", + "__init__.cython-30.pxd", + "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx", + "type.pxd", +}; +/* #### Code section: utility_code_proto_before_types ### */ +/* ForceInitThreads.proto */ +#ifndef __PYX_FORCE_INIT_THREADS + #define __PYX_FORCE_INIT_THREADS 0 +#endif + +/* BufferFormatStructs.proto */ +struct __Pyx_StructField_; +#define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0) +typedef struct { + const char* name; + struct __Pyx_StructField_* fields; + size_t size; + size_t arraysize[8]; + int ndim; + char typegroup; + char is_unsigned; + int flags; +} __Pyx_TypeInfo; +typedef struct __Pyx_StructField_ { + __Pyx_TypeInfo* type; + const char* name; + size_t offset; +} __Pyx_StructField; +typedef struct { + __Pyx_StructField* field; + size_t parent_offset; +} __Pyx_BufFmt_StackElem; +typedef struct { + __Pyx_StructField root; + __Pyx_BufFmt_StackElem* head; + size_t fmt_offset; + size_t new_count, enc_count; + size_t struct_alignment; + int is_complex; + char enc_type; + char new_packmode; + char enc_packmode; + char is_valid_array; +} __Pyx_BufFmt_Context; + +/* #### Code section: numeric_typedefs ### */ + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":730 + * # in Cython to enable them only on the right systems. + * + * ctypedef npy_int8 int8_t # <<<<<<<<<<<<<< + * ctypedef npy_int16 int16_t + * ctypedef npy_int32 int32_t + */ +typedef npy_int8 __pyx_t_5numpy_int8_t; + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":731 + * + * ctypedef npy_int8 int8_t + * ctypedef npy_int16 int16_t # <<<<<<<<<<<<<< + * ctypedef npy_int32 int32_t + * ctypedef npy_int64 int64_t + */ +typedef npy_int16 __pyx_t_5numpy_int16_t; + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":732 + * ctypedef npy_int8 int8_t + * ctypedef npy_int16 int16_t + * ctypedef npy_int32 int32_t # <<<<<<<<<<<<<< + * ctypedef npy_int64 int64_t + * #ctypedef npy_int96 int96_t + */ +typedef npy_int32 __pyx_t_5numpy_int32_t; + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":733 + * ctypedef npy_int16 int16_t + * ctypedef npy_int32 int32_t + * ctypedef npy_int64 int64_t # <<<<<<<<<<<<<< + * #ctypedef npy_int96 int96_t + * #ctypedef npy_int128 int128_t + */ +typedef npy_int64 __pyx_t_5numpy_int64_t; + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":737 + * #ctypedef npy_int128 int128_t + * + * ctypedef npy_uint8 uint8_t # <<<<<<<<<<<<<< + * ctypedef npy_uint16 uint16_t + * ctypedef npy_uint32 uint32_t + */ +typedef npy_uint8 __pyx_t_5numpy_uint8_t; + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":738 + * + * ctypedef npy_uint8 uint8_t + * ctypedef npy_uint16 uint16_t # <<<<<<<<<<<<<< + * ctypedef npy_uint32 uint32_t + * ctypedef npy_uint64 uint64_t + */ +typedef npy_uint16 __pyx_t_5numpy_uint16_t; + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":739 + * ctypedef npy_uint8 uint8_t + * ctypedef npy_uint16 uint16_t + * ctypedef npy_uint32 uint32_t # <<<<<<<<<<<<<< + * ctypedef npy_uint64 uint64_t + * #ctypedef npy_uint96 uint96_t + */ +typedef npy_uint32 __pyx_t_5numpy_uint32_t; + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":740 + * ctypedef npy_uint16 uint16_t + * ctypedef npy_uint32 uint32_t + * ctypedef npy_uint64 uint64_t # <<<<<<<<<<<<<< + * #ctypedef npy_uint96 uint96_t + * #ctypedef npy_uint128 uint128_t + */ +typedef npy_uint64 __pyx_t_5numpy_uint64_t; + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":744 + * #ctypedef npy_uint128 uint128_t + * + * ctypedef npy_float32 float32_t # <<<<<<<<<<<<<< + * ctypedef npy_float64 float64_t + * #ctypedef npy_float80 float80_t + */ +typedef npy_float32 __pyx_t_5numpy_float32_t; + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":745 + * + * ctypedef npy_float32 float32_t + * ctypedef npy_float64 float64_t # <<<<<<<<<<<<<< + * #ctypedef npy_float80 float80_t + * #ctypedef npy_float128 float128_t + */ +typedef npy_float64 __pyx_t_5numpy_float64_t; + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":754 + * # The int types are mapped a bit surprising -- + * # numpy.int corresponds to 'l' and numpy.long to 'q' + * ctypedef npy_long int_t # <<<<<<<<<<<<<< + * ctypedef npy_longlong longlong_t + * + */ +typedef npy_long __pyx_t_5numpy_int_t; + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":755 + * # numpy.int corresponds to 'l' and numpy.long to 'q' + * ctypedef npy_long int_t + * ctypedef npy_longlong longlong_t # <<<<<<<<<<<<<< + * + * ctypedef npy_ulong uint_t + */ +typedef npy_longlong __pyx_t_5numpy_longlong_t; + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":757 + * ctypedef npy_longlong longlong_t + * + * ctypedef npy_ulong uint_t # <<<<<<<<<<<<<< + * ctypedef npy_ulonglong ulonglong_t + * + */ +typedef npy_ulong __pyx_t_5numpy_uint_t; + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":758 + * + * ctypedef npy_ulong uint_t + * ctypedef npy_ulonglong ulonglong_t # <<<<<<<<<<<<<< + * + * ctypedef npy_intp intp_t + */ +typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t; + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":760 + * ctypedef npy_ulonglong ulonglong_t + * + * ctypedef npy_intp intp_t # <<<<<<<<<<<<<< + * ctypedef npy_uintp uintp_t + * + */ +typedef npy_intp __pyx_t_5numpy_intp_t; + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":761 + * + * ctypedef npy_intp intp_t + * ctypedef npy_uintp uintp_t # <<<<<<<<<<<<<< + * + * ctypedef npy_double float_t + */ +typedef npy_uintp __pyx_t_5numpy_uintp_t; + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":763 + * ctypedef npy_uintp uintp_t + * + * ctypedef npy_double float_t # <<<<<<<<<<<<<< + * ctypedef npy_double double_t + * ctypedef npy_longdouble longdouble_t + */ +typedef npy_double __pyx_t_5numpy_float_t; + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":764 + * + * ctypedef npy_double float_t + * ctypedef npy_double double_t # <<<<<<<<<<<<<< + * ctypedef npy_longdouble longdouble_t + * + */ +typedef npy_double __pyx_t_5numpy_double_t; + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":765 + * ctypedef npy_double float_t + * ctypedef npy_double double_t + * ctypedef npy_longdouble longdouble_t # <<<<<<<<<<<<<< + * + * ctypedef npy_cfloat cfloat_t + */ +typedef npy_longdouble __pyx_t_5numpy_longdouble_t; +/* #### Code section: complex_type_declarations ### */ +/* Declarations.proto */ +#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) + #ifdef __cplusplus + typedef ::std::complex< float > __pyx_t_float_complex; + #else + typedef float _Complex __pyx_t_float_complex; + #endif +#else + typedef struct { float real, imag; } __pyx_t_float_complex; +#endif +static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float, float); + +/* Declarations.proto */ +#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) + #ifdef __cplusplus + typedef ::std::complex< double > __pyx_t_double_complex; + #else + typedef double _Complex __pyx_t_double_complex; + #endif +#else + typedef struct { double real, imag; } __pyx_t_double_complex; +#endif +static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double); + +/* #### Code section: type_declarations ### */ + +/*--- Type declarations ---*/ + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":767 + * ctypedef npy_longdouble longdouble_t + * + * ctypedef npy_cfloat cfloat_t # <<<<<<<<<<<<<< + * ctypedef npy_cdouble cdouble_t + * ctypedef npy_clongdouble clongdouble_t + */ +typedef npy_cfloat __pyx_t_5numpy_cfloat_t; + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":768 + * + * ctypedef npy_cfloat cfloat_t + * ctypedef npy_cdouble cdouble_t # <<<<<<<<<<<<<< + * ctypedef npy_clongdouble clongdouble_t + * + */ +typedef npy_cdouble __pyx_t_5numpy_cdouble_t; + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":769 + * ctypedef npy_cfloat cfloat_t + * ctypedef npy_cdouble cdouble_t + * ctypedef npy_clongdouble clongdouble_t # <<<<<<<<<<<<<< + * + * ctypedef npy_cdouble complex_t + */ +typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t; + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":771 + * ctypedef npy_clongdouble clongdouble_t + * + * ctypedef npy_cdouble complex_t # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew1(a): + */ +typedef npy_cdouble __pyx_t_5numpy_complex_t; +/* #### Code section: utility_code_proto ### */ + +/* --- Runtime support code (head) --- */ +/* Refnanny.proto */ +#ifndef CYTHON_REFNANNY + #define CYTHON_REFNANNY 0 +#endif +#if CYTHON_REFNANNY + typedef struct { + void (*INCREF)(void*, PyObject*, Py_ssize_t); + void (*DECREF)(void*, PyObject*, Py_ssize_t); + void (*GOTREF)(void*, PyObject*, Py_ssize_t); + void (*GIVEREF)(void*, PyObject*, Py_ssize_t); + void* (*SetupContext)(const char*, Py_ssize_t, const char*); + void (*FinishContext)(void**); + } __Pyx_RefNannyAPIStruct; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); + #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; +#ifdef WITH_THREAD + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + if (acquire_gil) {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__));\ + PyGILState_Release(__pyx_gilstate_save);\ + } else {\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__));\ + } + #define __Pyx_RefNannyFinishContextNogil() {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __Pyx_RefNannyFinishContext();\ + PyGILState_Release(__pyx_gilstate_save);\ + } +#else + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__)) + #define __Pyx_RefNannyFinishContextNogil() __Pyx_RefNannyFinishContext() +#endif + #define __Pyx_RefNannyFinishContextNogil() {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __Pyx_RefNannyFinishContext();\ + PyGILState_Release(__pyx_gilstate_save);\ + } + #define __Pyx_RefNannyFinishContext()\ + __Pyx_RefNanny->FinishContext(&__pyx_refnanny) + #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_XINCREF(r) do { if((r) == NULL); else {__Pyx_INCREF(r); }} while(0) + #define __Pyx_XDECREF(r) do { if((r) == NULL); else {__Pyx_DECREF(r); }} while(0) + #define __Pyx_XGOTREF(r) do { if((r) == NULL); else {__Pyx_GOTREF(r); }} while(0) + #define __Pyx_XGIVEREF(r) do { if((r) == NULL); else {__Pyx_GIVEREF(r);}} while(0) +#else + #define __Pyx_RefNannyDeclarations + #define __Pyx_RefNannySetupContext(name, acquire_gil) + #define __Pyx_RefNannyFinishContextNogil() + #define __Pyx_RefNannyFinishContext() + #define __Pyx_INCREF(r) Py_INCREF(r) + #define __Pyx_DECREF(r) Py_DECREF(r) + #define __Pyx_GOTREF(r) + #define __Pyx_GIVEREF(r) + #define __Pyx_XINCREF(r) Py_XINCREF(r) + #define __Pyx_XDECREF(r) Py_XDECREF(r) + #define __Pyx_XGOTREF(r) + #define __Pyx_XGIVEREF(r) +#endif +#define __Pyx_Py_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; Py_XDECREF(tmp);\ + } while (0) +#define __Pyx_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_XDECREF(tmp);\ + } while (0) +#define __Pyx_DECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_DECREF(tmp);\ + } while (0) +#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) +#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) + +/* PyErrExceptionMatches.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) +static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); +#else +#define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) +#endif + +/* PyThreadStateGet.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; +#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; +#if PY_VERSION_HEX >= 0x030C00A6 +#define __Pyx_PyErr_Occurred() (__pyx_tstate->current_exception != NULL) +#define __Pyx_PyErr_CurrentExceptionType() (__pyx_tstate->current_exception ? (PyObject*) Py_TYPE(__pyx_tstate->current_exception) : (PyObject*) NULL) +#else +#define __Pyx_PyErr_Occurred() (__pyx_tstate->curexc_type != NULL) +#define __Pyx_PyErr_CurrentExceptionType() (__pyx_tstate->curexc_type) +#endif +#else +#define __Pyx_PyThreadState_declare +#define __Pyx_PyThreadState_assign +#define __Pyx_PyErr_Occurred() (PyErr_Occurred() != NULL) +#define __Pyx_PyErr_CurrentExceptionType() PyErr_Occurred() +#endif + +/* PyErrFetchRestore.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) +#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A6 +#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) +#else +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#endif +#else +#define __Pyx_PyErr_Clear() PyErr_Clear() +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) +#endif + +/* PyObjectGetAttrStr.proto */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) +#endif + +/* PyObjectGetAttrStrNoError.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name); + +/* GetBuiltinName.proto */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name); + +/* GetTopmostException.proto */ +#if CYTHON_USE_EXC_INFO_STACK && CYTHON_FAST_THREAD_STATE +static _PyErr_StackItem * __Pyx_PyErr_GetTopmostException(PyThreadState *tstate); +#endif + +/* SaveResetException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_ExceptionSave(type, value, tb) __Pyx__ExceptionSave(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#define __Pyx_ExceptionReset(type, value, tb) __Pyx__ExceptionReset(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +#else +#define __Pyx_ExceptionSave(type, value, tb) PyErr_GetExcInfo(type, value, tb) +#define __Pyx_ExceptionReset(type, value, tb) PyErr_SetExcInfo(type, value, tb) +#endif + +/* GetException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_GetException(type, value, tb) __Pyx__GetException(__pyx_tstate, type, value, tb) +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); +#endif + +/* PyObjectCall.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); +#else +#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) +#endif + +/* RaiseException.proto */ +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); + +/* TupleAndListFromArray.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n); +static CYTHON_INLINE PyObject* __Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n); +#endif + +/* IncludeStringH.proto */ +#include + +/* BytesEquals.proto */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); + +/* UnicodeEquals.proto */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); + +/* fastcall.proto */ +#if CYTHON_AVOID_BORROWED_REFS + #define __Pyx_Arg_VARARGS(args, i) PySequence_GetItem(args, i) +#elif CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_Arg_VARARGS(args, i) PyTuple_GET_ITEM(args, i) +#else + #define __Pyx_Arg_VARARGS(args, i) PyTuple_GetItem(args, i) +#endif +#if CYTHON_AVOID_BORROWED_REFS + #define __Pyx_Arg_NewRef_VARARGS(arg) __Pyx_NewRef(arg) + #define __Pyx_Arg_XDECREF_VARARGS(arg) Py_XDECREF(arg) +#else + #define __Pyx_Arg_NewRef_VARARGS(arg) arg + #define __Pyx_Arg_XDECREF_VARARGS(arg) +#endif +#define __Pyx_NumKwargs_VARARGS(kwds) PyDict_Size(kwds) +#define __Pyx_KwValues_VARARGS(args, nargs) NULL +#define __Pyx_GetKwValue_VARARGS(kw, kwvalues, s) __Pyx_PyDict_GetItemStrWithError(kw, s) +#define __Pyx_KwargsAsDict_VARARGS(kw, kwvalues) PyDict_Copy(kw) +#if CYTHON_METH_FASTCALL + #define __Pyx_Arg_FASTCALL(args, i) args[i] + #define __Pyx_NumKwargs_FASTCALL(kwds) PyTuple_GET_SIZE(kwds) + #define __Pyx_KwValues_FASTCALL(args, nargs) ((args) + (nargs)) + static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s); +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 + CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues); + #else + #define __Pyx_KwargsAsDict_FASTCALL(kw, kwvalues) _PyStack_AsDict(kwvalues, kw) + #endif + #define __Pyx_Arg_NewRef_FASTCALL(arg) arg /* no-op, __Pyx_Arg_FASTCALL is direct and this needs + to have the same reference counting */ + #define __Pyx_Arg_XDECREF_FASTCALL(arg) +#else + #define __Pyx_Arg_FASTCALL __Pyx_Arg_VARARGS + #define __Pyx_NumKwargs_FASTCALL __Pyx_NumKwargs_VARARGS + #define __Pyx_KwValues_FASTCALL __Pyx_KwValues_VARARGS + #define __Pyx_GetKwValue_FASTCALL __Pyx_GetKwValue_VARARGS + #define __Pyx_KwargsAsDict_FASTCALL __Pyx_KwargsAsDict_VARARGS + #define __Pyx_Arg_NewRef_FASTCALL(arg) __Pyx_Arg_NewRef_VARARGS(arg) + #define __Pyx_Arg_XDECREF_FASTCALL(arg) __Pyx_Arg_XDECREF_VARARGS(arg) +#endif +#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS +#define __Pyx_ArgsSlice_VARARGS(args, start, stop) __Pyx_PyTuple_FromArray(&__Pyx_Arg_VARARGS(args, start), stop - start) +#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) __Pyx_PyTuple_FromArray(&__Pyx_Arg_FASTCALL(args, start), stop - start) +#else +#define __Pyx_ArgsSlice_VARARGS(args, start, stop) PyTuple_GetSlice(args, start, stop) +#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) PyTuple_GetSlice(args, start, stop) +#endif + +/* RaiseArgTupleInvalid.proto */ +static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, + Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); + +/* RaiseDoubleKeywords.proto */ +static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); + +/* ParseKeywords.proto */ +static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject *const *kwvalues, + PyObject **argnames[], + PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, + const char* function_name); + +/* ArgTypeTest.proto */ +#define __Pyx_ArgTypeTest(obj, type, none_allowed, name, exact)\ + ((likely(__Pyx_IS_TYPE(obj, type) | (none_allowed && (obj == Py_None)))) ? 1 :\ + __Pyx__ArgTypeTest(obj, type, name, exact)) +static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact); + +/* IsLittleEndian.proto */ +static CYTHON_INLINE int __Pyx_Is_Little_Endian(void); + +/* BufferFormatCheck.proto */ +static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts); +static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, + __Pyx_BufFmt_StackElem* stack, + __Pyx_TypeInfo* type); + +/* BufferGetAndValidate.proto */ +#define __Pyx_GetBufferAndValidate(buf, obj, dtype, flags, nd, cast, stack)\ + ((obj == Py_None || obj == NULL) ?\ + (__Pyx_ZeroBuffer(buf), 0) :\ + __Pyx__GetBufferAndValidate(buf, obj, dtype, flags, nd, cast, stack)) +static int __Pyx__GetBufferAndValidate(Py_buffer* buf, PyObject* obj, + __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack); +static void __Pyx_ZeroBuffer(Py_buffer* buf); +static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info); +static Py_ssize_t __Pyx_minusones[] = { -1, -1, -1, -1, -1, -1, -1, -1 }; +static Py_ssize_t __Pyx_zeros[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + +/* MoveIfSupported.proto */ +#if CYTHON_USE_CPP_STD_MOVE + #include + #define __PYX_STD_MOVE_IF_SUPPORTED(x) std::move(x) +#else + #define __PYX_STD_MOVE_IF_SUPPORTED(x) x +#endif + +/* TypeImport.proto */ +#ifndef __PYX_HAVE_RT_ImportType_proto_3_0_9 +#define __PYX_HAVE_RT_ImportType_proto_3_0_9 +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L +#include +#endif +#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || __cplusplus >= 201103L +#define __PYX_GET_STRUCT_ALIGNMENT_3_0_9(s) alignof(s) +#else +#define __PYX_GET_STRUCT_ALIGNMENT_3_0_9(s) sizeof(void*) +#endif +enum __Pyx_ImportType_CheckSize_3_0_9 { + __Pyx_ImportType_CheckSize_Error_3_0_9 = 0, + __Pyx_ImportType_CheckSize_Warn_3_0_9 = 1, + __Pyx_ImportType_CheckSize_Ignore_3_0_9 = 2 +}; +static PyTypeObject *__Pyx_ImportType_3_0_9(PyObject* module, const char *module_name, const char *class_name, size_t size, size_t alignment, enum __Pyx_ImportType_CheckSize_3_0_9 check_size); +#endif + +/* Import.proto */ +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); + +/* ImportDottedModule.proto */ +static PyObject *__Pyx_ImportDottedModule(PyObject *name, PyObject *parts_tuple); +#if PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx_ImportDottedModule_WalkParts(PyObject *module, PyObject *name, PyObject *parts_tuple); +#endif + +/* IncludeStructmemberH.proto */ +#include + +/* FixUpExtensionType.proto */ +#if CYTHON_USE_TYPE_SPECS +static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type); +#endif + +/* FetchSharedCythonModule.proto */ +static PyObject *__Pyx_FetchSharedCythonABIModule(void); + +/* FetchCommonType.proto */ +#if !CYTHON_USE_TYPE_SPECS +static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type); +#else +static PyTypeObject* __Pyx_FetchCommonTypeFromSpec(PyObject *module, PyType_Spec *spec, PyObject *bases); +#endif + +/* PyMethodNew.proto */ +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) { + PyObject *typesModule=NULL, *methodType=NULL, *result=NULL; + CYTHON_UNUSED_VAR(typ); + if (!self) + return __Pyx_NewRef(func); + typesModule = PyImport_ImportModule("types"); + if (!typesModule) return NULL; + methodType = PyObject_GetAttrString(typesModule, "MethodType"); + Py_DECREF(typesModule); + if (!methodType) return NULL; + result = PyObject_CallFunctionObjArgs(methodType, func, self, NULL); + Py_DECREF(methodType); + return result; +} +#elif PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) { + CYTHON_UNUSED_VAR(typ); + if (!self) + return __Pyx_NewRef(func); + return PyMethod_New(func, self); +} +#else + #define __Pyx_PyMethod_New PyMethod_New +#endif + +/* PyVectorcallFastCallDict.proto */ +#if CYTHON_METH_FASTCALL +static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw); +#endif + +/* CythonFunctionShared.proto */ +#define __Pyx_CyFunction_USED +#define __Pyx_CYFUNCTION_STATICMETHOD 0x01 +#define __Pyx_CYFUNCTION_CLASSMETHOD 0x02 +#define __Pyx_CYFUNCTION_CCLASS 0x04 +#define __Pyx_CYFUNCTION_COROUTINE 0x08 +#define __Pyx_CyFunction_GetClosure(f)\ + (((__pyx_CyFunctionObject *) (f))->func_closure) +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_CyFunction_GetClassObj(f)\ + (((__pyx_CyFunctionObject *) (f))->func_classobj) +#else + #define __Pyx_CyFunction_GetClassObj(f)\ + ((PyObject*) ((PyCMethodObject *) (f))->mm_class) +#endif +#define __Pyx_CyFunction_SetClassObj(f, classobj)\ + __Pyx__CyFunction_SetClassObj((__pyx_CyFunctionObject *) (f), (classobj)) +#define __Pyx_CyFunction_Defaults(type, f)\ + ((type *)(((__pyx_CyFunctionObject *) (f))->defaults)) +#define __Pyx_CyFunction_SetDefaultsGetter(f, g)\ + ((__pyx_CyFunctionObject *) (f))->defaults_getter = (g) +typedef struct { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject_HEAD + PyObject *func; +#elif PY_VERSION_HEX < 0x030900B1 + PyCFunctionObject func; +#else + PyCMethodObject func; +#endif +#if CYTHON_BACKPORT_VECTORCALL + __pyx_vectorcallfunc func_vectorcall; +#endif +#if PY_VERSION_HEX < 0x030500A0 || CYTHON_COMPILING_IN_LIMITED_API + PyObject *func_weakreflist; +#endif + PyObject *func_dict; + PyObject *func_name; + PyObject *func_qualname; + PyObject *func_doc; + PyObject *func_globals; + PyObject *func_code; + PyObject *func_closure; +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + PyObject *func_classobj; +#endif + void *defaults; + int defaults_pyobjects; + size_t defaults_size; + int flags; + PyObject *defaults_tuple; + PyObject *defaults_kwdict; + PyObject *(*defaults_getter)(PyObject *); + PyObject *func_annotations; + PyObject *func_is_coroutine; +} __pyx_CyFunctionObject; +#undef __Pyx_CyOrPyCFunction_Check +#define __Pyx_CyFunction_Check(obj) __Pyx_TypeCheck(obj, __pyx_CyFunctionType) +#define __Pyx_CyOrPyCFunction_Check(obj) __Pyx_TypeCheck2(obj, __pyx_CyFunctionType, &PyCFunction_Type) +#define __Pyx_CyFunction_CheckExact(obj) __Pyx_IS_TYPE(obj, __pyx_CyFunctionType) +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc); +#undef __Pyx_IsSameCFunction +#define __Pyx_IsSameCFunction(func, cfunc) __Pyx__IsSameCyOrCFunction(func, cfunc) +static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject* op, PyMethodDef *ml, + int flags, PyObject* qualname, + PyObject *closure, + PyObject *module, PyObject *globals, + PyObject* code); +static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj); +static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *m, + size_t size, + int pyobjects); +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *m, + PyObject *tuple); +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *m, + PyObject *dict); +static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m, + PyObject *dict); +static int __pyx_CyFunction_init(PyObject *module); +#if CYTHON_METH_FASTCALL +static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +#if CYTHON_BACKPORT_VECTORCALL +#define __Pyx_CyFunction_func_vectorcall(f) (((__pyx_CyFunctionObject*)f)->func_vectorcall) +#else +#define __Pyx_CyFunction_func_vectorcall(f) (((PyCFunctionObject*)f)->vectorcall) +#endif +#endif + +/* CythonFunction.proto */ +static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, + int flags, PyObject* qualname, + PyObject *closure, + PyObject *module, PyObject *globals, + PyObject* code); + +/* PyDictVersioning.proto */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) +#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ + (version_var) = __PYX_GET_DICT_VERSION(dict);\ + (cache_var) = (value); +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ + (VAR) = __pyx_dict_cached_value;\ + } else {\ + (VAR) = __pyx_dict_cached_value = (LOOKUP);\ + __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ + }\ +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); +#else +#define __PYX_GET_DICT_VERSION(dict) (0) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); +#endif + +/* CLineInTraceback.proto */ +#ifdef CYTHON_CLINE_IN_TRACEBACK +#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) +#else +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); +#endif + +/* CodeObjectCache.proto */ +#if !CYTHON_COMPILING_IN_LIMITED_API +typedef struct { + PyCodeObject* code_object; + int code_line; +} __Pyx_CodeObjectCacheEntry; +struct __Pyx_CodeObjectCache { + int count; + int max_count; + __Pyx_CodeObjectCacheEntry* entries; +}; +static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); +static PyCodeObject *__pyx_find_code_object(int code_line); +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); +#endif + +/* AddTraceback.proto */ +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename); + +/* BufferStructDeclare.proto */ +typedef struct { + Py_ssize_t shape, strides, suboffsets; +} __Pyx_Buf_DimInfo; +typedef struct { + size_t refcount; + Py_buffer pybuffer; +} __Pyx_Buffer; +typedef struct { + __Pyx_Buffer *rcbuffer; + char *data; + __Pyx_Buf_DimInfo diminfo[8]; +} __Pyx_LocalBuf_ND; + +#if PY_MAJOR_VERSION < 3 + static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags); + static void __Pyx_ReleaseBuffer(Py_buffer *view); +#else + #define __Pyx_GetBuffer PyObject_GetBuffer + #define __Pyx_ReleaseBuffer PyBuffer_Release +#endif + + +/* GCCDiagnostics.proto */ +#if !defined(__INTEL_COMPILER) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#define __Pyx_HAS_GCC_DIAGNOSTIC +#endif + +/* RealImag.proto */ +#if CYTHON_CCOMPLEX + #ifdef __cplusplus + #define __Pyx_CREAL(z) ((z).real()) + #define __Pyx_CIMAG(z) ((z).imag()) + #else + #define __Pyx_CREAL(z) (__real__(z)) + #define __Pyx_CIMAG(z) (__imag__(z)) + #endif +#else + #define __Pyx_CREAL(z) ((z).real) + #define __Pyx_CIMAG(z) ((z).imag) +#endif +#if defined(__cplusplus) && CYTHON_CCOMPLEX\ + && (defined(_WIN32) || defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 5 || __GNUC__ == 4 && __GNUC_MINOR__ >= 4 )) || __cplusplus >= 201103) + #define __Pyx_SET_CREAL(z,x) ((z).real(x)) + #define __Pyx_SET_CIMAG(z,y) ((z).imag(y)) +#else + #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x) + #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y) +#endif + +/* Arithmetic.proto */ +#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) + #define __Pyx_c_eq_float(a, b) ((a)==(b)) + #define __Pyx_c_sum_float(a, b) ((a)+(b)) + #define __Pyx_c_diff_float(a, b) ((a)-(b)) + #define __Pyx_c_prod_float(a, b) ((a)*(b)) + #define __Pyx_c_quot_float(a, b) ((a)/(b)) + #define __Pyx_c_neg_float(a) (-(a)) + #ifdef __cplusplus + #define __Pyx_c_is_zero_float(z) ((z)==(float)0) + #define __Pyx_c_conj_float(z) (::std::conj(z)) + #if 1 + #define __Pyx_c_abs_float(z) (::std::abs(z)) + #define __Pyx_c_pow_float(a, b) (::std::pow(a, b)) + #endif + #else + #define __Pyx_c_is_zero_float(z) ((z)==0) + #define __Pyx_c_conj_float(z) (conjf(z)) + #if 1 + #define __Pyx_c_abs_float(z) (cabsf(z)) + #define __Pyx_c_pow_float(a, b) (cpowf(a, b)) + #endif + #endif +#else + static CYTHON_INLINE int __Pyx_c_eq_float(__pyx_t_float_complex, __pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sum_float(__pyx_t_float_complex, __pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_diff_float(__pyx_t_float_complex, __pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prod_float(__pyx_t_float_complex, __pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quot_float(__pyx_t_float_complex, __pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_neg_float(__pyx_t_float_complex); + static CYTHON_INLINE int __Pyx_c_is_zero_float(__pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conj_float(__pyx_t_float_complex); + #if 1 + static CYTHON_INLINE float __Pyx_c_abs_float(__pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_pow_float(__pyx_t_float_complex, __pyx_t_float_complex); + #endif +#endif + +/* Arithmetic.proto */ +#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) + #define __Pyx_c_eq_double(a, b) ((a)==(b)) + #define __Pyx_c_sum_double(a, b) ((a)+(b)) + #define __Pyx_c_diff_double(a, b) ((a)-(b)) + #define __Pyx_c_prod_double(a, b) ((a)*(b)) + #define __Pyx_c_quot_double(a, b) ((a)/(b)) + #define __Pyx_c_neg_double(a) (-(a)) + #ifdef __cplusplus + #define __Pyx_c_is_zero_double(z) ((z)==(double)0) + #define __Pyx_c_conj_double(z) (::std::conj(z)) + #if 1 + #define __Pyx_c_abs_double(z) (::std::abs(z)) + #define __Pyx_c_pow_double(a, b) (::std::pow(a, b)) + #endif + #else + #define __Pyx_c_is_zero_double(z) ((z)==0) + #define __Pyx_c_conj_double(z) (conj(z)) + #if 1 + #define __Pyx_c_abs_double(z) (cabs(z)) + #define __Pyx_c_pow_double(a, b) (cpow(a, b)) + #endif + #endif +#else + static CYTHON_INLINE int __Pyx_c_eq_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg_double(__pyx_t_double_complex); + static CYTHON_INLINE int __Pyx_c_is_zero_double(__pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj_double(__pyx_t_double_complex); + #if 1 + static CYTHON_INLINE double __Pyx_c_abs_double(__pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow_double(__pyx_t_double_complex, __pyx_t_double_complex); + #endif +#endif + +/* CIntFromPy.proto */ +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); + +/* CppExceptionConversion.proto */ +#ifndef __Pyx_CppExn2PyErr +#include +#include +#include +#include +static void __Pyx_CppExn2PyErr() { + try { + if (PyErr_Occurred()) + ; // let the latest Python exn pass through and ignore the current one + else + throw; + } catch (const std::bad_alloc& exn) { + PyErr_SetString(PyExc_MemoryError, exn.what()); + } catch (const std::bad_cast& exn) { + PyErr_SetString(PyExc_TypeError, exn.what()); + } catch (const std::bad_typeid& exn) { + PyErr_SetString(PyExc_TypeError, exn.what()); + } catch (const std::domain_error& exn) { + PyErr_SetString(PyExc_ValueError, exn.what()); + } catch (const std::invalid_argument& exn) { + PyErr_SetString(PyExc_ValueError, exn.what()); + } catch (const std::ios_base::failure& exn) { + PyErr_SetString(PyExc_IOError, exn.what()); + } catch (const std::out_of_range& exn) { + PyErr_SetString(PyExc_IndexError, exn.what()); + } catch (const std::overflow_error& exn) { + PyErr_SetString(PyExc_OverflowError, exn.what()); + } catch (const std::range_error& exn) { + PyErr_SetString(PyExc_ArithmeticError, exn.what()); + } catch (const std::underflow_error& exn) { + PyErr_SetString(PyExc_ArithmeticError, exn.what()); + } catch (const std::exception& exn) { + PyErr_SetString(PyExc_RuntimeError, exn.what()); + } + catch (...) + { + PyErr_SetString(PyExc_RuntimeError, "Unknown exception"); + } +} +#endif + +/* FormatTypeName.proto */ +#if CYTHON_COMPILING_IN_LIMITED_API +typedef PyObject *__Pyx_TypeName; +#define __Pyx_FMT_TYPENAME "%U" +static __Pyx_TypeName __Pyx_PyType_GetName(PyTypeObject* tp); +#define __Pyx_DECREF_TypeName(obj) Py_XDECREF(obj) +#else +typedef const char *__Pyx_TypeName; +#define __Pyx_FMT_TYPENAME "%.200s" +#define __Pyx_PyType_GetName(tp) ((tp)->tp_name) +#define __Pyx_DECREF_TypeName(obj) +#endif + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); + +/* CIntFromPy.proto */ +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); + +/* FastTypeChecks.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) +#define __Pyx_TypeCheck2(obj, type1, type2) __Pyx_IsAnySubtype2(Py_TYPE(obj), (PyTypeObject *)type1, (PyTypeObject *)type2) +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); +#else +#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) +#define __Pyx_TypeCheck2(obj, type1, type2) (PyObject_TypeCheck(obj, (PyTypeObject *)type1) || PyObject_TypeCheck(obj, (PyTypeObject *)type2)) +#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) +#define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2)) +#endif +#define __Pyx_PyErr_ExceptionMatches2(err1, err2) __Pyx_PyErr_GivenExceptionMatches2(__Pyx_PyErr_CurrentExceptionType(), err1, err2) +#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) + +/* CheckBinaryVersion.proto */ +static unsigned long __Pyx_get_runtime_version(void); +static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer); + +/* InitStrings.proto */ +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); + +/* #### Code section: module_declarations ### */ +static CYTHON_INLINE PyObject *__pyx_f_5numpy_7ndarray_4base_base(PyArrayObject *__pyx_v_self); /* proto*/ +static CYTHON_INLINE PyArray_Descr *__pyx_f_5numpy_7ndarray_5descr_descr(PyArrayObject *__pyx_v_self); /* proto*/ +static CYTHON_INLINE int __pyx_f_5numpy_7ndarray_4ndim_ndim(PyArrayObject *__pyx_v_self); /* proto*/ +static CYTHON_INLINE npy_intp *__pyx_f_5numpy_7ndarray_5shape_shape(PyArrayObject *__pyx_v_self); /* proto*/ +static CYTHON_INLINE npy_intp *__pyx_f_5numpy_7ndarray_7strides_strides(PyArrayObject *__pyx_v_self); /* proto*/ +static CYTHON_INLINE npy_intp __pyx_f_5numpy_7ndarray_4size_size(PyArrayObject *__pyx_v_self); /* proto*/ +static CYTHON_INLINE char *__pyx_f_5numpy_7ndarray_4data_data(PyArrayObject *__pyx_v_self); /* proto*/ + +/* Module declarations from "libc.string" */ + +/* Module declarations from "libc.stdio" */ + +/* Module declarations from "__builtin__" */ + +/* Module declarations from "cpython.type" */ + +/* Module declarations from "cpython" */ + +/* Module declarations from "cpython.object" */ + +/* Module declarations from "cpython.ref" */ + +/* Module declarations from "numpy" */ + +/* Module declarations from "numpy" */ +static CYTHON_INLINE int __pyx_f_5numpy_import_array(void); /*proto*/ + +/* Module declarations from "libcpp.string" */ + +/* Module declarations from "insightface.thirdparty.face3d.mesh.cython.mesh_core_cython" */ +static std::string __pyx_convert_string_from_py_6libcpp_6string_std__in_string(PyObject *); /*proto*/ +/* #### Code section: typeinfo ### */ +static __Pyx_TypeInfo __Pyx_TypeInfo_float = { "float", NULL, sizeof(float), { 0 }, 0, 'R', 0, 0 }; +static __Pyx_TypeInfo __Pyx_TypeInfo_int = { "int", NULL, sizeof(int), { 0 }, 0, __PYX_IS_UNSIGNED(int) ? 'U' : 'I', __PYX_IS_UNSIGNED(int), 0 }; +/* #### Code section: before_global_var ### */ +#define __Pyx_MODULE_NAME "insightface.thirdparty.face3d.mesh.cython.mesh_core_cython" +extern int __pyx_module_is_main_insightface__thirdparty__face3d__mesh__cython__mesh_core_cython; +int __pyx_module_is_main_insightface__thirdparty__face3d__mesh__cython__mesh_core_cython = 0; + +/* Implementation of "insightface.thirdparty.face3d.mesh.cython.mesh_core_cython" */ +/* #### Code section: global_var ### */ +static PyObject *__pyx_builtin_ImportError; +/* #### Code section: string_decls ### */ +static const char __pyx_k_c[] = "c"; +static const char __pyx_k_h[] = "h"; +static const char __pyx_k_w[] = "w"; +static const char __pyx_k__3[] = "*"; +static const char __pyx_k_np[] = "np"; +static const char __pyx_k__14[] = "?"; +static const char __pyx_k_main[] = "__main__"; +static const char __pyx_k_name[] = "__name__"; +static const char __pyx_k_ntri[] = "ntri"; +static const char __pyx_k_nver[] = "nver"; +static const char __pyx_k_spec[] = "__spec__"; +static const char __pyx_k_test[] = "__test__"; +static const char __pyx_k_image[] = "image"; +static const char __pyx_k_numpy[] = "numpy"; +static const char __pyx_k_tex_c[] = "tex_c"; +static const char __pyx_k_tex_h[] = "tex_h"; +static const char __pyx_k_tex_w[] = "tex_w"; +static const char __pyx_k_colors[] = "colors"; +static const char __pyx_k_import[] = "__import__"; +static const char __pyx_k_normal[] = "normal"; +static const char __pyx_k_ntexver[] = "ntexver"; +static const char __pyx_k_texture[] = "texture"; +static const char __pyx_k_filename[] = "filename"; +static const char __pyx_k_mtl_name[] = "mtl_name"; +static const char __pyx_k_tex_nver[] = "tex_nver"; +static const char __pyx_k_vertices[] = "vertices"; +static const char __pyx_k_triangles[] = "triangles"; +static const char __pyx_k_uv_coords[] = "uv_coords"; +static const char __pyx_k_tex_coords[] = "tex_coords"; +static const char __pyx_k_tri_normal[] = "tri_normal"; +static const char __pyx_k_ImportError[] = "ImportError"; +static const char __pyx_k_depth_buffer[] = "depth_buffer"; +static const char __pyx_k_initializing[] = "_initializing"; +static const char __pyx_k_is_coroutine[] = "_is_coroutine"; +static const char __pyx_k_mapping_type[] = "mapping_type"; +static const char __pyx_k_tex_triangles[] = "tex_triangles"; +static const char __pyx_k_get_normal_core[] = "get_normal_core"; +static const char __pyx_k_triangle_buffer[] = "triangle_buffer"; +static const char __pyx_k_asyncio_coroutines[] = "asyncio.coroutines"; +static const char __pyx_k_barycentric_weight[] = "barycentric_weight"; +static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback"; +static const char __pyx_k_render_colors_core[] = "render_colors_core"; +static const char __pyx_k_render_texture_core[] = "render_texture_core"; +static const char __pyx_k_rasterize_triangles_core[] = "rasterize_triangles_core"; +static const char __pyx_k_numpy_core_multiarray_failed_to[] = "numpy.core.multiarray failed to import"; +static const char __pyx_k_insightface_thirdparty_face3d_me[] = "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx"; +static const char __pyx_k_numpy_core_umath_failed_to_impor[] = "numpy.core.umath failed to import"; +static const char __pyx_k_write_obj_with_colors_texture_co[] = "write_obj_with_colors_texture_core"; +static const char __pyx_k_insightface_thirdparty_face3d_me_2[] = "insightface.thirdparty.face3d.mesh.cython.mesh_core_cython"; +/* #### Code section: decls ### */ +static PyObject *__pyx_pf_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_get_normal_core(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_normal, PyArrayObject *__pyx_v_tri_normal, PyArrayObject *__pyx_v_triangles, int __pyx_v_ntri); /* proto */ +static PyObject *__pyx_pf_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_2rasterize_triangles_core(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_vertices, PyArrayObject *__pyx_v_triangles, PyArrayObject *__pyx_v_depth_buffer, PyArrayObject *__pyx_v_triangle_buffer, PyArrayObject *__pyx_v_barycentric_weight, int __pyx_v_nver, int __pyx_v_ntri, int __pyx_v_h, int __pyx_v_w); /* proto */ +static PyObject *__pyx_pf_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_4render_colors_core(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_image, PyArrayObject *__pyx_v_vertices, PyArrayObject *__pyx_v_triangles, PyArrayObject *__pyx_v_colors, PyArrayObject *__pyx_v_depth_buffer, int __pyx_v_nver, int __pyx_v_ntri, int __pyx_v_h, int __pyx_v_w, int __pyx_v_c); /* proto */ +static PyObject *__pyx_pf_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_6render_texture_core(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_image, PyArrayObject *__pyx_v_vertices, PyArrayObject *__pyx_v_triangles, PyArrayObject *__pyx_v_texture, PyArrayObject *__pyx_v_tex_coords, PyArrayObject *__pyx_v_tex_triangles, PyArrayObject *__pyx_v_depth_buffer, int __pyx_v_nver, int __pyx_v_tex_nver, int __pyx_v_ntri, int __pyx_v_h, int __pyx_v_w, int __pyx_v_c, int __pyx_v_tex_h, int __pyx_v_tex_w, int __pyx_v_tex_c, int __pyx_v_mapping_type); /* proto */ +static PyObject *__pyx_pf_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_8write_obj_with_colors_texture_core(CYTHON_UNUSED PyObject *__pyx_self, std::string __pyx_v_filename, std::string __pyx_v_mtl_name, PyArrayObject *__pyx_v_vertices, PyArrayObject *__pyx_v_triangles, PyArrayObject *__pyx_v_colors, PyArrayObject *__pyx_v_uv_coords, int __pyx_v_nver, int __pyx_v_ntri, int __pyx_v_ntexver); /* proto */ +/* #### Code section: late_includes ### */ +/* #### Code section: module_state ### */ +typedef struct { + PyObject *__pyx_d; + PyObject *__pyx_b; + PyObject *__pyx_cython_runtime; + PyObject *__pyx_empty_tuple; + PyObject *__pyx_empty_bytes; + PyObject *__pyx_empty_unicode; + #ifdef __Pyx_CyFunction_USED + PyTypeObject *__pyx_CyFunctionType; + #endif + #ifdef __Pyx_FusedFunction_USED + PyTypeObject *__pyx_FusedFunctionType; + #endif + #ifdef __Pyx_Generator_USED + PyTypeObject *__pyx_GeneratorType; + #endif + #ifdef __Pyx_IterableCoroutine_USED + PyTypeObject *__pyx_IterableCoroutineType; + #endif + #ifdef __Pyx_Coroutine_USED + PyTypeObject *__pyx_CoroutineAwaitType; + #endif + #ifdef __Pyx_Coroutine_USED + PyTypeObject *__pyx_CoroutineType; + #endif + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + #endif + PyTypeObject *__pyx_ptype_7cpython_4type_type; + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + #endif + PyTypeObject *__pyx_ptype_5numpy_dtype; + PyTypeObject *__pyx_ptype_5numpy_flatiter; + PyTypeObject *__pyx_ptype_5numpy_broadcast; + PyTypeObject *__pyx_ptype_5numpy_ndarray; + PyTypeObject *__pyx_ptype_5numpy_generic; + PyTypeObject *__pyx_ptype_5numpy_number; + PyTypeObject *__pyx_ptype_5numpy_integer; + PyTypeObject *__pyx_ptype_5numpy_signedinteger; + PyTypeObject *__pyx_ptype_5numpy_unsignedinteger; + PyTypeObject *__pyx_ptype_5numpy_inexact; + PyTypeObject *__pyx_ptype_5numpy_floating; + PyTypeObject *__pyx_ptype_5numpy_complexfloating; + PyTypeObject *__pyx_ptype_5numpy_flexible; + PyTypeObject *__pyx_ptype_5numpy_character; + PyTypeObject *__pyx_ptype_5numpy_ufunc; + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + #endif + PyObject *__pyx_n_s_ImportError; + PyObject *__pyx_n_s__14; + PyObject *__pyx_n_s__3; + PyObject *__pyx_n_s_asyncio_coroutines; + PyObject *__pyx_n_s_barycentric_weight; + PyObject *__pyx_n_s_c; + PyObject *__pyx_n_s_cline_in_traceback; + PyObject *__pyx_n_s_colors; + PyObject *__pyx_n_s_depth_buffer; + PyObject *__pyx_n_s_filename; + PyObject *__pyx_n_s_get_normal_core; + PyObject *__pyx_n_s_h; + PyObject *__pyx_n_s_image; + PyObject *__pyx_n_s_import; + PyObject *__pyx_n_s_initializing; + PyObject *__pyx_kp_s_insightface_thirdparty_face3d_me; + PyObject *__pyx_n_s_insightface_thirdparty_face3d_me_2; + PyObject *__pyx_n_s_is_coroutine; + PyObject *__pyx_n_s_main; + PyObject *__pyx_n_s_mapping_type; + PyObject *__pyx_n_s_mtl_name; + PyObject *__pyx_n_s_name; + PyObject *__pyx_n_s_normal; + PyObject *__pyx_n_s_np; + PyObject *__pyx_n_s_ntexver; + PyObject *__pyx_n_s_ntri; + PyObject *__pyx_n_s_numpy; + PyObject *__pyx_kp_s_numpy_core_multiarray_failed_to; + PyObject *__pyx_kp_s_numpy_core_umath_failed_to_impor; + PyObject *__pyx_n_s_nver; + PyObject *__pyx_n_s_rasterize_triangles_core; + PyObject *__pyx_n_s_render_colors_core; + PyObject *__pyx_n_s_render_texture_core; + PyObject *__pyx_n_s_spec; + PyObject *__pyx_n_s_test; + PyObject *__pyx_n_s_tex_c; + PyObject *__pyx_n_s_tex_coords; + PyObject *__pyx_n_s_tex_h; + PyObject *__pyx_n_s_tex_nver; + PyObject *__pyx_n_s_tex_triangles; + PyObject *__pyx_n_s_tex_w; + PyObject *__pyx_n_s_texture; + PyObject *__pyx_n_s_tri_normal; + PyObject *__pyx_n_s_triangle_buffer; + PyObject *__pyx_n_s_triangles; + PyObject *__pyx_n_s_uv_coords; + PyObject *__pyx_n_s_vertices; + PyObject *__pyx_n_s_w; + PyObject *__pyx_n_s_write_obj_with_colors_texture_co; + PyObject *__pyx_tuple_; + PyObject *__pyx_tuple__2; + PyObject *__pyx_tuple__4; + PyObject *__pyx_tuple__6; + PyObject *__pyx_tuple__8; + PyObject *__pyx_tuple__10; + PyObject *__pyx_tuple__12; + PyObject *__pyx_codeobj__5; + PyObject *__pyx_codeobj__7; + PyObject *__pyx_codeobj__9; + PyObject *__pyx_codeobj__11; + PyObject *__pyx_codeobj__13; +} __pyx_mstate; + +#if CYTHON_USE_MODULE_STATE +#ifdef __cplusplus +namespace { + extern struct PyModuleDef __pyx_moduledef; +} /* anonymous namespace */ +#else +static struct PyModuleDef __pyx_moduledef; +#endif + +#define __pyx_mstate(o) ((__pyx_mstate *)__Pyx_PyModule_GetState(o)) + +#define __pyx_mstate_global (__pyx_mstate(PyState_FindModule(&__pyx_moduledef))) + +#define __pyx_m (PyState_FindModule(&__pyx_moduledef)) +#else +static __pyx_mstate __pyx_mstate_global_static = +#ifdef __cplusplus + {}; +#else + {0}; +#endif +static __pyx_mstate *__pyx_mstate_global = &__pyx_mstate_global_static; +#endif +/* #### Code section: module_state_clear ### */ +#if CYTHON_USE_MODULE_STATE +static int __pyx_m_clear(PyObject *m) { + __pyx_mstate *clear_module_state = __pyx_mstate(m); + if (!clear_module_state) return 0; + Py_CLEAR(clear_module_state->__pyx_d); + Py_CLEAR(clear_module_state->__pyx_b); + Py_CLEAR(clear_module_state->__pyx_cython_runtime); + Py_CLEAR(clear_module_state->__pyx_empty_tuple); + Py_CLEAR(clear_module_state->__pyx_empty_bytes); + Py_CLEAR(clear_module_state->__pyx_empty_unicode); + #ifdef __Pyx_CyFunction_USED + Py_CLEAR(clear_module_state->__pyx_CyFunctionType); + #endif + #ifdef __Pyx_FusedFunction_USED + Py_CLEAR(clear_module_state->__pyx_FusedFunctionType); + #endif + Py_CLEAR(clear_module_state->__pyx_ptype_7cpython_4type_type); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_dtype); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_flatiter); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_broadcast); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_ndarray); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_generic); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_number); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_integer); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_signedinteger); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_unsignedinteger); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_inexact); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_floating); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_complexfloating); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_flexible); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_character); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_ufunc); + Py_CLEAR(clear_module_state->__pyx_n_s_ImportError); + Py_CLEAR(clear_module_state->__pyx_n_s__14); + Py_CLEAR(clear_module_state->__pyx_n_s__3); + Py_CLEAR(clear_module_state->__pyx_n_s_asyncio_coroutines); + Py_CLEAR(clear_module_state->__pyx_n_s_barycentric_weight); + Py_CLEAR(clear_module_state->__pyx_n_s_c); + Py_CLEAR(clear_module_state->__pyx_n_s_cline_in_traceback); + Py_CLEAR(clear_module_state->__pyx_n_s_colors); + Py_CLEAR(clear_module_state->__pyx_n_s_depth_buffer); + Py_CLEAR(clear_module_state->__pyx_n_s_filename); + Py_CLEAR(clear_module_state->__pyx_n_s_get_normal_core); + Py_CLEAR(clear_module_state->__pyx_n_s_h); + Py_CLEAR(clear_module_state->__pyx_n_s_image); + Py_CLEAR(clear_module_state->__pyx_n_s_import); + Py_CLEAR(clear_module_state->__pyx_n_s_initializing); + Py_CLEAR(clear_module_state->__pyx_kp_s_insightface_thirdparty_face3d_me); + Py_CLEAR(clear_module_state->__pyx_n_s_insightface_thirdparty_face3d_me_2); + Py_CLEAR(clear_module_state->__pyx_n_s_is_coroutine); + Py_CLEAR(clear_module_state->__pyx_n_s_main); + Py_CLEAR(clear_module_state->__pyx_n_s_mapping_type); + Py_CLEAR(clear_module_state->__pyx_n_s_mtl_name); + Py_CLEAR(clear_module_state->__pyx_n_s_name); + Py_CLEAR(clear_module_state->__pyx_n_s_normal); + Py_CLEAR(clear_module_state->__pyx_n_s_np); + Py_CLEAR(clear_module_state->__pyx_n_s_ntexver); + Py_CLEAR(clear_module_state->__pyx_n_s_ntri); + Py_CLEAR(clear_module_state->__pyx_n_s_numpy); + Py_CLEAR(clear_module_state->__pyx_kp_s_numpy_core_multiarray_failed_to); + Py_CLEAR(clear_module_state->__pyx_kp_s_numpy_core_umath_failed_to_impor); + Py_CLEAR(clear_module_state->__pyx_n_s_nver); + Py_CLEAR(clear_module_state->__pyx_n_s_rasterize_triangles_core); + Py_CLEAR(clear_module_state->__pyx_n_s_render_colors_core); + Py_CLEAR(clear_module_state->__pyx_n_s_render_texture_core); + Py_CLEAR(clear_module_state->__pyx_n_s_spec); + Py_CLEAR(clear_module_state->__pyx_n_s_test); + Py_CLEAR(clear_module_state->__pyx_n_s_tex_c); + Py_CLEAR(clear_module_state->__pyx_n_s_tex_coords); + Py_CLEAR(clear_module_state->__pyx_n_s_tex_h); + Py_CLEAR(clear_module_state->__pyx_n_s_tex_nver); + Py_CLEAR(clear_module_state->__pyx_n_s_tex_triangles); + Py_CLEAR(clear_module_state->__pyx_n_s_tex_w); + Py_CLEAR(clear_module_state->__pyx_n_s_texture); + Py_CLEAR(clear_module_state->__pyx_n_s_tri_normal); + Py_CLEAR(clear_module_state->__pyx_n_s_triangle_buffer); + Py_CLEAR(clear_module_state->__pyx_n_s_triangles); + Py_CLEAR(clear_module_state->__pyx_n_s_uv_coords); + Py_CLEAR(clear_module_state->__pyx_n_s_vertices); + Py_CLEAR(clear_module_state->__pyx_n_s_w); + Py_CLEAR(clear_module_state->__pyx_n_s_write_obj_with_colors_texture_co); + Py_CLEAR(clear_module_state->__pyx_tuple_); + Py_CLEAR(clear_module_state->__pyx_tuple__2); + Py_CLEAR(clear_module_state->__pyx_tuple__4); + Py_CLEAR(clear_module_state->__pyx_tuple__6); + Py_CLEAR(clear_module_state->__pyx_tuple__8); + Py_CLEAR(clear_module_state->__pyx_tuple__10); + Py_CLEAR(clear_module_state->__pyx_tuple__12); + Py_CLEAR(clear_module_state->__pyx_codeobj__5); + Py_CLEAR(clear_module_state->__pyx_codeobj__7); + Py_CLEAR(clear_module_state->__pyx_codeobj__9); + Py_CLEAR(clear_module_state->__pyx_codeobj__11); + Py_CLEAR(clear_module_state->__pyx_codeobj__13); + return 0; +} +#endif +/* #### Code section: module_state_traverse ### */ +#if CYTHON_USE_MODULE_STATE +static int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) { + __pyx_mstate *traverse_module_state = __pyx_mstate(m); + if (!traverse_module_state) return 0; + Py_VISIT(traverse_module_state->__pyx_d); + Py_VISIT(traverse_module_state->__pyx_b); + Py_VISIT(traverse_module_state->__pyx_cython_runtime); + Py_VISIT(traverse_module_state->__pyx_empty_tuple); + Py_VISIT(traverse_module_state->__pyx_empty_bytes); + Py_VISIT(traverse_module_state->__pyx_empty_unicode); + #ifdef __Pyx_CyFunction_USED + Py_VISIT(traverse_module_state->__pyx_CyFunctionType); + #endif + #ifdef __Pyx_FusedFunction_USED + Py_VISIT(traverse_module_state->__pyx_FusedFunctionType); + #endif + Py_VISIT(traverse_module_state->__pyx_ptype_7cpython_4type_type); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_dtype); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_flatiter); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_broadcast); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_ndarray); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_generic); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_number); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_integer); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_signedinteger); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_unsignedinteger); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_inexact); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_floating); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_complexfloating); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_flexible); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_character); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_ufunc); + Py_VISIT(traverse_module_state->__pyx_n_s_ImportError); + Py_VISIT(traverse_module_state->__pyx_n_s__14); + Py_VISIT(traverse_module_state->__pyx_n_s__3); + Py_VISIT(traverse_module_state->__pyx_n_s_asyncio_coroutines); + Py_VISIT(traverse_module_state->__pyx_n_s_barycentric_weight); + Py_VISIT(traverse_module_state->__pyx_n_s_c); + Py_VISIT(traverse_module_state->__pyx_n_s_cline_in_traceback); + Py_VISIT(traverse_module_state->__pyx_n_s_colors); + Py_VISIT(traverse_module_state->__pyx_n_s_depth_buffer); + Py_VISIT(traverse_module_state->__pyx_n_s_filename); + Py_VISIT(traverse_module_state->__pyx_n_s_get_normal_core); + Py_VISIT(traverse_module_state->__pyx_n_s_h); + Py_VISIT(traverse_module_state->__pyx_n_s_image); + Py_VISIT(traverse_module_state->__pyx_n_s_import); + Py_VISIT(traverse_module_state->__pyx_n_s_initializing); + Py_VISIT(traverse_module_state->__pyx_kp_s_insightface_thirdparty_face3d_me); + Py_VISIT(traverse_module_state->__pyx_n_s_insightface_thirdparty_face3d_me_2); + Py_VISIT(traverse_module_state->__pyx_n_s_is_coroutine); + Py_VISIT(traverse_module_state->__pyx_n_s_main); + Py_VISIT(traverse_module_state->__pyx_n_s_mapping_type); + Py_VISIT(traverse_module_state->__pyx_n_s_mtl_name); + Py_VISIT(traverse_module_state->__pyx_n_s_name); + Py_VISIT(traverse_module_state->__pyx_n_s_normal); + Py_VISIT(traverse_module_state->__pyx_n_s_np); + Py_VISIT(traverse_module_state->__pyx_n_s_ntexver); + Py_VISIT(traverse_module_state->__pyx_n_s_ntri); + Py_VISIT(traverse_module_state->__pyx_n_s_numpy); + Py_VISIT(traverse_module_state->__pyx_kp_s_numpy_core_multiarray_failed_to); + Py_VISIT(traverse_module_state->__pyx_kp_s_numpy_core_umath_failed_to_impor); + Py_VISIT(traverse_module_state->__pyx_n_s_nver); + Py_VISIT(traverse_module_state->__pyx_n_s_rasterize_triangles_core); + Py_VISIT(traverse_module_state->__pyx_n_s_render_colors_core); + Py_VISIT(traverse_module_state->__pyx_n_s_render_texture_core); + Py_VISIT(traverse_module_state->__pyx_n_s_spec); + Py_VISIT(traverse_module_state->__pyx_n_s_test); + Py_VISIT(traverse_module_state->__pyx_n_s_tex_c); + Py_VISIT(traverse_module_state->__pyx_n_s_tex_coords); + Py_VISIT(traverse_module_state->__pyx_n_s_tex_h); + Py_VISIT(traverse_module_state->__pyx_n_s_tex_nver); + Py_VISIT(traverse_module_state->__pyx_n_s_tex_triangles); + Py_VISIT(traverse_module_state->__pyx_n_s_tex_w); + Py_VISIT(traverse_module_state->__pyx_n_s_texture); + Py_VISIT(traverse_module_state->__pyx_n_s_tri_normal); + Py_VISIT(traverse_module_state->__pyx_n_s_triangle_buffer); + Py_VISIT(traverse_module_state->__pyx_n_s_triangles); + Py_VISIT(traverse_module_state->__pyx_n_s_uv_coords); + Py_VISIT(traverse_module_state->__pyx_n_s_vertices); + Py_VISIT(traverse_module_state->__pyx_n_s_w); + Py_VISIT(traverse_module_state->__pyx_n_s_write_obj_with_colors_texture_co); + Py_VISIT(traverse_module_state->__pyx_tuple_); + Py_VISIT(traverse_module_state->__pyx_tuple__2); + Py_VISIT(traverse_module_state->__pyx_tuple__4); + Py_VISIT(traverse_module_state->__pyx_tuple__6); + Py_VISIT(traverse_module_state->__pyx_tuple__8); + Py_VISIT(traverse_module_state->__pyx_tuple__10); + Py_VISIT(traverse_module_state->__pyx_tuple__12); + Py_VISIT(traverse_module_state->__pyx_codeobj__5); + Py_VISIT(traverse_module_state->__pyx_codeobj__7); + Py_VISIT(traverse_module_state->__pyx_codeobj__9); + Py_VISIT(traverse_module_state->__pyx_codeobj__11); + Py_VISIT(traverse_module_state->__pyx_codeobj__13); + return 0; +} +#endif +/* #### Code section: module_state_defines ### */ +#define __pyx_d __pyx_mstate_global->__pyx_d +#define __pyx_b __pyx_mstate_global->__pyx_b +#define __pyx_cython_runtime __pyx_mstate_global->__pyx_cython_runtime +#define __pyx_empty_tuple __pyx_mstate_global->__pyx_empty_tuple +#define __pyx_empty_bytes __pyx_mstate_global->__pyx_empty_bytes +#define __pyx_empty_unicode __pyx_mstate_global->__pyx_empty_unicode +#ifdef __Pyx_CyFunction_USED +#define __pyx_CyFunctionType __pyx_mstate_global->__pyx_CyFunctionType +#endif +#ifdef __Pyx_FusedFunction_USED +#define __pyx_FusedFunctionType __pyx_mstate_global->__pyx_FusedFunctionType +#endif +#ifdef __Pyx_Generator_USED +#define __pyx_GeneratorType __pyx_mstate_global->__pyx_GeneratorType +#endif +#ifdef __Pyx_IterableCoroutine_USED +#define __pyx_IterableCoroutineType __pyx_mstate_global->__pyx_IterableCoroutineType +#endif +#ifdef __Pyx_Coroutine_USED +#define __pyx_CoroutineAwaitType __pyx_mstate_global->__pyx_CoroutineAwaitType +#endif +#ifdef __Pyx_Coroutine_USED +#define __pyx_CoroutineType __pyx_mstate_global->__pyx_CoroutineType +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#define __pyx_ptype_7cpython_4type_type __pyx_mstate_global->__pyx_ptype_7cpython_4type_type +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#define __pyx_ptype_5numpy_dtype __pyx_mstate_global->__pyx_ptype_5numpy_dtype +#define __pyx_ptype_5numpy_flatiter __pyx_mstate_global->__pyx_ptype_5numpy_flatiter +#define __pyx_ptype_5numpy_broadcast __pyx_mstate_global->__pyx_ptype_5numpy_broadcast +#define __pyx_ptype_5numpy_ndarray __pyx_mstate_global->__pyx_ptype_5numpy_ndarray +#define __pyx_ptype_5numpy_generic __pyx_mstate_global->__pyx_ptype_5numpy_generic +#define __pyx_ptype_5numpy_number __pyx_mstate_global->__pyx_ptype_5numpy_number +#define __pyx_ptype_5numpy_integer __pyx_mstate_global->__pyx_ptype_5numpy_integer +#define __pyx_ptype_5numpy_signedinteger __pyx_mstate_global->__pyx_ptype_5numpy_signedinteger +#define __pyx_ptype_5numpy_unsignedinteger __pyx_mstate_global->__pyx_ptype_5numpy_unsignedinteger +#define __pyx_ptype_5numpy_inexact __pyx_mstate_global->__pyx_ptype_5numpy_inexact +#define __pyx_ptype_5numpy_floating __pyx_mstate_global->__pyx_ptype_5numpy_floating +#define __pyx_ptype_5numpy_complexfloating __pyx_mstate_global->__pyx_ptype_5numpy_complexfloating +#define __pyx_ptype_5numpy_flexible __pyx_mstate_global->__pyx_ptype_5numpy_flexible +#define __pyx_ptype_5numpy_character __pyx_mstate_global->__pyx_ptype_5numpy_character +#define __pyx_ptype_5numpy_ufunc __pyx_mstate_global->__pyx_ptype_5numpy_ufunc +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#define __pyx_n_s_ImportError __pyx_mstate_global->__pyx_n_s_ImportError +#define __pyx_n_s__14 __pyx_mstate_global->__pyx_n_s__14 +#define __pyx_n_s__3 __pyx_mstate_global->__pyx_n_s__3 +#define __pyx_n_s_asyncio_coroutines __pyx_mstate_global->__pyx_n_s_asyncio_coroutines +#define __pyx_n_s_barycentric_weight __pyx_mstate_global->__pyx_n_s_barycentric_weight +#define __pyx_n_s_c __pyx_mstate_global->__pyx_n_s_c +#define __pyx_n_s_cline_in_traceback __pyx_mstate_global->__pyx_n_s_cline_in_traceback +#define __pyx_n_s_colors __pyx_mstate_global->__pyx_n_s_colors +#define __pyx_n_s_depth_buffer __pyx_mstate_global->__pyx_n_s_depth_buffer +#define __pyx_n_s_filename __pyx_mstate_global->__pyx_n_s_filename +#define __pyx_n_s_get_normal_core __pyx_mstate_global->__pyx_n_s_get_normal_core +#define __pyx_n_s_h __pyx_mstate_global->__pyx_n_s_h +#define __pyx_n_s_image __pyx_mstate_global->__pyx_n_s_image +#define __pyx_n_s_import __pyx_mstate_global->__pyx_n_s_import +#define __pyx_n_s_initializing __pyx_mstate_global->__pyx_n_s_initializing +#define __pyx_kp_s_insightface_thirdparty_face3d_me __pyx_mstate_global->__pyx_kp_s_insightface_thirdparty_face3d_me +#define __pyx_n_s_insightface_thirdparty_face3d_me_2 __pyx_mstate_global->__pyx_n_s_insightface_thirdparty_face3d_me_2 +#define __pyx_n_s_is_coroutine __pyx_mstate_global->__pyx_n_s_is_coroutine +#define __pyx_n_s_main __pyx_mstate_global->__pyx_n_s_main +#define __pyx_n_s_mapping_type __pyx_mstate_global->__pyx_n_s_mapping_type +#define __pyx_n_s_mtl_name __pyx_mstate_global->__pyx_n_s_mtl_name +#define __pyx_n_s_name __pyx_mstate_global->__pyx_n_s_name +#define __pyx_n_s_normal __pyx_mstate_global->__pyx_n_s_normal +#define __pyx_n_s_np __pyx_mstate_global->__pyx_n_s_np +#define __pyx_n_s_ntexver __pyx_mstate_global->__pyx_n_s_ntexver +#define __pyx_n_s_ntri __pyx_mstate_global->__pyx_n_s_ntri +#define __pyx_n_s_numpy __pyx_mstate_global->__pyx_n_s_numpy +#define __pyx_kp_s_numpy_core_multiarray_failed_to __pyx_mstate_global->__pyx_kp_s_numpy_core_multiarray_failed_to +#define __pyx_kp_s_numpy_core_umath_failed_to_impor __pyx_mstate_global->__pyx_kp_s_numpy_core_umath_failed_to_impor +#define __pyx_n_s_nver __pyx_mstate_global->__pyx_n_s_nver +#define __pyx_n_s_rasterize_triangles_core __pyx_mstate_global->__pyx_n_s_rasterize_triangles_core +#define __pyx_n_s_render_colors_core __pyx_mstate_global->__pyx_n_s_render_colors_core +#define __pyx_n_s_render_texture_core __pyx_mstate_global->__pyx_n_s_render_texture_core +#define __pyx_n_s_spec __pyx_mstate_global->__pyx_n_s_spec +#define __pyx_n_s_test __pyx_mstate_global->__pyx_n_s_test +#define __pyx_n_s_tex_c __pyx_mstate_global->__pyx_n_s_tex_c +#define __pyx_n_s_tex_coords __pyx_mstate_global->__pyx_n_s_tex_coords +#define __pyx_n_s_tex_h __pyx_mstate_global->__pyx_n_s_tex_h +#define __pyx_n_s_tex_nver __pyx_mstate_global->__pyx_n_s_tex_nver +#define __pyx_n_s_tex_triangles __pyx_mstate_global->__pyx_n_s_tex_triangles +#define __pyx_n_s_tex_w __pyx_mstate_global->__pyx_n_s_tex_w +#define __pyx_n_s_texture __pyx_mstate_global->__pyx_n_s_texture +#define __pyx_n_s_tri_normal __pyx_mstate_global->__pyx_n_s_tri_normal +#define __pyx_n_s_triangle_buffer __pyx_mstate_global->__pyx_n_s_triangle_buffer +#define __pyx_n_s_triangles __pyx_mstate_global->__pyx_n_s_triangles +#define __pyx_n_s_uv_coords __pyx_mstate_global->__pyx_n_s_uv_coords +#define __pyx_n_s_vertices __pyx_mstate_global->__pyx_n_s_vertices +#define __pyx_n_s_w __pyx_mstate_global->__pyx_n_s_w +#define __pyx_n_s_write_obj_with_colors_texture_co __pyx_mstate_global->__pyx_n_s_write_obj_with_colors_texture_co +#define __pyx_tuple_ __pyx_mstate_global->__pyx_tuple_ +#define __pyx_tuple__2 __pyx_mstate_global->__pyx_tuple__2 +#define __pyx_tuple__4 __pyx_mstate_global->__pyx_tuple__4 +#define __pyx_tuple__6 __pyx_mstate_global->__pyx_tuple__6 +#define __pyx_tuple__8 __pyx_mstate_global->__pyx_tuple__8 +#define __pyx_tuple__10 __pyx_mstate_global->__pyx_tuple__10 +#define __pyx_tuple__12 __pyx_mstate_global->__pyx_tuple__12 +#define __pyx_codeobj__5 __pyx_mstate_global->__pyx_codeobj__5 +#define __pyx_codeobj__7 __pyx_mstate_global->__pyx_codeobj__7 +#define __pyx_codeobj__9 __pyx_mstate_global->__pyx_codeobj__9 +#define __pyx_codeobj__11 __pyx_mstate_global->__pyx_codeobj__11 +#define __pyx_codeobj__13 __pyx_mstate_global->__pyx_codeobj__13 +/* #### Code section: module_code ### */ + +/* "string.from_py":13 + * + * @cname("__pyx_convert_string_from_py_6libcpp_6string_std__in_string") + * cdef string __pyx_convert_string_from_py_6libcpp_6string_std__in_string(object o) except *: # <<<<<<<<<<<<<< + * cdef Py_ssize_t length = 0 + * cdef const char* data = __Pyx_PyObject_AsStringAndSize(o, &length) + */ + +static std::string __pyx_convert_string_from_py_6libcpp_6string_std__in_string(PyObject *__pyx_v_o) { + Py_ssize_t __pyx_v_length; + char const *__pyx_v_data; + std::string __pyx_r; + char const *__pyx_t_1; + std::string __pyx_t_2; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + + /* "string.from_py":14 + * @cname("__pyx_convert_string_from_py_6libcpp_6string_std__in_string") + * cdef string __pyx_convert_string_from_py_6libcpp_6string_std__in_string(object o) except *: + * cdef Py_ssize_t length = 0 # <<<<<<<<<<<<<< + * cdef const char* data = __Pyx_PyObject_AsStringAndSize(o, &length) + * return string(data, length) + */ + __pyx_v_length = 0; + + /* "string.from_py":15 + * cdef string __pyx_convert_string_from_py_6libcpp_6string_std__in_string(object o) except *: + * cdef Py_ssize_t length = 0 + * cdef const char* data = __Pyx_PyObject_AsStringAndSize(o, &length) # <<<<<<<<<<<<<< + * return string(data, length) + * + */ + __pyx_t_1 = __Pyx_PyObject_AsStringAndSize(__pyx_v_o, (&__pyx_v_length)); if (unlikely(__pyx_t_1 == ((char const *)NULL))) __PYX_ERR(0, 15, __pyx_L1_error) + __pyx_v_data = __pyx_t_1; + + /* "string.from_py":16 + * cdef Py_ssize_t length = 0 + * cdef const char* data = __Pyx_PyObject_AsStringAndSize(o, &length) + * return string(data, length) # <<<<<<<<<<<<<< + * + * + */ + try { + __pyx_t_2 = std::string(__pyx_v_data, __pyx_v_length); + } catch(...) { + __Pyx_CppExn2PyErr(); + __PYX_ERR(0, 16, __pyx_L1_error) + } + __pyx_r = __pyx_t_2; + goto __pyx_L0; + + /* "string.from_py":13 + * + * @cname("__pyx_convert_string_from_py_6libcpp_6string_std__in_string") + * cdef string __pyx_convert_string_from_py_6libcpp_6string_std__in_string(object o) except *: # <<<<<<<<<<<<<< + * cdef Py_ssize_t length = 0 + * cdef const char* data = __Pyx_PyObject_AsStringAndSize(o, &length) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("string.from_py.__pyx_convert_string_from_py_6libcpp_6string_std__in_string", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_pretend_to_initialize(&__pyx_r); + __pyx_L0:; + return __pyx_r; +} + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":245 + * + * @property + * cdef inline PyObject* base(self) nogil: # <<<<<<<<<<<<<< + * """Returns a borrowed reference to the object owning the data/memory. + * """ + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_7ndarray_4base_base(PyArrayObject *__pyx_v_self) { + PyObject *__pyx_r; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":248 + * """Returns a borrowed reference to the object owning the data/memory. + * """ + * return PyArray_BASE(self) # <<<<<<<<<<<<<< + * + * @property + */ + __pyx_r = PyArray_BASE(__pyx_v_self); + goto __pyx_L0; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":245 + * + * @property + * cdef inline PyObject* base(self) nogil: # <<<<<<<<<<<<<< + * """Returns a borrowed reference to the object owning the data/memory. + * """ + */ + + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":251 + * + * @property + * cdef inline dtype descr(self): # <<<<<<<<<<<<<< + * """Returns an owned reference to the dtype of the array. + * """ + */ + +static CYTHON_INLINE PyArray_Descr *__pyx_f_5numpy_7ndarray_5descr_descr(PyArrayObject *__pyx_v_self) { + PyArray_Descr *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyArray_Descr *__pyx_t_1; + __Pyx_RefNannySetupContext("descr", 1); + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":254 + * """Returns an owned reference to the dtype of the array. + * """ + * return PyArray_DESCR(self) # <<<<<<<<<<<<<< + * + * @property + */ + __Pyx_XDECREF((PyObject *)__pyx_r); + __pyx_t_1 = PyArray_DESCR(__pyx_v_self); + __Pyx_INCREF((PyObject *)((PyArray_Descr *)__pyx_t_1)); + __pyx_r = ((PyArray_Descr *)__pyx_t_1); + goto __pyx_L0; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":251 + * + * @property + * cdef inline dtype descr(self): # <<<<<<<<<<<<<< + * """Returns an owned reference to the dtype of the array. + * """ + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF((PyObject *)__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":257 + * + * @property + * cdef inline int ndim(self) nogil: # <<<<<<<<<<<<<< + * """Returns the number of dimensions in the array. + * """ + */ + +static CYTHON_INLINE int __pyx_f_5numpy_7ndarray_4ndim_ndim(PyArrayObject *__pyx_v_self) { + int __pyx_r; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":260 + * """Returns the number of dimensions in the array. + * """ + * return PyArray_NDIM(self) # <<<<<<<<<<<<<< + * + * @property + */ + __pyx_r = PyArray_NDIM(__pyx_v_self); + goto __pyx_L0; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":257 + * + * @property + * cdef inline int ndim(self) nogil: # <<<<<<<<<<<<<< + * """Returns the number of dimensions in the array. + * """ + */ + + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":263 + * + * @property + * cdef inline npy_intp *shape(self) nogil: # <<<<<<<<<<<<<< + * """Returns a pointer to the dimensions/shape of the array. + * The number of elements matches the number of dimensions of the array (ndim). + */ + +static CYTHON_INLINE npy_intp *__pyx_f_5numpy_7ndarray_5shape_shape(PyArrayObject *__pyx_v_self) { + npy_intp *__pyx_r; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":268 + * Can return NULL for 0-dimensional arrays. + * """ + * return PyArray_DIMS(self) # <<<<<<<<<<<<<< + * + * @property + */ + __pyx_r = PyArray_DIMS(__pyx_v_self); + goto __pyx_L0; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":263 + * + * @property + * cdef inline npy_intp *shape(self) nogil: # <<<<<<<<<<<<<< + * """Returns a pointer to the dimensions/shape of the array. + * The number of elements matches the number of dimensions of the array (ndim). + */ + + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":271 + * + * @property + * cdef inline npy_intp *strides(self) nogil: # <<<<<<<<<<<<<< + * """Returns a pointer to the strides of the array. + * The number of elements matches the number of dimensions of the array (ndim). + */ + +static CYTHON_INLINE npy_intp *__pyx_f_5numpy_7ndarray_7strides_strides(PyArrayObject *__pyx_v_self) { + npy_intp *__pyx_r; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":275 + * The number of elements matches the number of dimensions of the array (ndim). + * """ + * return PyArray_STRIDES(self) # <<<<<<<<<<<<<< + * + * @property + */ + __pyx_r = PyArray_STRIDES(__pyx_v_self); + goto __pyx_L0; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":271 + * + * @property + * cdef inline npy_intp *strides(self) nogil: # <<<<<<<<<<<<<< + * """Returns a pointer to the strides of the array. + * The number of elements matches the number of dimensions of the array (ndim). + */ + + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":278 + * + * @property + * cdef inline npy_intp size(self) nogil: # <<<<<<<<<<<<<< + * """Returns the total size (in number of elements) of the array. + * """ + */ + +static CYTHON_INLINE npy_intp __pyx_f_5numpy_7ndarray_4size_size(PyArrayObject *__pyx_v_self) { + npy_intp __pyx_r; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":281 + * """Returns the total size (in number of elements) of the array. + * """ + * return PyArray_SIZE(self) # <<<<<<<<<<<<<< + * + * @property + */ + __pyx_r = PyArray_SIZE(__pyx_v_self); + goto __pyx_L0; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":278 + * + * @property + * cdef inline npy_intp size(self) nogil: # <<<<<<<<<<<<<< + * """Returns the total size (in number of elements) of the array. + * """ + */ + + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":284 + * + * @property + * cdef inline char* data(self) nogil: # <<<<<<<<<<<<<< + * """The pointer to the data buffer as a char*. + * This is provided for legacy reasons to avoid direct struct field access. + */ + +static CYTHON_INLINE char *__pyx_f_5numpy_7ndarray_4data_data(PyArrayObject *__pyx_v_self) { + char *__pyx_r; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":290 + * of `PyArray_DATA()` instead, which returns a 'void*'. + * """ + * return PyArray_BYTES(self) # <<<<<<<<<<<<<< + * + * ctypedef unsigned char npy_bool + */ + __pyx_r = PyArray_BYTES(__pyx_v_self); + goto __pyx_L0; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":284 + * + * @property + * cdef inline char* data(self) nogil: # <<<<<<<<<<<<<< + * """The pointer to the data buffer as a char*. + * This is provided for legacy reasons to avoid direct struct field access. + */ + + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":773 + * ctypedef npy_cdouble complex_t + * + * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(1, a) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 1); + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":774 + * + * cdef inline object PyArray_MultiIterNew1(a): + * return PyArray_MultiIterNew(1, a) # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew2(a, b): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 774, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":773 + * ctypedef npy_cdouble complex_t + * + * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(1, a) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":776 + * return PyArray_MultiIterNew(1, a) + * + * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(2, a, b) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 1); + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":777 + * + * cdef inline object PyArray_MultiIterNew2(a, b): + * return PyArray_MultiIterNew(2, a, b) # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew3(a, b, c): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 777, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":776 + * return PyArray_MultiIterNew(1, a) + * + * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(2, a, b) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":779 + * return PyArray_MultiIterNew(2, a, b) + * + * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(3, a, b, c) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 1); + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":780 + * + * cdef inline object PyArray_MultiIterNew3(a, b, c): + * return PyArray_MultiIterNew(3, a, b, c) # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew4(a, b, c, d): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 780, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":779 + * return PyArray_MultiIterNew(2, a, b) + * + * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(3, a, b, c) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew3", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":782 + * return PyArray_MultiIterNew(3, a, b, c) + * + * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(4, a, b, c, d) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 1); + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":783 + * + * cdef inline object PyArray_MultiIterNew4(a, b, c, d): + * return PyArray_MultiIterNew(4, a, b, c, d) # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 783, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":782 + * return PyArray_MultiIterNew(3, a, b, c) + * + * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(4, a, b, c, d) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew4", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":785 + * return PyArray_MultiIterNew(4, a, b, c, d) + * + * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(5, a, b, c, d, e) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 1); + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":786 + * + * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): + * return PyArray_MultiIterNew(5, a, b, c, d, e) # <<<<<<<<<<<<<< + * + * cdef inline tuple PyDataType_SHAPE(dtype d): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 786, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":785 + * return PyArray_MultiIterNew(4, a, b, c, d) + * + * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(5, a, b, c, d, e) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew5", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":788 + * return PyArray_MultiIterNew(5, a, b, c, d, e) + * + * cdef inline tuple PyDataType_SHAPE(dtype d): # <<<<<<<<<<<<<< + * if PyDataType_HASSUBARRAY(d): + * return d.subarray.shape + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyDataType_SHAPE(PyArray_Descr *__pyx_v_d) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + __Pyx_RefNannySetupContext("PyDataType_SHAPE", 1); + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":789 + * + * cdef inline tuple PyDataType_SHAPE(dtype d): + * if PyDataType_HASSUBARRAY(d): # <<<<<<<<<<<<<< + * return d.subarray.shape + * else: + */ + __pyx_t_1 = PyDataType_HASSUBARRAY(__pyx_v_d); + if (__pyx_t_1) { + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":790 + * cdef inline tuple PyDataType_SHAPE(dtype d): + * if PyDataType_HASSUBARRAY(d): + * return d.subarray.shape # <<<<<<<<<<<<<< + * else: + * return () + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(((PyObject*)__pyx_v_d->subarray->shape)); + __pyx_r = ((PyObject*)__pyx_v_d->subarray->shape); + goto __pyx_L0; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":789 + * + * cdef inline tuple PyDataType_SHAPE(dtype d): + * if PyDataType_HASSUBARRAY(d): # <<<<<<<<<<<<<< + * return d.subarray.shape + * else: + */ + } + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":792 + * return d.subarray.shape + * else: + * return () # <<<<<<<<<<<<<< + * + * + */ + /*else*/ { + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_empty_tuple); + __pyx_r = __pyx_empty_tuple; + goto __pyx_L0; + } + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":788 + * return PyArray_MultiIterNew(5, a, b, c, d, e) + * + * cdef inline tuple PyDataType_SHAPE(dtype d): # <<<<<<<<<<<<<< + * if PyDataType_HASSUBARRAY(d): + * return d.subarray.shape + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":968 + * int _import_umath() except -1 + * + * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<< + * Py_INCREF(base) # important to do this before stealing the reference below! + * PyArray_SetBaseObject(arr, base) + */ + +static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) { + int __pyx_t_1; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":969 + * + * cdef inline void set_array_base(ndarray arr, object base): + * Py_INCREF(base) # important to do this before stealing the reference below! # <<<<<<<<<<<<<< + * PyArray_SetBaseObject(arr, base) + * + */ + Py_INCREF(__pyx_v_base); + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":970 + * cdef inline void set_array_base(ndarray arr, object base): + * Py_INCREF(base) # important to do this before stealing the reference below! + * PyArray_SetBaseObject(arr, base) # <<<<<<<<<<<<<< + * + * cdef inline object get_array_base(ndarray arr): + */ + __pyx_t_1 = PyArray_SetBaseObject(__pyx_v_arr, __pyx_v_base); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(1, 970, __pyx_L1_error) + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":968 + * int _import_umath() except -1 + * + * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<< + * Py_INCREF(base) # important to do this before stealing the reference below! + * PyArray_SetBaseObject(arr, base) + */ + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_AddTraceback("numpy.set_array_base", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_L0:; +} + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":972 + * PyArray_SetBaseObject(arr, base) + * + * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< + * base = PyArray_BASE(arr) + * if base is NULL: + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) { + PyObject *__pyx_v_base; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + __Pyx_RefNannySetupContext("get_array_base", 1); + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":973 + * + * cdef inline object get_array_base(ndarray arr): + * base = PyArray_BASE(arr) # <<<<<<<<<<<<<< + * if base is NULL: + * return None + */ + __pyx_v_base = PyArray_BASE(__pyx_v_arr); + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":974 + * cdef inline object get_array_base(ndarray arr): + * base = PyArray_BASE(arr) + * if base is NULL: # <<<<<<<<<<<<<< + * return None + * return base + */ + __pyx_t_1 = (__pyx_v_base == NULL); + if (__pyx_t_1) { + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":975 + * base = PyArray_BASE(arr) + * if base is NULL: + * return None # <<<<<<<<<<<<<< + * return base + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":974 + * cdef inline object get_array_base(ndarray arr): + * base = PyArray_BASE(arr) + * if base is NULL: # <<<<<<<<<<<<<< + * return None + * return base + */ + } + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":976 + * if base is NULL: + * return None + * return base # <<<<<<<<<<<<<< + * + * # Versions of the import_* functions which are more suitable for + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(((PyObject *)__pyx_v_base)); + __pyx_r = ((PyObject *)__pyx_v_base); + goto __pyx_L0; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":972 + * PyArray_SetBaseObject(arr, base) + * + * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< + * base = PyArray_BASE(arr) + * if base is NULL: + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":980 + * # Versions of the import_* functions which are more suitable for + * # Cython code. + * cdef inline int import_array() except -1: # <<<<<<<<<<<<<< + * try: + * __pyx_import_array() + */ + +static CYTHON_INLINE int __pyx_f_5numpy_import_array(void) { + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("import_array", 1); + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":981 + * # Cython code. + * cdef inline int import_array() except -1: + * try: # <<<<<<<<<<<<<< + * __pyx_import_array() + * except Exception: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + /*try:*/ { + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":982 + * cdef inline int import_array() except -1: + * try: + * __pyx_import_array() # <<<<<<<<<<<<<< + * except Exception: + * raise ImportError("numpy.core.multiarray failed to import") + */ + __pyx_t_4 = _import_array(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 982, __pyx_L3_error) + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":981 + * # Cython code. + * cdef inline int import_array() except -1: + * try: # <<<<<<<<<<<<<< + * __pyx_import_array() + * except Exception: + */ + } + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L8_try_end; + __pyx_L3_error:; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":983 + * try: + * __pyx_import_array() + * except Exception: # <<<<<<<<<<<<<< + * raise ImportError("numpy.core.multiarray failed to import") + * + */ + __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); + if (__pyx_t_4) { + __Pyx_AddTraceback("numpy.import_array", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(1, 983, __pyx_L5_except_error) + __Pyx_XGOTREF(__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_6); + __Pyx_XGOTREF(__pyx_t_7); + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":984 + * __pyx_import_array() + * except Exception: + * raise ImportError("numpy.core.multiarray failed to import") # <<<<<<<<<<<<<< + * + * cdef inline int import_umath() except -1: + */ + __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 984, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_Raise(__pyx_t_8, 0, 0, 0); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __PYX_ERR(1, 984, __pyx_L5_except_error) + } + goto __pyx_L5_except_error; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":981 + * # Cython code. + * cdef inline int import_array() except -1: + * try: # <<<<<<<<<<<<<< + * __pyx_import_array() + * except Exception: + */ + __pyx_L5_except_error:; + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + goto __pyx_L1_error; + __pyx_L8_try_end:; + } + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":980 + * # Versions of the import_* functions which are more suitable for + * # Cython code. + * cdef inline int import_array() except -1: # <<<<<<<<<<<<<< + * try: + * __pyx_import_array() + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("numpy.import_array", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":986 + * raise ImportError("numpy.core.multiarray failed to import") + * + * cdef inline int import_umath() except -1: # <<<<<<<<<<<<<< + * try: + * _import_umath() + */ + +static CYTHON_INLINE int __pyx_f_5numpy_import_umath(void) { + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("import_umath", 1); + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":987 + * + * cdef inline int import_umath() except -1: + * try: # <<<<<<<<<<<<<< + * _import_umath() + * except Exception: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + /*try:*/ { + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":988 + * cdef inline int import_umath() except -1: + * try: + * _import_umath() # <<<<<<<<<<<<<< + * except Exception: + * raise ImportError("numpy.core.umath failed to import") + */ + __pyx_t_4 = _import_umath(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 988, __pyx_L3_error) + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":987 + * + * cdef inline int import_umath() except -1: + * try: # <<<<<<<<<<<<<< + * _import_umath() + * except Exception: + */ + } + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L8_try_end; + __pyx_L3_error:; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":989 + * try: + * _import_umath() + * except Exception: # <<<<<<<<<<<<<< + * raise ImportError("numpy.core.umath failed to import") + * + */ + __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); + if (__pyx_t_4) { + __Pyx_AddTraceback("numpy.import_umath", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(1, 989, __pyx_L5_except_error) + __Pyx_XGOTREF(__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_6); + __Pyx_XGOTREF(__pyx_t_7); + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":990 + * _import_umath() + * except Exception: + * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< + * + * cdef inline int import_ufunc() except -1: + */ + __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 990, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_Raise(__pyx_t_8, 0, 0, 0); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __PYX_ERR(1, 990, __pyx_L5_except_error) + } + goto __pyx_L5_except_error; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":987 + * + * cdef inline int import_umath() except -1: + * try: # <<<<<<<<<<<<<< + * _import_umath() + * except Exception: + */ + __pyx_L5_except_error:; + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + goto __pyx_L1_error; + __pyx_L8_try_end:; + } + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":986 + * raise ImportError("numpy.core.multiarray failed to import") + * + * cdef inline int import_umath() except -1: # <<<<<<<<<<<<<< + * try: + * _import_umath() + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("numpy.import_umath", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":992 + * raise ImportError("numpy.core.umath failed to import") + * + * cdef inline int import_ufunc() except -1: # <<<<<<<<<<<<<< + * try: + * _import_umath() + */ + +static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("import_ufunc", 1); + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":993 + * + * cdef inline int import_ufunc() except -1: + * try: # <<<<<<<<<<<<<< + * _import_umath() + * except Exception: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + /*try:*/ { + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":994 + * cdef inline int import_ufunc() except -1: + * try: + * _import_umath() # <<<<<<<<<<<<<< + * except Exception: + * raise ImportError("numpy.core.umath failed to import") + */ + __pyx_t_4 = _import_umath(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 994, __pyx_L3_error) + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":993 + * + * cdef inline int import_ufunc() except -1: + * try: # <<<<<<<<<<<<<< + * _import_umath() + * except Exception: + */ + } + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L8_try_end; + __pyx_L3_error:; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":995 + * try: + * _import_umath() + * except Exception: # <<<<<<<<<<<<<< + * raise ImportError("numpy.core.umath failed to import") + * + */ + __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); + if (__pyx_t_4) { + __Pyx_AddTraceback("numpy.import_ufunc", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(1, 995, __pyx_L5_except_error) + __Pyx_XGOTREF(__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_6); + __Pyx_XGOTREF(__pyx_t_7); + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":996 + * _import_umath() + * except Exception: + * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 996, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_Raise(__pyx_t_8, 0, 0, 0); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __PYX_ERR(1, 996, __pyx_L5_except_error) + } + goto __pyx_L5_except_error; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":993 + * + * cdef inline int import_ufunc() except -1: + * try: # <<<<<<<<<<<<<< + * _import_umath() + * except Exception: + */ + __pyx_L5_except_error:; + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + goto __pyx_L1_error; + __pyx_L8_try_end:; + } + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":992 + * raise ImportError("numpy.core.umath failed to import") + * + * cdef inline int import_ufunc() except -1: # <<<<<<<<<<<<<< + * try: + * _import_umath() + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("numpy.import_ufunc", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":999 + * + * + * cdef inline bint is_timedelta64_object(object obj): # <<<<<<<<<<<<<< + * """ + * Cython equivalent of `isinstance(obj, np.timedelta64)` + */ + +static CYTHON_INLINE int __pyx_f_5numpy_is_timedelta64_object(PyObject *__pyx_v_obj) { + int __pyx_r; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":1011 + * bool + * """ + * return PyObject_TypeCheck(obj, &PyTimedeltaArrType_Type) # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = PyObject_TypeCheck(__pyx_v_obj, (&PyTimedeltaArrType_Type)); + goto __pyx_L0; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":999 + * + * + * cdef inline bint is_timedelta64_object(object obj): # <<<<<<<<<<<<<< + * """ + * Cython equivalent of `isinstance(obj, np.timedelta64)` + */ + + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":1014 + * + * + * cdef inline bint is_datetime64_object(object obj): # <<<<<<<<<<<<<< + * """ + * Cython equivalent of `isinstance(obj, np.datetime64)` + */ + +static CYTHON_INLINE int __pyx_f_5numpy_is_datetime64_object(PyObject *__pyx_v_obj) { + int __pyx_r; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":1026 + * bool + * """ + * return PyObject_TypeCheck(obj, &PyDatetimeArrType_Type) # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = PyObject_TypeCheck(__pyx_v_obj, (&PyDatetimeArrType_Type)); + goto __pyx_L0; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":1014 + * + * + * cdef inline bint is_datetime64_object(object obj): # <<<<<<<<<<<<<< + * """ + * Cython equivalent of `isinstance(obj, np.datetime64)` + */ + + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":1029 + * + * + * cdef inline npy_datetime get_datetime64_value(object obj) nogil: # <<<<<<<<<<<<<< + * """ + * returns the int64 value underlying scalar numpy datetime64 object + */ + +static CYTHON_INLINE npy_datetime __pyx_f_5numpy_get_datetime64_value(PyObject *__pyx_v_obj) { + npy_datetime __pyx_r; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":1036 + * also needed. That can be found using `get_datetime64_unit`. + * """ + * return (obj).obval # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = ((PyDatetimeScalarObject *)__pyx_v_obj)->obval; + goto __pyx_L0; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":1029 + * + * + * cdef inline npy_datetime get_datetime64_value(object obj) nogil: # <<<<<<<<<<<<<< + * """ + * returns the int64 value underlying scalar numpy datetime64 object + */ + + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":1039 + * + * + * cdef inline npy_timedelta get_timedelta64_value(object obj) nogil: # <<<<<<<<<<<<<< + * """ + * returns the int64 value underlying scalar numpy timedelta64 object + */ + +static CYTHON_INLINE npy_timedelta __pyx_f_5numpy_get_timedelta64_value(PyObject *__pyx_v_obj) { + npy_timedelta __pyx_r; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":1043 + * returns the int64 value underlying scalar numpy timedelta64 object + * """ + * return (obj).obval # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = ((PyTimedeltaScalarObject *)__pyx_v_obj)->obval; + goto __pyx_L0; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":1039 + * + * + * cdef inline npy_timedelta get_timedelta64_value(object obj) nogil: # <<<<<<<<<<<<<< + * """ + * returns the int64 value underlying scalar numpy timedelta64 object + */ + + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} + +/* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":1046 + * + * + * cdef inline NPY_DATETIMEUNIT get_datetime64_unit(object obj) nogil: # <<<<<<<<<<<<<< + * """ + * returns the unit part of the dtype for a numpy datetime64 object. + */ + +static CYTHON_INLINE NPY_DATETIMEUNIT __pyx_f_5numpy_get_datetime64_unit(PyObject *__pyx_v_obj) { + NPY_DATETIMEUNIT __pyx_r; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":1050 + * returns the unit part of the dtype for a numpy datetime64 object. + * """ + * return (obj).obmeta.base # <<<<<<<<<<<<<< + */ + __pyx_r = ((NPY_DATETIMEUNIT)((PyDatetimeScalarObject *)__pyx_v_obj)->obmeta.base); + goto __pyx_L0; + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":1046 + * + * + * cdef inline NPY_DATETIMEUNIT get_datetime64_unit(object obj) nogil: # <<<<<<<<<<<<<< + * """ + * returns the unit part of the dtype for a numpy datetime64 object. + */ + + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} + +/* "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx":40 + * int nver, int ntri, int ntexver) + * + * def get_normal_core(np.ndarray[float, ndim=2, mode = "c"] normal not None, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] tri_normal not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_1get_normal_core(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +static PyMethodDef __pyx_mdef_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_1get_normal_core = {"get_normal_core", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_1get_normal_core, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}; +static PyObject *__pyx_pw_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_1get_normal_core(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyArrayObject *__pyx_v_normal = 0; + PyArrayObject *__pyx_v_tri_normal = 0; + PyArrayObject *__pyx_v_triangles = 0; + int __pyx_v_ntri; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("get_normal_core (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_normal,&__pyx_n_s_tri_normal,&__pyx_n_s_triangles,&__pyx_n_s_ntri,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_normal)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 40, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_tri_normal)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 40, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("get_normal_core", 1, 4, 4, 1); __PYX_ERR(2, 40, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_triangles)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 40, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("get_normal_core", 1, 4, 4, 2); __PYX_ERR(2, 40, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_ntri)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 40, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("get_normal_core", 1, 4, 4, 3); __PYX_ERR(2, 40, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "get_normal_core") < 0)) __PYX_ERR(2, 40, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + } + __pyx_v_normal = ((PyArrayObject *)values[0]); + __pyx_v_tri_normal = ((PyArrayObject *)values[1]); + __pyx_v_triangles = ((PyArrayObject *)values[2]); + __pyx_v_ntri = __Pyx_PyInt_As_int(values[3]); if (unlikely((__pyx_v_ntri == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 43, __pyx_L3_error) + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("get_normal_core", 1, 4, 4, __pyx_nargs); __PYX_ERR(2, 40, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("insightface.thirdparty.face3d.mesh.cython.mesh_core_cython.get_normal_core", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_normal), __pyx_ptype_5numpy_ndarray, 0, "normal", 0))) __PYX_ERR(2, 40, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_tri_normal), __pyx_ptype_5numpy_ndarray, 0, "tri_normal", 0))) __PYX_ERR(2, 41, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_triangles), __pyx_ptype_5numpy_ndarray, 0, "triangles", 0))) __PYX_ERR(2, 42, __pyx_L1_error) + __pyx_r = __pyx_pf_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_get_normal_core(__pyx_self, __pyx_v_normal, __pyx_v_tri_normal, __pyx_v_triangles, __pyx_v_ntri); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_get_normal_core(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_normal, PyArrayObject *__pyx_v_tri_normal, PyArrayObject *__pyx_v_triangles, int __pyx_v_ntri) { + __Pyx_LocalBuf_ND __pyx_pybuffernd_normal; + __Pyx_Buffer __pyx_pybuffer_normal; + __Pyx_LocalBuf_ND __pyx_pybuffernd_tri_normal; + __Pyx_Buffer __pyx_pybuffer_tri_normal; + __Pyx_LocalBuf_ND __pyx_pybuffernd_triangles; + __Pyx_Buffer __pyx_pybuffer_triangles; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("get_normal_core", 1); + __pyx_pybuffer_normal.pybuffer.buf = NULL; + __pyx_pybuffer_normal.refcount = 0; + __pyx_pybuffernd_normal.data = NULL; + __pyx_pybuffernd_normal.rcbuffer = &__pyx_pybuffer_normal; + __pyx_pybuffer_tri_normal.pybuffer.buf = NULL; + __pyx_pybuffer_tri_normal.refcount = 0; + __pyx_pybuffernd_tri_normal.data = NULL; + __pyx_pybuffernd_tri_normal.rcbuffer = &__pyx_pybuffer_tri_normal; + __pyx_pybuffer_triangles.pybuffer.buf = NULL; + __pyx_pybuffer_triangles.refcount = 0; + __pyx_pybuffernd_triangles.data = NULL; + __pyx_pybuffernd_triangles.rcbuffer = &__pyx_pybuffer_triangles; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_normal.rcbuffer->pybuffer, (PyObject*)__pyx_v_normal, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(2, 40, __pyx_L1_error) + } + __pyx_pybuffernd_normal.diminfo[0].strides = __pyx_pybuffernd_normal.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_normal.diminfo[0].shape = __pyx_pybuffernd_normal.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_normal.diminfo[1].strides = __pyx_pybuffernd_normal.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_normal.diminfo[1].shape = __pyx_pybuffernd_normal.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_tri_normal.rcbuffer->pybuffer, (PyObject*)__pyx_v_tri_normal, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(2, 40, __pyx_L1_error) + } + __pyx_pybuffernd_tri_normal.diminfo[0].strides = __pyx_pybuffernd_tri_normal.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_tri_normal.diminfo[0].shape = __pyx_pybuffernd_tri_normal.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_tri_normal.diminfo[1].strides = __pyx_pybuffernd_tri_normal.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_tri_normal.diminfo[1].shape = __pyx_pybuffernd_tri_normal.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer, (PyObject*)__pyx_v_triangles, &__Pyx_TypeInfo_int, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(2, 40, __pyx_L1_error) + } + __pyx_pybuffernd_triangles.diminfo[0].strides = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_triangles.diminfo[0].shape = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_triangles.diminfo[1].strides = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_triangles.diminfo[1].shape = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.shape[1]; + + /* "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx":45 + * int ntri + * ): + * _get_normal_core( # <<<<<<<<<<<<<< + * np.PyArray_DATA(normal), np.PyArray_DATA(tri_normal), np.PyArray_DATA(triangles), + * ntri) + */ + _get_normal_core(((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_normal))), ((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_tri_normal))), ((int *)PyArray_DATA(((PyArrayObject *)__pyx_v_triangles))), __pyx_v_ntri); + + /* "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx":40 + * int nver, int ntri, int ntexver) + * + * def get_normal_core(np.ndarray[float, ndim=2, mode = "c"] normal not None, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] tri_normal not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_normal.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tri_normal.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer); + __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} + __Pyx_AddTraceback("insightface.thirdparty.face3d.mesh.cython.mesh_core_cython.get_normal_core", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + goto __pyx_L2; + __pyx_L0:; + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_normal.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tri_normal.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer); + __pyx_L2:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx":49 + * ntri) + * + * def rasterize_triangles_core( # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_3rasterize_triangles_core(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +static PyMethodDef __pyx_mdef_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_3rasterize_triangles_core = {"rasterize_triangles_core", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_3rasterize_triangles_core, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}; +static PyObject *__pyx_pw_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_3rasterize_triangles_core(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyArrayObject *__pyx_v_vertices = 0; + PyArrayObject *__pyx_v_triangles = 0; + PyArrayObject *__pyx_v_depth_buffer = 0; + PyArrayObject *__pyx_v_triangle_buffer = 0; + PyArrayObject *__pyx_v_barycentric_weight = 0; + int __pyx_v_nver; + int __pyx_v_ntri; + int __pyx_v_h; + int __pyx_v_w; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[9] = {0,0,0,0,0,0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("rasterize_triangles_core (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_vertices,&__pyx_n_s_triangles,&__pyx_n_s_depth_buffer,&__pyx_n_s_triangle_buffer,&__pyx_n_s_barycentric_weight,&__pyx_n_s_nver,&__pyx_n_s_ntri,&__pyx_n_s_h,&__pyx_n_s_w,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 9: values[8] = __Pyx_Arg_FASTCALL(__pyx_args, 8); + CYTHON_FALLTHROUGH; + case 8: values[7] = __Pyx_Arg_FASTCALL(__pyx_args, 7); + CYTHON_FALLTHROUGH; + case 7: values[6] = __Pyx_Arg_FASTCALL(__pyx_args, 6); + CYTHON_FALLTHROUGH; + case 6: values[5] = __Pyx_Arg_FASTCALL(__pyx_args, 5); + CYTHON_FALLTHROUGH; + case 5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_vertices)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 49, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_triangles)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 49, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("rasterize_triangles_core", 1, 9, 9, 1); __PYX_ERR(2, 49, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_depth_buffer)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 49, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("rasterize_triangles_core", 1, 9, 9, 2); __PYX_ERR(2, 49, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_triangle_buffer)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 49, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("rasterize_triangles_core", 1, 9, 9, 3); __PYX_ERR(2, 49, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 4: + if (likely((values[4] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_barycentric_weight)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[4]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 49, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("rasterize_triangles_core", 1, 9, 9, 4); __PYX_ERR(2, 49, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 5: + if (likely((values[5] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_nver)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[5]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 49, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("rasterize_triangles_core", 1, 9, 9, 5); __PYX_ERR(2, 49, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 6: + if (likely((values[6] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_ntri)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[6]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 49, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("rasterize_triangles_core", 1, 9, 9, 6); __PYX_ERR(2, 49, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 7: + if (likely((values[7] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_h)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[7]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 49, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("rasterize_triangles_core", 1, 9, 9, 7); __PYX_ERR(2, 49, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 8: + if (likely((values[8] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_w)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[8]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 49, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("rasterize_triangles_core", 1, 9, 9, 8); __PYX_ERR(2, 49, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "rasterize_triangles_core") < 0)) __PYX_ERR(2, 49, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 9)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + values[5] = __Pyx_Arg_FASTCALL(__pyx_args, 5); + values[6] = __Pyx_Arg_FASTCALL(__pyx_args, 6); + values[7] = __Pyx_Arg_FASTCALL(__pyx_args, 7); + values[8] = __Pyx_Arg_FASTCALL(__pyx_args, 8); + } + __pyx_v_vertices = ((PyArrayObject *)values[0]); + __pyx_v_triangles = ((PyArrayObject *)values[1]); + __pyx_v_depth_buffer = ((PyArrayObject *)values[2]); + __pyx_v_triangle_buffer = ((PyArrayObject *)values[3]); + __pyx_v_barycentric_weight = ((PyArrayObject *)values[4]); + __pyx_v_nver = __Pyx_PyInt_As_int(values[5]); if (unlikely((__pyx_v_nver == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 55, __pyx_L3_error) + __pyx_v_ntri = __Pyx_PyInt_As_int(values[6]); if (unlikely((__pyx_v_ntri == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 55, __pyx_L3_error) + __pyx_v_h = __Pyx_PyInt_As_int(values[7]); if (unlikely((__pyx_v_h == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 56, __pyx_L3_error) + __pyx_v_w = __Pyx_PyInt_As_int(values[8]); if (unlikely((__pyx_v_w == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 56, __pyx_L3_error) + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("rasterize_triangles_core", 1, 9, 9, __pyx_nargs); __PYX_ERR(2, 49, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("insightface.thirdparty.face3d.mesh.cython.mesh_core_cython.rasterize_triangles_core", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_vertices), __pyx_ptype_5numpy_ndarray, 0, "vertices", 0))) __PYX_ERR(2, 50, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_triangles), __pyx_ptype_5numpy_ndarray, 0, "triangles", 0))) __PYX_ERR(2, 51, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_depth_buffer), __pyx_ptype_5numpy_ndarray, 0, "depth_buffer", 0))) __PYX_ERR(2, 52, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_triangle_buffer), __pyx_ptype_5numpy_ndarray, 0, "triangle_buffer", 0))) __PYX_ERR(2, 53, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_barycentric_weight), __pyx_ptype_5numpy_ndarray, 0, "barycentric_weight", 0))) __PYX_ERR(2, 54, __pyx_L1_error) + __pyx_r = __pyx_pf_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_2rasterize_triangles_core(__pyx_self, __pyx_v_vertices, __pyx_v_triangles, __pyx_v_depth_buffer, __pyx_v_triangle_buffer, __pyx_v_barycentric_weight, __pyx_v_nver, __pyx_v_ntri, __pyx_v_h, __pyx_v_w); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_2rasterize_triangles_core(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_vertices, PyArrayObject *__pyx_v_triangles, PyArrayObject *__pyx_v_depth_buffer, PyArrayObject *__pyx_v_triangle_buffer, PyArrayObject *__pyx_v_barycentric_weight, int __pyx_v_nver, int __pyx_v_ntri, int __pyx_v_h, int __pyx_v_w) { + __Pyx_LocalBuf_ND __pyx_pybuffernd_barycentric_weight; + __Pyx_Buffer __pyx_pybuffer_barycentric_weight; + __Pyx_LocalBuf_ND __pyx_pybuffernd_depth_buffer; + __Pyx_Buffer __pyx_pybuffer_depth_buffer; + __Pyx_LocalBuf_ND __pyx_pybuffernd_triangle_buffer; + __Pyx_Buffer __pyx_pybuffer_triangle_buffer; + __Pyx_LocalBuf_ND __pyx_pybuffernd_triangles; + __Pyx_Buffer __pyx_pybuffer_triangles; + __Pyx_LocalBuf_ND __pyx_pybuffernd_vertices; + __Pyx_Buffer __pyx_pybuffer_vertices; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("rasterize_triangles_core", 1); + __pyx_pybuffer_vertices.pybuffer.buf = NULL; + __pyx_pybuffer_vertices.refcount = 0; + __pyx_pybuffernd_vertices.data = NULL; + __pyx_pybuffernd_vertices.rcbuffer = &__pyx_pybuffer_vertices; + __pyx_pybuffer_triangles.pybuffer.buf = NULL; + __pyx_pybuffer_triangles.refcount = 0; + __pyx_pybuffernd_triangles.data = NULL; + __pyx_pybuffernd_triangles.rcbuffer = &__pyx_pybuffer_triangles; + __pyx_pybuffer_depth_buffer.pybuffer.buf = NULL; + __pyx_pybuffer_depth_buffer.refcount = 0; + __pyx_pybuffernd_depth_buffer.data = NULL; + __pyx_pybuffernd_depth_buffer.rcbuffer = &__pyx_pybuffer_depth_buffer; + __pyx_pybuffer_triangle_buffer.pybuffer.buf = NULL; + __pyx_pybuffer_triangle_buffer.refcount = 0; + __pyx_pybuffernd_triangle_buffer.data = NULL; + __pyx_pybuffernd_triangle_buffer.rcbuffer = &__pyx_pybuffer_triangle_buffer; + __pyx_pybuffer_barycentric_weight.pybuffer.buf = NULL; + __pyx_pybuffer_barycentric_weight.refcount = 0; + __pyx_pybuffernd_barycentric_weight.data = NULL; + __pyx_pybuffernd_barycentric_weight.rcbuffer = &__pyx_pybuffer_barycentric_weight; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertices.rcbuffer->pybuffer, (PyObject*)__pyx_v_vertices, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(2, 49, __pyx_L1_error) + } + __pyx_pybuffernd_vertices.diminfo[0].strides = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_vertices.diminfo[0].shape = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_vertices.diminfo[1].strides = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_vertices.diminfo[1].shape = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer, (PyObject*)__pyx_v_triangles, &__Pyx_TypeInfo_int, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(2, 49, __pyx_L1_error) + } + __pyx_pybuffernd_triangles.diminfo[0].strides = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_triangles.diminfo[0].shape = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_triangles.diminfo[1].strides = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_triangles.diminfo[1].shape = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer, (PyObject*)__pyx_v_depth_buffer, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(2, 49, __pyx_L1_error) + } + __pyx_pybuffernd_depth_buffer.diminfo[0].strides = __pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_depth_buffer.diminfo[0].shape = __pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_depth_buffer.diminfo[1].strides = __pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_depth_buffer.diminfo[1].shape = __pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_triangle_buffer.rcbuffer->pybuffer, (PyObject*)__pyx_v_triangle_buffer, &__Pyx_TypeInfo_int, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(2, 49, __pyx_L1_error) + } + __pyx_pybuffernd_triangle_buffer.diminfo[0].strides = __pyx_pybuffernd_triangle_buffer.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_triangle_buffer.diminfo[0].shape = __pyx_pybuffernd_triangle_buffer.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_triangle_buffer.diminfo[1].strides = __pyx_pybuffernd_triangle_buffer.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_triangle_buffer.diminfo[1].shape = __pyx_pybuffernd_triangle_buffer.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_barycentric_weight.rcbuffer->pybuffer, (PyObject*)__pyx_v_barycentric_weight, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(2, 49, __pyx_L1_error) + } + __pyx_pybuffernd_barycentric_weight.diminfo[0].strides = __pyx_pybuffernd_barycentric_weight.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_barycentric_weight.diminfo[0].shape = __pyx_pybuffernd_barycentric_weight.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_barycentric_weight.diminfo[1].strides = __pyx_pybuffernd_barycentric_weight.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_barycentric_weight.diminfo[1].shape = __pyx_pybuffernd_barycentric_weight.rcbuffer->pybuffer.shape[1]; + + /* "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx":58 + * int h, int w + * ): + * _rasterize_triangles_core( # <<<<<<<<<<<<<< + * np.PyArray_DATA(vertices), np.PyArray_DATA(triangles), + * np.PyArray_DATA(depth_buffer), np.PyArray_DATA(triangle_buffer), np.PyArray_DATA(barycentric_weight), + */ + _rasterize_triangles_core(((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_vertices))), ((int *)PyArray_DATA(((PyArrayObject *)__pyx_v_triangles))), ((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_depth_buffer))), ((int *)PyArray_DATA(((PyArrayObject *)__pyx_v_triangle_buffer))), ((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_barycentric_weight))), __pyx_v_nver, __pyx_v_ntri, __pyx_v_h, __pyx_v_w); + + /* "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx":49 + * ntri) + * + * def rasterize_triangles_core( # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_barycentric_weight.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_triangle_buffer.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertices.rcbuffer->pybuffer); + __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} + __Pyx_AddTraceback("insightface.thirdparty.face3d.mesh.cython.mesh_core_cython.rasterize_triangles_core", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + goto __pyx_L2; + __pyx_L0:; + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_barycentric_weight.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_triangle_buffer.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertices.rcbuffer->pybuffer); + __pyx_L2:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx":64 + * h, w) + * + * def render_colors_core(np.ndarray[float, ndim=3, mode = "c"] image not None, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_5render_colors_core(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +static PyMethodDef __pyx_mdef_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_5render_colors_core = {"render_colors_core", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_5render_colors_core, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}; +static PyObject *__pyx_pw_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_5render_colors_core(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyArrayObject *__pyx_v_image = 0; + PyArrayObject *__pyx_v_vertices = 0; + PyArrayObject *__pyx_v_triangles = 0; + PyArrayObject *__pyx_v_colors = 0; + PyArrayObject *__pyx_v_depth_buffer = 0; + int __pyx_v_nver; + int __pyx_v_ntri; + int __pyx_v_h; + int __pyx_v_w; + int __pyx_v_c; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[10] = {0,0,0,0,0,0,0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("render_colors_core (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_image,&__pyx_n_s_vertices,&__pyx_n_s_triangles,&__pyx_n_s_colors,&__pyx_n_s_depth_buffer,&__pyx_n_s_nver,&__pyx_n_s_ntri,&__pyx_n_s_h,&__pyx_n_s_w,&__pyx_n_s_c,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 10: values[9] = __Pyx_Arg_FASTCALL(__pyx_args, 9); + CYTHON_FALLTHROUGH; + case 9: values[8] = __Pyx_Arg_FASTCALL(__pyx_args, 8); + CYTHON_FALLTHROUGH; + case 8: values[7] = __Pyx_Arg_FASTCALL(__pyx_args, 7); + CYTHON_FALLTHROUGH; + case 7: values[6] = __Pyx_Arg_FASTCALL(__pyx_args, 6); + CYTHON_FALLTHROUGH; + case 6: values[5] = __Pyx_Arg_FASTCALL(__pyx_args, 5); + CYTHON_FALLTHROUGH; + case 5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_image)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 64, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_vertices)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 64, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("render_colors_core", 1, 10, 10, 1); __PYX_ERR(2, 64, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_triangles)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 64, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("render_colors_core", 1, 10, 10, 2); __PYX_ERR(2, 64, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_colors)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 64, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("render_colors_core", 1, 10, 10, 3); __PYX_ERR(2, 64, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 4: + if (likely((values[4] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_depth_buffer)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[4]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 64, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("render_colors_core", 1, 10, 10, 4); __PYX_ERR(2, 64, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 5: + if (likely((values[5] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_nver)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[5]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 64, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("render_colors_core", 1, 10, 10, 5); __PYX_ERR(2, 64, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 6: + if (likely((values[6] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_ntri)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[6]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 64, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("render_colors_core", 1, 10, 10, 6); __PYX_ERR(2, 64, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 7: + if (likely((values[7] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_h)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[7]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 64, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("render_colors_core", 1, 10, 10, 7); __PYX_ERR(2, 64, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 8: + if (likely((values[8] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_w)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[8]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 64, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("render_colors_core", 1, 10, 10, 8); __PYX_ERR(2, 64, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 9: + if (likely((values[9] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_c)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[9]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 64, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("render_colors_core", 1, 10, 10, 9); __PYX_ERR(2, 64, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "render_colors_core") < 0)) __PYX_ERR(2, 64, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 10)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + values[5] = __Pyx_Arg_FASTCALL(__pyx_args, 5); + values[6] = __Pyx_Arg_FASTCALL(__pyx_args, 6); + values[7] = __Pyx_Arg_FASTCALL(__pyx_args, 7); + values[8] = __Pyx_Arg_FASTCALL(__pyx_args, 8); + values[9] = __Pyx_Arg_FASTCALL(__pyx_args, 9); + } + __pyx_v_image = ((PyArrayObject *)values[0]); + __pyx_v_vertices = ((PyArrayObject *)values[1]); + __pyx_v_triangles = ((PyArrayObject *)values[2]); + __pyx_v_colors = ((PyArrayObject *)values[3]); + __pyx_v_depth_buffer = ((PyArrayObject *)values[4]); + __pyx_v_nver = __Pyx_PyInt_As_int(values[5]); if (unlikely((__pyx_v_nver == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 69, __pyx_L3_error) + __pyx_v_ntri = __Pyx_PyInt_As_int(values[6]); if (unlikely((__pyx_v_ntri == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 69, __pyx_L3_error) + __pyx_v_h = __Pyx_PyInt_As_int(values[7]); if (unlikely((__pyx_v_h == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 70, __pyx_L3_error) + __pyx_v_w = __Pyx_PyInt_As_int(values[8]); if (unlikely((__pyx_v_w == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 70, __pyx_L3_error) + __pyx_v_c = __Pyx_PyInt_As_int(values[9]); if (unlikely((__pyx_v_c == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 70, __pyx_L3_error) + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("render_colors_core", 1, 10, 10, __pyx_nargs); __PYX_ERR(2, 64, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("insightface.thirdparty.face3d.mesh.cython.mesh_core_cython.render_colors_core", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_image), __pyx_ptype_5numpy_ndarray, 0, "image", 0))) __PYX_ERR(2, 64, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_vertices), __pyx_ptype_5numpy_ndarray, 0, "vertices", 0))) __PYX_ERR(2, 65, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_triangles), __pyx_ptype_5numpy_ndarray, 0, "triangles", 0))) __PYX_ERR(2, 66, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_colors), __pyx_ptype_5numpy_ndarray, 0, "colors", 0))) __PYX_ERR(2, 67, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_depth_buffer), __pyx_ptype_5numpy_ndarray, 0, "depth_buffer", 0))) __PYX_ERR(2, 68, __pyx_L1_error) + __pyx_r = __pyx_pf_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_4render_colors_core(__pyx_self, __pyx_v_image, __pyx_v_vertices, __pyx_v_triangles, __pyx_v_colors, __pyx_v_depth_buffer, __pyx_v_nver, __pyx_v_ntri, __pyx_v_h, __pyx_v_w, __pyx_v_c); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_4render_colors_core(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_image, PyArrayObject *__pyx_v_vertices, PyArrayObject *__pyx_v_triangles, PyArrayObject *__pyx_v_colors, PyArrayObject *__pyx_v_depth_buffer, int __pyx_v_nver, int __pyx_v_ntri, int __pyx_v_h, int __pyx_v_w, int __pyx_v_c) { + __Pyx_LocalBuf_ND __pyx_pybuffernd_colors; + __Pyx_Buffer __pyx_pybuffer_colors; + __Pyx_LocalBuf_ND __pyx_pybuffernd_depth_buffer; + __Pyx_Buffer __pyx_pybuffer_depth_buffer; + __Pyx_LocalBuf_ND __pyx_pybuffernd_image; + __Pyx_Buffer __pyx_pybuffer_image; + __Pyx_LocalBuf_ND __pyx_pybuffernd_triangles; + __Pyx_Buffer __pyx_pybuffer_triangles; + __Pyx_LocalBuf_ND __pyx_pybuffernd_vertices; + __Pyx_Buffer __pyx_pybuffer_vertices; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("render_colors_core", 1); + __pyx_pybuffer_image.pybuffer.buf = NULL; + __pyx_pybuffer_image.refcount = 0; + __pyx_pybuffernd_image.data = NULL; + __pyx_pybuffernd_image.rcbuffer = &__pyx_pybuffer_image; + __pyx_pybuffer_vertices.pybuffer.buf = NULL; + __pyx_pybuffer_vertices.refcount = 0; + __pyx_pybuffernd_vertices.data = NULL; + __pyx_pybuffernd_vertices.rcbuffer = &__pyx_pybuffer_vertices; + __pyx_pybuffer_triangles.pybuffer.buf = NULL; + __pyx_pybuffer_triangles.refcount = 0; + __pyx_pybuffernd_triangles.data = NULL; + __pyx_pybuffernd_triangles.rcbuffer = &__pyx_pybuffer_triangles; + __pyx_pybuffer_colors.pybuffer.buf = NULL; + __pyx_pybuffer_colors.refcount = 0; + __pyx_pybuffernd_colors.data = NULL; + __pyx_pybuffernd_colors.rcbuffer = &__pyx_pybuffer_colors; + __pyx_pybuffer_depth_buffer.pybuffer.buf = NULL; + __pyx_pybuffer_depth_buffer.refcount = 0; + __pyx_pybuffernd_depth_buffer.data = NULL; + __pyx_pybuffernd_depth_buffer.rcbuffer = &__pyx_pybuffer_depth_buffer; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_image.rcbuffer->pybuffer, (PyObject*)__pyx_v_image, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 3, 0, __pyx_stack) == -1)) __PYX_ERR(2, 64, __pyx_L1_error) + } + __pyx_pybuffernd_image.diminfo[0].strides = __pyx_pybuffernd_image.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_image.diminfo[0].shape = __pyx_pybuffernd_image.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_image.diminfo[1].strides = __pyx_pybuffernd_image.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_image.diminfo[1].shape = __pyx_pybuffernd_image.rcbuffer->pybuffer.shape[1]; __pyx_pybuffernd_image.diminfo[2].strides = __pyx_pybuffernd_image.rcbuffer->pybuffer.strides[2]; __pyx_pybuffernd_image.diminfo[2].shape = __pyx_pybuffernd_image.rcbuffer->pybuffer.shape[2]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertices.rcbuffer->pybuffer, (PyObject*)__pyx_v_vertices, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(2, 64, __pyx_L1_error) + } + __pyx_pybuffernd_vertices.diminfo[0].strides = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_vertices.diminfo[0].shape = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_vertices.diminfo[1].strides = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_vertices.diminfo[1].shape = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer, (PyObject*)__pyx_v_triangles, &__Pyx_TypeInfo_int, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(2, 64, __pyx_L1_error) + } + __pyx_pybuffernd_triangles.diminfo[0].strides = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_triangles.diminfo[0].shape = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_triangles.diminfo[1].strides = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_triangles.diminfo[1].shape = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_colors.rcbuffer->pybuffer, (PyObject*)__pyx_v_colors, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(2, 64, __pyx_L1_error) + } + __pyx_pybuffernd_colors.diminfo[0].strides = __pyx_pybuffernd_colors.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_colors.diminfo[0].shape = __pyx_pybuffernd_colors.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_colors.diminfo[1].strides = __pyx_pybuffernd_colors.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_colors.diminfo[1].shape = __pyx_pybuffernd_colors.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer, (PyObject*)__pyx_v_depth_buffer, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(2, 64, __pyx_L1_error) + } + __pyx_pybuffernd_depth_buffer.diminfo[0].strides = __pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_depth_buffer.diminfo[0].shape = __pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_depth_buffer.diminfo[1].strides = __pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_depth_buffer.diminfo[1].shape = __pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer.shape[1]; + + /* "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx":72 + * int h, int w, int c + * ): + * _render_colors_core( # <<<<<<<<<<<<<< + * np.PyArray_DATA(image), np.PyArray_DATA(vertices), np.PyArray_DATA(triangles), + * np.PyArray_DATA(colors), + */ + _render_colors_core(((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_image))), ((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_vertices))), ((int *)PyArray_DATA(((PyArrayObject *)__pyx_v_triangles))), ((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_colors))), ((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_depth_buffer))), __pyx_v_nver, __pyx_v_ntri, __pyx_v_h, __pyx_v_w, __pyx_v_c); + + /* "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx":64 + * h, w) + * + * def render_colors_core(np.ndarray[float, ndim=3, mode = "c"] image not None, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_colors.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_image.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertices.rcbuffer->pybuffer); + __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} + __Pyx_AddTraceback("insightface.thirdparty.face3d.mesh.cython.mesh_core_cython.render_colors_core", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + goto __pyx_L2; + __pyx_L0:; + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_colors.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_image.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertices.rcbuffer->pybuffer); + __pyx_L2:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx":79 + * h, w, c) + * + * def render_texture_core(np.ndarray[float, ndim=3, mode = "c"] image not None, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_7render_texture_core(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +static PyMethodDef __pyx_mdef_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_7render_texture_core = {"render_texture_core", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_7render_texture_core, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}; +static PyObject *__pyx_pw_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_7render_texture_core(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyArrayObject *__pyx_v_image = 0; + PyArrayObject *__pyx_v_vertices = 0; + PyArrayObject *__pyx_v_triangles = 0; + PyArrayObject *__pyx_v_texture = 0; + PyArrayObject *__pyx_v_tex_coords = 0; + PyArrayObject *__pyx_v_tex_triangles = 0; + PyArrayObject *__pyx_v_depth_buffer = 0; + int __pyx_v_nver; + int __pyx_v_tex_nver; + int __pyx_v_ntri; + int __pyx_v_h; + int __pyx_v_w; + int __pyx_v_c; + int __pyx_v_tex_h; + int __pyx_v_tex_w; + int __pyx_v_tex_c; + int __pyx_v_mapping_type; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[17] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("render_texture_core (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_image,&__pyx_n_s_vertices,&__pyx_n_s_triangles,&__pyx_n_s_texture,&__pyx_n_s_tex_coords,&__pyx_n_s_tex_triangles,&__pyx_n_s_depth_buffer,&__pyx_n_s_nver,&__pyx_n_s_tex_nver,&__pyx_n_s_ntri,&__pyx_n_s_h,&__pyx_n_s_w,&__pyx_n_s_c,&__pyx_n_s_tex_h,&__pyx_n_s_tex_w,&__pyx_n_s_tex_c,&__pyx_n_s_mapping_type,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 17: values[16] = __Pyx_Arg_FASTCALL(__pyx_args, 16); + CYTHON_FALLTHROUGH; + case 16: values[15] = __Pyx_Arg_FASTCALL(__pyx_args, 15); + CYTHON_FALLTHROUGH; + case 15: values[14] = __Pyx_Arg_FASTCALL(__pyx_args, 14); + CYTHON_FALLTHROUGH; + case 14: values[13] = __Pyx_Arg_FASTCALL(__pyx_args, 13); + CYTHON_FALLTHROUGH; + case 13: values[12] = __Pyx_Arg_FASTCALL(__pyx_args, 12); + CYTHON_FALLTHROUGH; + case 12: values[11] = __Pyx_Arg_FASTCALL(__pyx_args, 11); + CYTHON_FALLTHROUGH; + case 11: values[10] = __Pyx_Arg_FASTCALL(__pyx_args, 10); + CYTHON_FALLTHROUGH; + case 10: values[9] = __Pyx_Arg_FASTCALL(__pyx_args, 9); + CYTHON_FALLTHROUGH; + case 9: values[8] = __Pyx_Arg_FASTCALL(__pyx_args, 8); + CYTHON_FALLTHROUGH; + case 8: values[7] = __Pyx_Arg_FASTCALL(__pyx_args, 7); + CYTHON_FALLTHROUGH; + case 7: values[6] = __Pyx_Arg_FASTCALL(__pyx_args, 6); + CYTHON_FALLTHROUGH; + case 6: values[5] = __Pyx_Arg_FASTCALL(__pyx_args, 5); + CYTHON_FALLTHROUGH; + case 5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_image)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 79, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_vertices)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 79, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 1); __PYX_ERR(2, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_triangles)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 79, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 2); __PYX_ERR(2, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_texture)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 79, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 3); __PYX_ERR(2, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 4: + if (likely((values[4] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_tex_coords)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[4]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 79, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 4); __PYX_ERR(2, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 5: + if (likely((values[5] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_tex_triangles)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[5]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 79, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 5); __PYX_ERR(2, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 6: + if (likely((values[6] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_depth_buffer)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[6]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 79, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 6); __PYX_ERR(2, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 7: + if (likely((values[7] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_nver)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[7]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 79, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 7); __PYX_ERR(2, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 8: + if (likely((values[8] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_tex_nver)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[8]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 79, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 8); __PYX_ERR(2, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 9: + if (likely((values[9] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_ntri)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[9]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 79, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 9); __PYX_ERR(2, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 10: + if (likely((values[10] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_h)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[10]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 79, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 10); __PYX_ERR(2, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 11: + if (likely((values[11] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_w)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[11]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 79, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 11); __PYX_ERR(2, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 12: + if (likely((values[12] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_c)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[12]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 79, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 12); __PYX_ERR(2, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 13: + if (likely((values[13] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_tex_h)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[13]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 79, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 13); __PYX_ERR(2, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 14: + if (likely((values[14] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_tex_w)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[14]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 79, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 14); __PYX_ERR(2, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 15: + if (likely((values[15] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_tex_c)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[15]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 79, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 15); __PYX_ERR(2, 79, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 16: + if (likely((values[16] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_mapping_type)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[16]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 79, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, 16); __PYX_ERR(2, 79, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "render_texture_core") < 0)) __PYX_ERR(2, 79, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 17)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + values[5] = __Pyx_Arg_FASTCALL(__pyx_args, 5); + values[6] = __Pyx_Arg_FASTCALL(__pyx_args, 6); + values[7] = __Pyx_Arg_FASTCALL(__pyx_args, 7); + values[8] = __Pyx_Arg_FASTCALL(__pyx_args, 8); + values[9] = __Pyx_Arg_FASTCALL(__pyx_args, 9); + values[10] = __Pyx_Arg_FASTCALL(__pyx_args, 10); + values[11] = __Pyx_Arg_FASTCALL(__pyx_args, 11); + values[12] = __Pyx_Arg_FASTCALL(__pyx_args, 12); + values[13] = __Pyx_Arg_FASTCALL(__pyx_args, 13); + values[14] = __Pyx_Arg_FASTCALL(__pyx_args, 14); + values[15] = __Pyx_Arg_FASTCALL(__pyx_args, 15); + values[16] = __Pyx_Arg_FASTCALL(__pyx_args, 16); + } + __pyx_v_image = ((PyArrayObject *)values[0]); + __pyx_v_vertices = ((PyArrayObject *)values[1]); + __pyx_v_triangles = ((PyArrayObject *)values[2]); + __pyx_v_texture = ((PyArrayObject *)values[3]); + __pyx_v_tex_coords = ((PyArrayObject *)values[4]); + __pyx_v_tex_triangles = ((PyArrayObject *)values[5]); + __pyx_v_depth_buffer = ((PyArrayObject *)values[6]); + __pyx_v_nver = __Pyx_PyInt_As_int(values[7]); if (unlikely((__pyx_v_nver == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 86, __pyx_L3_error) + __pyx_v_tex_nver = __Pyx_PyInt_As_int(values[8]); if (unlikely((__pyx_v_tex_nver == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 86, __pyx_L3_error) + __pyx_v_ntri = __Pyx_PyInt_As_int(values[9]); if (unlikely((__pyx_v_ntri == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 86, __pyx_L3_error) + __pyx_v_h = __Pyx_PyInt_As_int(values[10]); if (unlikely((__pyx_v_h == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 87, __pyx_L3_error) + __pyx_v_w = __Pyx_PyInt_As_int(values[11]); if (unlikely((__pyx_v_w == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 87, __pyx_L3_error) + __pyx_v_c = __Pyx_PyInt_As_int(values[12]); if (unlikely((__pyx_v_c == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 87, __pyx_L3_error) + __pyx_v_tex_h = __Pyx_PyInt_As_int(values[13]); if (unlikely((__pyx_v_tex_h == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 88, __pyx_L3_error) + __pyx_v_tex_w = __Pyx_PyInt_As_int(values[14]); if (unlikely((__pyx_v_tex_w == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 88, __pyx_L3_error) + __pyx_v_tex_c = __Pyx_PyInt_As_int(values[15]); if (unlikely((__pyx_v_tex_c == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 88, __pyx_L3_error) + __pyx_v_mapping_type = __Pyx_PyInt_As_int(values[16]); if (unlikely((__pyx_v_mapping_type == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 89, __pyx_L3_error) + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("render_texture_core", 1, 17, 17, __pyx_nargs); __PYX_ERR(2, 79, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("insightface.thirdparty.face3d.mesh.cython.mesh_core_cython.render_texture_core", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_image), __pyx_ptype_5numpy_ndarray, 0, "image", 0))) __PYX_ERR(2, 79, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_vertices), __pyx_ptype_5numpy_ndarray, 0, "vertices", 0))) __PYX_ERR(2, 80, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_triangles), __pyx_ptype_5numpy_ndarray, 0, "triangles", 0))) __PYX_ERR(2, 81, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_texture), __pyx_ptype_5numpy_ndarray, 0, "texture", 0))) __PYX_ERR(2, 82, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_tex_coords), __pyx_ptype_5numpy_ndarray, 0, "tex_coords", 0))) __PYX_ERR(2, 83, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_tex_triangles), __pyx_ptype_5numpy_ndarray, 0, "tex_triangles", 0))) __PYX_ERR(2, 84, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_depth_buffer), __pyx_ptype_5numpy_ndarray, 0, "depth_buffer", 0))) __PYX_ERR(2, 85, __pyx_L1_error) + __pyx_r = __pyx_pf_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_6render_texture_core(__pyx_self, __pyx_v_image, __pyx_v_vertices, __pyx_v_triangles, __pyx_v_texture, __pyx_v_tex_coords, __pyx_v_tex_triangles, __pyx_v_depth_buffer, __pyx_v_nver, __pyx_v_tex_nver, __pyx_v_ntri, __pyx_v_h, __pyx_v_w, __pyx_v_c, __pyx_v_tex_h, __pyx_v_tex_w, __pyx_v_tex_c, __pyx_v_mapping_type); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_6render_texture_core(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_image, PyArrayObject *__pyx_v_vertices, PyArrayObject *__pyx_v_triangles, PyArrayObject *__pyx_v_texture, PyArrayObject *__pyx_v_tex_coords, PyArrayObject *__pyx_v_tex_triangles, PyArrayObject *__pyx_v_depth_buffer, int __pyx_v_nver, int __pyx_v_tex_nver, int __pyx_v_ntri, int __pyx_v_h, int __pyx_v_w, int __pyx_v_c, int __pyx_v_tex_h, int __pyx_v_tex_w, int __pyx_v_tex_c, int __pyx_v_mapping_type) { + __Pyx_LocalBuf_ND __pyx_pybuffernd_depth_buffer; + __Pyx_Buffer __pyx_pybuffer_depth_buffer; + __Pyx_LocalBuf_ND __pyx_pybuffernd_image; + __Pyx_Buffer __pyx_pybuffer_image; + __Pyx_LocalBuf_ND __pyx_pybuffernd_tex_coords; + __Pyx_Buffer __pyx_pybuffer_tex_coords; + __Pyx_LocalBuf_ND __pyx_pybuffernd_tex_triangles; + __Pyx_Buffer __pyx_pybuffer_tex_triangles; + __Pyx_LocalBuf_ND __pyx_pybuffernd_texture; + __Pyx_Buffer __pyx_pybuffer_texture; + __Pyx_LocalBuf_ND __pyx_pybuffernd_triangles; + __Pyx_Buffer __pyx_pybuffer_triangles; + __Pyx_LocalBuf_ND __pyx_pybuffernd_vertices; + __Pyx_Buffer __pyx_pybuffer_vertices; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("render_texture_core", 1); + __pyx_pybuffer_image.pybuffer.buf = NULL; + __pyx_pybuffer_image.refcount = 0; + __pyx_pybuffernd_image.data = NULL; + __pyx_pybuffernd_image.rcbuffer = &__pyx_pybuffer_image; + __pyx_pybuffer_vertices.pybuffer.buf = NULL; + __pyx_pybuffer_vertices.refcount = 0; + __pyx_pybuffernd_vertices.data = NULL; + __pyx_pybuffernd_vertices.rcbuffer = &__pyx_pybuffer_vertices; + __pyx_pybuffer_triangles.pybuffer.buf = NULL; + __pyx_pybuffer_triangles.refcount = 0; + __pyx_pybuffernd_triangles.data = NULL; + __pyx_pybuffernd_triangles.rcbuffer = &__pyx_pybuffer_triangles; + __pyx_pybuffer_texture.pybuffer.buf = NULL; + __pyx_pybuffer_texture.refcount = 0; + __pyx_pybuffernd_texture.data = NULL; + __pyx_pybuffernd_texture.rcbuffer = &__pyx_pybuffer_texture; + __pyx_pybuffer_tex_coords.pybuffer.buf = NULL; + __pyx_pybuffer_tex_coords.refcount = 0; + __pyx_pybuffernd_tex_coords.data = NULL; + __pyx_pybuffernd_tex_coords.rcbuffer = &__pyx_pybuffer_tex_coords; + __pyx_pybuffer_tex_triangles.pybuffer.buf = NULL; + __pyx_pybuffer_tex_triangles.refcount = 0; + __pyx_pybuffernd_tex_triangles.data = NULL; + __pyx_pybuffernd_tex_triangles.rcbuffer = &__pyx_pybuffer_tex_triangles; + __pyx_pybuffer_depth_buffer.pybuffer.buf = NULL; + __pyx_pybuffer_depth_buffer.refcount = 0; + __pyx_pybuffernd_depth_buffer.data = NULL; + __pyx_pybuffernd_depth_buffer.rcbuffer = &__pyx_pybuffer_depth_buffer; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_image.rcbuffer->pybuffer, (PyObject*)__pyx_v_image, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 3, 0, __pyx_stack) == -1)) __PYX_ERR(2, 79, __pyx_L1_error) + } + __pyx_pybuffernd_image.diminfo[0].strides = __pyx_pybuffernd_image.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_image.diminfo[0].shape = __pyx_pybuffernd_image.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_image.diminfo[1].strides = __pyx_pybuffernd_image.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_image.diminfo[1].shape = __pyx_pybuffernd_image.rcbuffer->pybuffer.shape[1]; __pyx_pybuffernd_image.diminfo[2].strides = __pyx_pybuffernd_image.rcbuffer->pybuffer.strides[2]; __pyx_pybuffernd_image.diminfo[2].shape = __pyx_pybuffernd_image.rcbuffer->pybuffer.shape[2]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertices.rcbuffer->pybuffer, (PyObject*)__pyx_v_vertices, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(2, 79, __pyx_L1_error) + } + __pyx_pybuffernd_vertices.diminfo[0].strides = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_vertices.diminfo[0].shape = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_vertices.diminfo[1].strides = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_vertices.diminfo[1].shape = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer, (PyObject*)__pyx_v_triangles, &__Pyx_TypeInfo_int, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(2, 79, __pyx_L1_error) + } + __pyx_pybuffernd_triangles.diminfo[0].strides = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_triangles.diminfo[0].shape = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_triangles.diminfo[1].strides = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_triangles.diminfo[1].shape = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_texture.rcbuffer->pybuffer, (PyObject*)__pyx_v_texture, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 3, 0, __pyx_stack) == -1)) __PYX_ERR(2, 79, __pyx_L1_error) + } + __pyx_pybuffernd_texture.diminfo[0].strides = __pyx_pybuffernd_texture.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_texture.diminfo[0].shape = __pyx_pybuffernd_texture.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_texture.diminfo[1].strides = __pyx_pybuffernd_texture.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_texture.diminfo[1].shape = __pyx_pybuffernd_texture.rcbuffer->pybuffer.shape[1]; __pyx_pybuffernd_texture.diminfo[2].strides = __pyx_pybuffernd_texture.rcbuffer->pybuffer.strides[2]; __pyx_pybuffernd_texture.diminfo[2].shape = __pyx_pybuffernd_texture.rcbuffer->pybuffer.shape[2]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_tex_coords.rcbuffer->pybuffer, (PyObject*)__pyx_v_tex_coords, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(2, 79, __pyx_L1_error) + } + __pyx_pybuffernd_tex_coords.diminfo[0].strides = __pyx_pybuffernd_tex_coords.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_tex_coords.diminfo[0].shape = __pyx_pybuffernd_tex_coords.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_tex_coords.diminfo[1].strides = __pyx_pybuffernd_tex_coords.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_tex_coords.diminfo[1].shape = __pyx_pybuffernd_tex_coords.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_tex_triangles.rcbuffer->pybuffer, (PyObject*)__pyx_v_tex_triangles, &__Pyx_TypeInfo_int, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(2, 79, __pyx_L1_error) + } + __pyx_pybuffernd_tex_triangles.diminfo[0].strides = __pyx_pybuffernd_tex_triangles.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_tex_triangles.diminfo[0].shape = __pyx_pybuffernd_tex_triangles.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_tex_triangles.diminfo[1].strides = __pyx_pybuffernd_tex_triangles.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_tex_triangles.diminfo[1].shape = __pyx_pybuffernd_tex_triangles.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer, (PyObject*)__pyx_v_depth_buffer, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(2, 79, __pyx_L1_error) + } + __pyx_pybuffernd_depth_buffer.diminfo[0].strides = __pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_depth_buffer.diminfo[0].shape = __pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_depth_buffer.diminfo[1].strides = __pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_depth_buffer.diminfo[1].shape = __pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer.shape[1]; + + /* "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx":91 + * int mapping_type + * ): + * _render_texture_core( # <<<<<<<<<<<<<< + * np.PyArray_DATA(image), np.PyArray_DATA(vertices), np.PyArray_DATA(triangles), + * np.PyArray_DATA(texture), np.PyArray_DATA(tex_coords), np.PyArray_DATA(tex_triangles), + */ + _render_texture_core(((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_image))), ((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_vertices))), ((int *)PyArray_DATA(((PyArrayObject *)__pyx_v_triangles))), ((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_texture))), ((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_tex_coords))), ((int *)PyArray_DATA(((PyArrayObject *)__pyx_v_tex_triangles))), ((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_depth_buffer))), __pyx_v_nver, __pyx_v_tex_nver, __pyx_v_ntri, __pyx_v_h, __pyx_v_w, __pyx_v_c, __pyx_v_tex_h, __pyx_v_tex_w, __pyx_v_tex_c, __pyx_v_mapping_type); + + /* "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx":79 + * h, w, c) + * + * def render_texture_core(np.ndarray[float, ndim=3, mode = "c"] image not None, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_image.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tex_coords.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tex_triangles.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_texture.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertices.rcbuffer->pybuffer); + __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} + __Pyx_AddTraceback("insightface.thirdparty.face3d.mesh.cython.mesh_core_cython.render_texture_core", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + goto __pyx_L2; + __pyx_L0:; + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_depth_buffer.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_image.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tex_coords.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tex_triangles.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_texture.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertices.rcbuffer->pybuffer); + __pyx_L2:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx":100 + * mapping_type) + * + * def write_obj_with_colors_texture_core(string filename, string mtl_name, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_9write_obj_with_colors_texture_core(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +static PyMethodDef __pyx_mdef_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_9write_obj_with_colors_texture_core = {"write_obj_with_colors_texture_core", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_9write_obj_with_colors_texture_core, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}; +static PyObject *__pyx_pw_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_9write_obj_with_colors_texture_core(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + std::string __pyx_v_filename; + std::string __pyx_v_mtl_name; + PyArrayObject *__pyx_v_vertices = 0; + PyArrayObject *__pyx_v_triangles = 0; + PyArrayObject *__pyx_v_colors = 0; + PyArrayObject *__pyx_v_uv_coords = 0; + int __pyx_v_nver; + int __pyx_v_ntri; + int __pyx_v_ntexver; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[9] = {0,0,0,0,0,0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("write_obj_with_colors_texture_core (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_filename,&__pyx_n_s_mtl_name,&__pyx_n_s_vertices,&__pyx_n_s_triangles,&__pyx_n_s_colors,&__pyx_n_s_uv_coords,&__pyx_n_s_nver,&__pyx_n_s_ntri,&__pyx_n_s_ntexver,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 9: values[8] = __Pyx_Arg_FASTCALL(__pyx_args, 8); + CYTHON_FALLTHROUGH; + case 8: values[7] = __Pyx_Arg_FASTCALL(__pyx_args, 7); + CYTHON_FALLTHROUGH; + case 7: values[6] = __Pyx_Arg_FASTCALL(__pyx_args, 6); + CYTHON_FALLTHROUGH; + case 6: values[5] = __Pyx_Arg_FASTCALL(__pyx_args, 5); + CYTHON_FALLTHROUGH; + case 5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_filename)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 100, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_mtl_name)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 100, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("write_obj_with_colors_texture_core", 1, 9, 9, 1); __PYX_ERR(2, 100, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_vertices)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 100, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("write_obj_with_colors_texture_core", 1, 9, 9, 2); __PYX_ERR(2, 100, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_triangles)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 100, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("write_obj_with_colors_texture_core", 1, 9, 9, 3); __PYX_ERR(2, 100, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 4: + if (likely((values[4] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_colors)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[4]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 100, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("write_obj_with_colors_texture_core", 1, 9, 9, 4); __PYX_ERR(2, 100, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 5: + if (likely((values[5] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_uv_coords)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[5]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 100, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("write_obj_with_colors_texture_core", 1, 9, 9, 5); __PYX_ERR(2, 100, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 6: + if (likely((values[6] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_nver)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[6]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 100, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("write_obj_with_colors_texture_core", 1, 9, 9, 6); __PYX_ERR(2, 100, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 7: + if (likely((values[7] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_ntri)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[7]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 100, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("write_obj_with_colors_texture_core", 1, 9, 9, 7); __PYX_ERR(2, 100, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 8: + if (likely((values[8] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_ntexver)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[8]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 100, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("write_obj_with_colors_texture_core", 1, 9, 9, 8); __PYX_ERR(2, 100, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "write_obj_with_colors_texture_core") < 0)) __PYX_ERR(2, 100, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 9)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + values[5] = __Pyx_Arg_FASTCALL(__pyx_args, 5); + values[6] = __Pyx_Arg_FASTCALL(__pyx_args, 6); + values[7] = __Pyx_Arg_FASTCALL(__pyx_args, 7); + values[8] = __Pyx_Arg_FASTCALL(__pyx_args, 8); + } + __pyx_v_filename = __pyx_convert_string_from_py_6libcpp_6string_std__in_string(values[0]); if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 100, __pyx_L3_error) + __pyx_v_mtl_name = __pyx_convert_string_from_py_6libcpp_6string_std__in_string(values[1]); if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 100, __pyx_L3_error) + __pyx_v_vertices = ((PyArrayObject *)values[2]); + __pyx_v_triangles = ((PyArrayObject *)values[3]); + __pyx_v_colors = ((PyArrayObject *)values[4]); + __pyx_v_uv_coords = ((PyArrayObject *)values[5]); + __pyx_v_nver = __Pyx_PyInt_As_int(values[6]); if (unlikely((__pyx_v_nver == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 105, __pyx_L3_error) + __pyx_v_ntri = __Pyx_PyInt_As_int(values[7]); if (unlikely((__pyx_v_ntri == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 105, __pyx_L3_error) + __pyx_v_ntexver = __Pyx_PyInt_As_int(values[8]); if (unlikely((__pyx_v_ntexver == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 105, __pyx_L3_error) + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("write_obj_with_colors_texture_core", 1, 9, 9, __pyx_nargs); __PYX_ERR(2, 100, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("insightface.thirdparty.face3d.mesh.cython.mesh_core_cython.write_obj_with_colors_texture_core", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_vertices), __pyx_ptype_5numpy_ndarray, 0, "vertices", 0))) __PYX_ERR(2, 101, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_triangles), __pyx_ptype_5numpy_ndarray, 0, "triangles", 0))) __PYX_ERR(2, 102, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_colors), __pyx_ptype_5numpy_ndarray, 0, "colors", 0))) __PYX_ERR(2, 103, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_uv_coords), __pyx_ptype_5numpy_ndarray, 0, "uv_coords", 0))) __PYX_ERR(2, 104, __pyx_L1_error) + __pyx_r = __pyx_pf_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_8write_obj_with_colors_texture_core(__pyx_self, __PYX_STD_MOVE_IF_SUPPORTED(__pyx_v_filename), __PYX_STD_MOVE_IF_SUPPORTED(__pyx_v_mtl_name), __pyx_v_vertices, __pyx_v_triangles, __pyx_v_colors, __pyx_v_uv_coords, __pyx_v_nver, __pyx_v_ntri, __pyx_v_ntexver); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_8write_obj_with_colors_texture_core(CYTHON_UNUSED PyObject *__pyx_self, std::string __pyx_v_filename, std::string __pyx_v_mtl_name, PyArrayObject *__pyx_v_vertices, PyArrayObject *__pyx_v_triangles, PyArrayObject *__pyx_v_colors, PyArrayObject *__pyx_v_uv_coords, int __pyx_v_nver, int __pyx_v_ntri, int __pyx_v_ntexver) { + __Pyx_LocalBuf_ND __pyx_pybuffernd_colors; + __Pyx_Buffer __pyx_pybuffer_colors; + __Pyx_LocalBuf_ND __pyx_pybuffernd_triangles; + __Pyx_Buffer __pyx_pybuffer_triangles; + __Pyx_LocalBuf_ND __pyx_pybuffernd_uv_coords; + __Pyx_Buffer __pyx_pybuffer_uv_coords; + __Pyx_LocalBuf_ND __pyx_pybuffernd_vertices; + __Pyx_Buffer __pyx_pybuffer_vertices; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("write_obj_with_colors_texture_core", 1); + __pyx_pybuffer_vertices.pybuffer.buf = NULL; + __pyx_pybuffer_vertices.refcount = 0; + __pyx_pybuffernd_vertices.data = NULL; + __pyx_pybuffernd_vertices.rcbuffer = &__pyx_pybuffer_vertices; + __pyx_pybuffer_triangles.pybuffer.buf = NULL; + __pyx_pybuffer_triangles.refcount = 0; + __pyx_pybuffernd_triangles.data = NULL; + __pyx_pybuffernd_triangles.rcbuffer = &__pyx_pybuffer_triangles; + __pyx_pybuffer_colors.pybuffer.buf = NULL; + __pyx_pybuffer_colors.refcount = 0; + __pyx_pybuffernd_colors.data = NULL; + __pyx_pybuffernd_colors.rcbuffer = &__pyx_pybuffer_colors; + __pyx_pybuffer_uv_coords.pybuffer.buf = NULL; + __pyx_pybuffer_uv_coords.refcount = 0; + __pyx_pybuffernd_uv_coords.data = NULL; + __pyx_pybuffernd_uv_coords.rcbuffer = &__pyx_pybuffer_uv_coords; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_vertices.rcbuffer->pybuffer, (PyObject*)__pyx_v_vertices, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(2, 100, __pyx_L1_error) + } + __pyx_pybuffernd_vertices.diminfo[0].strides = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_vertices.diminfo[0].shape = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_vertices.diminfo[1].strides = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_vertices.diminfo[1].shape = __pyx_pybuffernd_vertices.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer, (PyObject*)__pyx_v_triangles, &__Pyx_TypeInfo_int, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(2, 100, __pyx_L1_error) + } + __pyx_pybuffernd_triangles.diminfo[0].strides = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_triangles.diminfo[0].shape = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_triangles.diminfo[1].strides = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_triangles.diminfo[1].shape = __pyx_pybuffernd_triangles.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_colors.rcbuffer->pybuffer, (PyObject*)__pyx_v_colors, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(2, 100, __pyx_L1_error) + } + __pyx_pybuffernd_colors.diminfo[0].strides = __pyx_pybuffernd_colors.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_colors.diminfo[0].shape = __pyx_pybuffernd_colors.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_colors.diminfo[1].strides = __pyx_pybuffernd_colors.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_colors.diminfo[1].shape = __pyx_pybuffernd_colors.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_uv_coords.rcbuffer->pybuffer, (PyObject*)__pyx_v_uv_coords, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) __PYX_ERR(2, 100, __pyx_L1_error) + } + __pyx_pybuffernd_uv_coords.diminfo[0].strides = __pyx_pybuffernd_uv_coords.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_uv_coords.diminfo[0].shape = __pyx_pybuffernd_uv_coords.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_uv_coords.diminfo[1].strides = __pyx_pybuffernd_uv_coords.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_uv_coords.diminfo[1].shape = __pyx_pybuffernd_uv_coords.rcbuffer->pybuffer.shape[1]; + + /* "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx":107 + * int nver, int ntri, int ntexver + * ): + * _write_obj_with_colors_texture(filename, mtl_name, # <<<<<<<<<<<<<< + * np.PyArray_DATA(vertices), np.PyArray_DATA(triangles), np.PyArray_DATA(colors), np.PyArray_DATA(uv_coords), + * nver, ntri, ntexver) + */ + _write_obj_with_colors_texture(__pyx_v_filename, __pyx_v_mtl_name, ((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_vertices))), ((int *)PyArray_DATA(((PyArrayObject *)__pyx_v_triangles))), ((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_colors))), ((float *)PyArray_DATA(((PyArrayObject *)__pyx_v_uv_coords))), __pyx_v_nver, __pyx_v_ntri, __pyx_v_ntexver); + + /* "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx":100 + * mapping_type) + * + * def write_obj_with_colors_texture_core(string filename, string mtl_name, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_colors.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_uv_coords.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertices.rcbuffer->pybuffer); + __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} + __Pyx_AddTraceback("insightface.thirdparty.face3d.mesh.cython.mesh_core_cython.write_obj_with_colors_texture_core", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + goto __pyx_L2; + __pyx_L0:; + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_colors.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_triangles.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_uv_coords.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_vertices.rcbuffer->pybuffer); + __pyx_L2:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyMethodDef __pyx_methods[] = { + {0, 0, 0, 0} +}; +#ifndef CYTHON_SMALL_CODE +#if defined(__clang__) + #define CYTHON_SMALL_CODE +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + #define CYTHON_SMALL_CODE __attribute__((cold)) +#else + #define CYTHON_SMALL_CODE +#endif +#endif +/* #### Code section: pystring_table ### */ + +static int __Pyx_CreateStringTabAndInitStrings(void) { + __Pyx_StringTabEntry __pyx_string_tab[] = { + {&__pyx_n_s_ImportError, __pyx_k_ImportError, sizeof(__pyx_k_ImportError), 0, 0, 1, 1}, + {&__pyx_n_s__14, __pyx_k__14, sizeof(__pyx_k__14), 0, 0, 1, 1}, + {&__pyx_n_s__3, __pyx_k__3, sizeof(__pyx_k__3), 0, 0, 1, 1}, + {&__pyx_n_s_asyncio_coroutines, __pyx_k_asyncio_coroutines, sizeof(__pyx_k_asyncio_coroutines), 0, 0, 1, 1}, + {&__pyx_n_s_barycentric_weight, __pyx_k_barycentric_weight, sizeof(__pyx_k_barycentric_weight), 0, 0, 1, 1}, + {&__pyx_n_s_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 0, 1, 1}, + {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, + {&__pyx_n_s_colors, __pyx_k_colors, sizeof(__pyx_k_colors), 0, 0, 1, 1}, + {&__pyx_n_s_depth_buffer, __pyx_k_depth_buffer, sizeof(__pyx_k_depth_buffer), 0, 0, 1, 1}, + {&__pyx_n_s_filename, __pyx_k_filename, sizeof(__pyx_k_filename), 0, 0, 1, 1}, + {&__pyx_n_s_get_normal_core, __pyx_k_get_normal_core, sizeof(__pyx_k_get_normal_core), 0, 0, 1, 1}, + {&__pyx_n_s_h, __pyx_k_h, sizeof(__pyx_k_h), 0, 0, 1, 1}, + {&__pyx_n_s_image, __pyx_k_image, sizeof(__pyx_k_image), 0, 0, 1, 1}, + {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, + {&__pyx_n_s_initializing, __pyx_k_initializing, sizeof(__pyx_k_initializing), 0, 0, 1, 1}, + {&__pyx_kp_s_insightface_thirdparty_face3d_me, __pyx_k_insightface_thirdparty_face3d_me, sizeof(__pyx_k_insightface_thirdparty_face3d_me), 0, 0, 1, 0}, + {&__pyx_n_s_insightface_thirdparty_face3d_me_2, __pyx_k_insightface_thirdparty_face3d_me_2, sizeof(__pyx_k_insightface_thirdparty_face3d_me_2), 0, 0, 1, 1}, + {&__pyx_n_s_is_coroutine, __pyx_k_is_coroutine, sizeof(__pyx_k_is_coroutine), 0, 0, 1, 1}, + {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, + {&__pyx_n_s_mapping_type, __pyx_k_mapping_type, sizeof(__pyx_k_mapping_type), 0, 0, 1, 1}, + {&__pyx_n_s_mtl_name, __pyx_k_mtl_name, sizeof(__pyx_k_mtl_name), 0, 0, 1, 1}, + {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, + {&__pyx_n_s_normal, __pyx_k_normal, sizeof(__pyx_k_normal), 0, 0, 1, 1}, + {&__pyx_n_s_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1}, + {&__pyx_n_s_ntexver, __pyx_k_ntexver, sizeof(__pyx_k_ntexver), 0, 0, 1, 1}, + {&__pyx_n_s_ntri, __pyx_k_ntri, sizeof(__pyx_k_ntri), 0, 0, 1, 1}, + {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1}, + {&__pyx_kp_s_numpy_core_multiarray_failed_to, __pyx_k_numpy_core_multiarray_failed_to, sizeof(__pyx_k_numpy_core_multiarray_failed_to), 0, 0, 1, 0}, + {&__pyx_kp_s_numpy_core_umath_failed_to_impor, __pyx_k_numpy_core_umath_failed_to_impor, sizeof(__pyx_k_numpy_core_umath_failed_to_impor), 0, 0, 1, 0}, + {&__pyx_n_s_nver, __pyx_k_nver, sizeof(__pyx_k_nver), 0, 0, 1, 1}, + {&__pyx_n_s_rasterize_triangles_core, __pyx_k_rasterize_triangles_core, sizeof(__pyx_k_rasterize_triangles_core), 0, 0, 1, 1}, + {&__pyx_n_s_render_colors_core, __pyx_k_render_colors_core, sizeof(__pyx_k_render_colors_core), 0, 0, 1, 1}, + {&__pyx_n_s_render_texture_core, __pyx_k_render_texture_core, sizeof(__pyx_k_render_texture_core), 0, 0, 1, 1}, + {&__pyx_n_s_spec, __pyx_k_spec, sizeof(__pyx_k_spec), 0, 0, 1, 1}, + {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, + {&__pyx_n_s_tex_c, __pyx_k_tex_c, sizeof(__pyx_k_tex_c), 0, 0, 1, 1}, + {&__pyx_n_s_tex_coords, __pyx_k_tex_coords, sizeof(__pyx_k_tex_coords), 0, 0, 1, 1}, + {&__pyx_n_s_tex_h, __pyx_k_tex_h, sizeof(__pyx_k_tex_h), 0, 0, 1, 1}, + {&__pyx_n_s_tex_nver, __pyx_k_tex_nver, sizeof(__pyx_k_tex_nver), 0, 0, 1, 1}, + {&__pyx_n_s_tex_triangles, __pyx_k_tex_triangles, sizeof(__pyx_k_tex_triangles), 0, 0, 1, 1}, + {&__pyx_n_s_tex_w, __pyx_k_tex_w, sizeof(__pyx_k_tex_w), 0, 0, 1, 1}, + {&__pyx_n_s_texture, __pyx_k_texture, sizeof(__pyx_k_texture), 0, 0, 1, 1}, + {&__pyx_n_s_tri_normal, __pyx_k_tri_normal, sizeof(__pyx_k_tri_normal), 0, 0, 1, 1}, + {&__pyx_n_s_triangle_buffer, __pyx_k_triangle_buffer, sizeof(__pyx_k_triangle_buffer), 0, 0, 1, 1}, + {&__pyx_n_s_triangles, __pyx_k_triangles, sizeof(__pyx_k_triangles), 0, 0, 1, 1}, + {&__pyx_n_s_uv_coords, __pyx_k_uv_coords, sizeof(__pyx_k_uv_coords), 0, 0, 1, 1}, + {&__pyx_n_s_vertices, __pyx_k_vertices, sizeof(__pyx_k_vertices), 0, 0, 1, 1}, + {&__pyx_n_s_w, __pyx_k_w, sizeof(__pyx_k_w), 0, 0, 1, 1}, + {&__pyx_n_s_write_obj_with_colors_texture_co, __pyx_k_write_obj_with_colors_texture_co, sizeof(__pyx_k_write_obj_with_colors_texture_co), 0, 0, 1, 1}, + {0, 0, 0, 0, 0, 0, 0} + }; + return __Pyx_InitStrings(__pyx_string_tab); +} +/* #### Code section: cached_builtins ### */ +static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { + __pyx_builtin_ImportError = __Pyx_GetBuiltinName(__pyx_n_s_ImportError); if (!__pyx_builtin_ImportError) __PYX_ERR(1, 984, __pyx_L1_error) + return 0; + __pyx_L1_error:; + return -1; +} +/* #### Code section: cached_constants ### */ + +static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":984 + * __pyx_import_array() + * except Exception: + * raise ImportError("numpy.core.multiarray failed to import") # <<<<<<<<<<<<<< + * + * cdef inline int import_umath() except -1: + */ + __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_s_numpy_core_multiarray_failed_to); if (unlikely(!__pyx_tuple_)) __PYX_ERR(1, 984, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple_); + __Pyx_GIVEREF(__pyx_tuple_); + + /* "../../pip-build-env-lwy92fk6/overlay/lib/python3.9/site-packages/numpy/__init__.cython-30.pxd":990 + * _import_umath() + * except Exception: + * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< + * + * cdef inline int import_ufunc() except -1: + */ + __pyx_tuple__2 = PyTuple_Pack(1, __pyx_kp_s_numpy_core_umath_failed_to_impor); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(1, 990, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__2); + __Pyx_GIVEREF(__pyx_tuple__2); + + /* "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx":40 + * int nver, int ntri, int ntexver) + * + * def get_normal_core(np.ndarray[float, ndim=2, mode = "c"] normal not None, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] tri_normal not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + __pyx_tuple__4 = PyTuple_Pack(4, __pyx_n_s_normal, __pyx_n_s_tri_normal, __pyx_n_s_triangles, __pyx_n_s_ntri); if (unlikely(!__pyx_tuple__4)) __PYX_ERR(2, 40, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__4); + __Pyx_GIVEREF(__pyx_tuple__4); + __pyx_codeobj__5 = (PyObject*)__Pyx_PyCode_New(4, 0, 0, 4, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__4, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_insightface_thirdparty_face3d_me, __pyx_n_s_get_normal_core, 40, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__5)) __PYX_ERR(2, 40, __pyx_L1_error) + + /* "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx":49 + * ntri) + * + * def rasterize_triangles_core( # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + __pyx_tuple__6 = PyTuple_Pack(9, __pyx_n_s_vertices, __pyx_n_s_triangles, __pyx_n_s_depth_buffer, __pyx_n_s_triangle_buffer, __pyx_n_s_barycentric_weight, __pyx_n_s_nver, __pyx_n_s_ntri, __pyx_n_s_h, __pyx_n_s_w); if (unlikely(!__pyx_tuple__6)) __PYX_ERR(2, 49, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__6); + __Pyx_GIVEREF(__pyx_tuple__6); + __pyx_codeobj__7 = (PyObject*)__Pyx_PyCode_New(9, 0, 0, 9, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__6, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_insightface_thirdparty_face3d_me, __pyx_n_s_rasterize_triangles_core, 49, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__7)) __PYX_ERR(2, 49, __pyx_L1_error) + + /* "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx":64 + * h, w) + * + * def render_colors_core(np.ndarray[float, ndim=3, mode = "c"] image not None, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + __pyx_tuple__8 = PyTuple_Pack(10, __pyx_n_s_image, __pyx_n_s_vertices, __pyx_n_s_triangles, __pyx_n_s_colors, __pyx_n_s_depth_buffer, __pyx_n_s_nver, __pyx_n_s_ntri, __pyx_n_s_h, __pyx_n_s_w, __pyx_n_s_c); if (unlikely(!__pyx_tuple__8)) __PYX_ERR(2, 64, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__8); + __Pyx_GIVEREF(__pyx_tuple__8); + __pyx_codeobj__9 = (PyObject*)__Pyx_PyCode_New(10, 0, 0, 10, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__8, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_insightface_thirdparty_face3d_me, __pyx_n_s_render_colors_core, 64, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__9)) __PYX_ERR(2, 64, __pyx_L1_error) + + /* "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx":79 + * h, w, c) + * + * def render_texture_core(np.ndarray[float, ndim=3, mode = "c"] image not None, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + __pyx_tuple__10 = PyTuple_Pack(17, __pyx_n_s_image, __pyx_n_s_vertices, __pyx_n_s_triangles, __pyx_n_s_texture, __pyx_n_s_tex_coords, __pyx_n_s_tex_triangles, __pyx_n_s_depth_buffer, __pyx_n_s_nver, __pyx_n_s_tex_nver, __pyx_n_s_ntri, __pyx_n_s_h, __pyx_n_s_w, __pyx_n_s_c, __pyx_n_s_tex_h, __pyx_n_s_tex_w, __pyx_n_s_tex_c, __pyx_n_s_mapping_type); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(2, 79, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__10); + __Pyx_GIVEREF(__pyx_tuple__10); + __pyx_codeobj__11 = (PyObject*)__Pyx_PyCode_New(17, 0, 0, 17, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__10, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_insightface_thirdparty_face3d_me, __pyx_n_s_render_texture_core, 79, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__11)) __PYX_ERR(2, 79, __pyx_L1_error) + + /* "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx":100 + * mapping_type) + * + * def write_obj_with_colors_texture_core(string filename, string mtl_name, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + __pyx_tuple__12 = PyTuple_Pack(9, __pyx_n_s_filename, __pyx_n_s_mtl_name, __pyx_n_s_vertices, __pyx_n_s_triangles, __pyx_n_s_colors, __pyx_n_s_uv_coords, __pyx_n_s_nver, __pyx_n_s_ntri, __pyx_n_s_ntexver); if (unlikely(!__pyx_tuple__12)) __PYX_ERR(2, 100, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__12); + __Pyx_GIVEREF(__pyx_tuple__12); + __pyx_codeobj__13 = (PyObject*)__Pyx_PyCode_New(9, 0, 0, 9, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__12, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_insightface_thirdparty_face3d_me, __pyx_n_s_write_obj_with_colors_texture_co, 100, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__13)) __PYX_ERR(2, 100, __pyx_L1_error) + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} +/* #### Code section: init_constants ### */ + +static CYTHON_SMALL_CODE int __Pyx_InitConstants(void) { + if (__Pyx_CreateStringTabAndInitStrings() < 0) __PYX_ERR(2, 1, __pyx_L1_error); + return 0; + __pyx_L1_error:; + return -1; +} +/* #### Code section: init_globals ### */ + +static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { + return 0; +} +/* #### Code section: init_module ### */ + +static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ + +static int __Pyx_modinit_global_init_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); + /*--- Global init code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); + /*--- Variable export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); + /*--- Function export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_init_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); + /*--- Type init code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_import_code(void) { + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); + /*--- Type import code ---*/ + __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(3, 9, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_ptype_7cpython_4type_type = __Pyx_ImportType_3_0_9(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "type", + #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 + sizeof(PyTypeObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_9(PyTypeObject), + #elif CYTHON_COMPILING_IN_LIMITED_API + sizeof(PyTypeObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_9(PyTypeObject), + #else + sizeof(PyHeapTypeObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_9(PyHeapTypeObject), + #endif + __Pyx_ImportType_CheckSize_Warn_3_0_9); if (!__pyx_ptype_7cpython_4type_type) __PYX_ERR(3, 9, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyImport_ImportModule("numpy"); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 202, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_ptype_5numpy_dtype = __Pyx_ImportType_3_0_9(__pyx_t_1, "numpy", "dtype", sizeof(PyArray_Descr), __PYX_GET_STRUCT_ALIGNMENT_3_0_9(PyArray_Descr),__Pyx_ImportType_CheckSize_Ignore_3_0_9); if (!__pyx_ptype_5numpy_dtype) __PYX_ERR(1, 202, __pyx_L1_error) + __pyx_ptype_5numpy_flatiter = __Pyx_ImportType_3_0_9(__pyx_t_1, "numpy", "flatiter", sizeof(PyArrayIterObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_9(PyArrayIterObject),__Pyx_ImportType_CheckSize_Ignore_3_0_9); if (!__pyx_ptype_5numpy_flatiter) __PYX_ERR(1, 225, __pyx_L1_error) + __pyx_ptype_5numpy_broadcast = __Pyx_ImportType_3_0_9(__pyx_t_1, "numpy", "broadcast", sizeof(PyArrayMultiIterObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_9(PyArrayMultiIterObject),__Pyx_ImportType_CheckSize_Ignore_3_0_9); if (!__pyx_ptype_5numpy_broadcast) __PYX_ERR(1, 229, __pyx_L1_error) + __pyx_ptype_5numpy_ndarray = __Pyx_ImportType_3_0_9(__pyx_t_1, "numpy", "ndarray", sizeof(PyArrayObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_9(PyArrayObject),__Pyx_ImportType_CheckSize_Ignore_3_0_9); if (!__pyx_ptype_5numpy_ndarray) __PYX_ERR(1, 238, __pyx_L1_error) + __pyx_ptype_5numpy_generic = __Pyx_ImportType_3_0_9(__pyx_t_1, "numpy", "generic", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_9(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_9); if (!__pyx_ptype_5numpy_generic) __PYX_ERR(1, 809, __pyx_L1_error) + __pyx_ptype_5numpy_number = __Pyx_ImportType_3_0_9(__pyx_t_1, "numpy", "number", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_9(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_9); if (!__pyx_ptype_5numpy_number) __PYX_ERR(1, 811, __pyx_L1_error) + __pyx_ptype_5numpy_integer = __Pyx_ImportType_3_0_9(__pyx_t_1, "numpy", "integer", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_9(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_9); if (!__pyx_ptype_5numpy_integer) __PYX_ERR(1, 813, __pyx_L1_error) + __pyx_ptype_5numpy_signedinteger = __Pyx_ImportType_3_0_9(__pyx_t_1, "numpy", "signedinteger", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_9(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_9); if (!__pyx_ptype_5numpy_signedinteger) __PYX_ERR(1, 815, __pyx_L1_error) + __pyx_ptype_5numpy_unsignedinteger = __Pyx_ImportType_3_0_9(__pyx_t_1, "numpy", "unsignedinteger", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_9(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_9); if (!__pyx_ptype_5numpy_unsignedinteger) __PYX_ERR(1, 817, __pyx_L1_error) + __pyx_ptype_5numpy_inexact = __Pyx_ImportType_3_0_9(__pyx_t_1, "numpy", "inexact", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_9(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_9); if (!__pyx_ptype_5numpy_inexact) __PYX_ERR(1, 819, __pyx_L1_error) + __pyx_ptype_5numpy_floating = __Pyx_ImportType_3_0_9(__pyx_t_1, "numpy", "floating", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_9(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_9); if (!__pyx_ptype_5numpy_floating) __PYX_ERR(1, 821, __pyx_L1_error) + __pyx_ptype_5numpy_complexfloating = __Pyx_ImportType_3_0_9(__pyx_t_1, "numpy", "complexfloating", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_9(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_9); if (!__pyx_ptype_5numpy_complexfloating) __PYX_ERR(1, 823, __pyx_L1_error) + __pyx_ptype_5numpy_flexible = __Pyx_ImportType_3_0_9(__pyx_t_1, "numpy", "flexible", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_9(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_9); if (!__pyx_ptype_5numpy_flexible) __PYX_ERR(1, 825, __pyx_L1_error) + __pyx_ptype_5numpy_character = __Pyx_ImportType_3_0_9(__pyx_t_1, "numpy", "character", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_9(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_9); if (!__pyx_ptype_5numpy_character) __PYX_ERR(1, 827, __pyx_L1_error) + __pyx_ptype_5numpy_ufunc = __Pyx_ImportType_3_0_9(__pyx_t_1, "numpy", "ufunc", sizeof(PyUFuncObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_9(PyUFuncObject),__Pyx_ImportType_CheckSize_Ignore_3_0_9); if (!__pyx_ptype_5numpy_ufunc) __PYX_ERR(1, 866, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_RefNannyFinishContext(); + return -1; +} + +static int __Pyx_modinit_variable_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); + /*--- Variable import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); + /*--- Function import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + + +#if PY_MAJOR_VERSION >= 3 +#if CYTHON_PEP489_MULTI_PHASE_INIT +static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ +static int __pyx_pymod_exec_mesh_core_cython(PyObject* module); /*proto*/ +static PyModuleDef_Slot __pyx_moduledef_slots[] = { + {Py_mod_create, (void*)__pyx_pymod_create}, + {Py_mod_exec, (void*)__pyx_pymod_exec_mesh_core_cython}, + {0, NULL} +}; +#endif + +#ifdef __cplusplus +namespace { + struct PyModuleDef __pyx_moduledef = + #else + static struct PyModuleDef __pyx_moduledef = + #endif + { + PyModuleDef_HEAD_INIT, + "mesh_core_cython", + 0, /* m_doc */ + #if CYTHON_PEP489_MULTI_PHASE_INIT + 0, /* m_size */ + #elif CYTHON_USE_MODULE_STATE + sizeof(__pyx_mstate), /* m_size */ + #else + -1, /* m_size */ + #endif + __pyx_methods /* m_methods */, + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_moduledef_slots, /* m_slots */ + #else + NULL, /* m_reload */ + #endif + #if CYTHON_USE_MODULE_STATE + __pyx_m_traverse, /* m_traverse */ + __pyx_m_clear, /* m_clear */ + NULL /* m_free */ + #else + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ + #endif + }; + #ifdef __cplusplus +} /* anonymous namespace */ +#endif +#endif + +#ifndef CYTHON_NO_PYINIT_EXPORT +#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC +#elif PY_MAJOR_VERSION < 3 +#ifdef __cplusplus +#define __Pyx_PyMODINIT_FUNC extern "C" void +#else +#define __Pyx_PyMODINIT_FUNC void +#endif +#else +#ifdef __cplusplus +#define __Pyx_PyMODINIT_FUNC extern "C" PyObject * +#else +#define __Pyx_PyMODINIT_FUNC PyObject * +#endif +#endif + + +#if PY_MAJOR_VERSION < 3 +__Pyx_PyMODINIT_FUNC initmesh_core_cython(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC initmesh_core_cython(void) +#else +__Pyx_PyMODINIT_FUNC PyInit_mesh_core_cython(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC PyInit_mesh_core_cython(void) +#if CYTHON_PEP489_MULTI_PHASE_INIT +{ + return PyModuleDef_Init(&__pyx_moduledef); +} +static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { + #if PY_VERSION_HEX >= 0x030700A1 + static PY_INT64_T main_interpreter_id = -1; + PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); + if (main_interpreter_id == -1) { + main_interpreter_id = current_id; + return (unlikely(current_id == -1)) ? -1 : 0; + } else if (unlikely(main_interpreter_id != current_id)) + #else + static PyInterpreterState *main_interpreter = NULL; + PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; + if (!main_interpreter) { + main_interpreter = current_interpreter; + } else if (unlikely(main_interpreter != current_interpreter)) + #endif + { + PyErr_SetString( + PyExc_ImportError, + "Interpreter change detected - this module can only be loaded into one interpreter per process."); + return -1; + } + return 0; +} +#if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *module, const char* from_name, const char* to_name, int allow_none) +#else +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) +#endif +{ + PyObject *value = PyObject_GetAttrString(spec, from_name); + int result = 0; + if (likely(value)) { + if (allow_none || value != Py_None) { +#if CYTHON_COMPILING_IN_LIMITED_API + result = PyModule_AddObject(module, to_name, value); +#else + result = PyDict_SetItemString(moddict, to_name, value); +#endif + } + Py_DECREF(value); + } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } else { + result = -1; + } + return result; +} +static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def) { + PyObject *module = NULL, *moddict, *modname; + CYTHON_UNUSED_VAR(def); + if (__Pyx_check_single_interpreter()) + return NULL; + if (__pyx_m) + return __Pyx_NewRef(__pyx_m); + modname = PyObject_GetAttrString(spec, "name"); + if (unlikely(!modname)) goto bad; + module = PyModule_NewObject(modname); + Py_DECREF(modname); + if (unlikely(!module)) goto bad; +#if CYTHON_COMPILING_IN_LIMITED_API + moddict = module; +#else + moddict = PyModule_GetDict(module); + if (unlikely(!moddict)) goto bad; +#endif + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; + return module; +bad: + Py_XDECREF(module); + return NULL; +} + + +static CYTHON_SMALL_CODE int __pyx_pymod_exec_mesh_core_cython(PyObject *__pyx_pyinit_module) +#endif +#endif +{ + int stringtab_initialized = 0; + #if CYTHON_USE_MODULE_STATE + int pystate_addmodule_run = 0; + #endif + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + int __pyx_t_3; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + #if CYTHON_PEP489_MULTI_PHASE_INIT + if (__pyx_m) { + if (__pyx_m == __pyx_pyinit_module) return 0; + PyErr_SetString(PyExc_RuntimeError, "Module 'mesh_core_cython' has already been imported. Re-initialisation is not supported."); + return -1; + } + #elif PY_MAJOR_VERSION >= 3 + if (__pyx_m) return __Pyx_NewRef(__pyx_m); + #endif + /*--- Module creation code ---*/ + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_m = __pyx_pyinit_module; + Py_INCREF(__pyx_m); + #else + #if PY_MAJOR_VERSION < 3 + __pyx_m = Py_InitModule4("mesh_core_cython", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); + if (unlikely(!__pyx_m)) __PYX_ERR(2, 1, __pyx_L1_error) + #elif CYTHON_USE_MODULE_STATE + __pyx_t_1 = PyModule_Create(&__pyx_moduledef); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 1, __pyx_L1_error) + { + int add_module_result = PyState_AddModule(__pyx_t_1, &__pyx_moduledef); + __pyx_t_1 = 0; /* transfer ownership from __pyx_t_1 to "mesh_core_cython" pseudovariable */ + if (unlikely((add_module_result < 0))) __PYX_ERR(2, 1, __pyx_L1_error) + pystate_addmodule_run = 1; + } + #else + __pyx_m = PyModule_Create(&__pyx_moduledef); + if (unlikely(!__pyx_m)) __PYX_ERR(2, 1, __pyx_L1_error) + #endif + #endif + CYTHON_UNUSED_VAR(__pyx_t_1); + __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(2, 1, __pyx_L1_error) + Py_INCREF(__pyx_d); + __pyx_b = __Pyx_PyImport_AddModuleRef(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(2, 1, __pyx_L1_error) + __pyx_cython_runtime = __Pyx_PyImport_AddModuleRef((const char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(2, 1, __pyx_L1_error) + if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(2, 1, __pyx_L1_error) + #if CYTHON_REFNANNY +__Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); +if (!__Pyx_RefNanny) { + PyErr_Clear(); + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); + if (!__Pyx_RefNanny) + Py_FatalError("failed to import 'refnanny' module"); +} +#endif + __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit_mesh_core_cython(void)", 0); + if (__Pyx_check_binary_version(__PYX_LIMITED_VERSION_HEX, __Pyx_get_runtime_version(), CYTHON_COMPILING_IN_LIMITED_API) < 0) __PYX_ERR(2, 1, __pyx_L1_error) + #ifdef __Pxy_PyFrame_Initialize_Offsets + __Pxy_PyFrame_Initialize_Offsets(); + #endif + __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(2, 1, __pyx_L1_error) + __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(2, 1, __pyx_L1_error) + __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(2, 1, __pyx_L1_error) + #ifdef __Pyx_CyFunction_USED + if (__pyx_CyFunction_init(__pyx_m) < 0) __PYX_ERR(2, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_FusedFunction_USED + if (__pyx_FusedFunction_init(__pyx_m) < 0) __PYX_ERR(2, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Coroutine_USED + if (__pyx_Coroutine_init(__pyx_m) < 0) __PYX_ERR(2, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Generator_USED + if (__pyx_Generator_init(__pyx_m) < 0) __PYX_ERR(2, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_AsyncGen_USED + if (__pyx_AsyncGen_init(__pyx_m) < 0) __PYX_ERR(2, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_StopAsyncIteration_USED + if (__pyx_StopAsyncIteration_init(__pyx_m) < 0) __PYX_ERR(2, 1, __pyx_L1_error) + #endif + /*--- Library function declarations ---*/ + /*--- Threads initialization code ---*/ + #if defined(WITH_THREAD) && PY_VERSION_HEX < 0x030700F0 && defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS + PyEval_InitThreads(); + #endif + /*--- Initialize various global constants etc. ---*/ + if (__Pyx_InitConstants() < 0) __PYX_ERR(2, 1, __pyx_L1_error) + stringtab_initialized = 1; + if (__Pyx_InitGlobals() < 0) __PYX_ERR(2, 1, __pyx_L1_error) + #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) + if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(2, 1, __pyx_L1_error) + #endif + if (__pyx_module_is_main_insightface__thirdparty__face3d__mesh__cython__mesh_core_cython) { + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name, __pyx_n_s_main) < 0) __PYX_ERR(2, 1, __pyx_L1_error) + } + #if PY_MAJOR_VERSION >= 3 + { + PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(2, 1, __pyx_L1_error) + if (!PyDict_GetItemString(modules, "insightface.thirdparty.face3d.mesh.cython.mesh_core_cython")) { + if (unlikely((PyDict_SetItemString(modules, "insightface.thirdparty.face3d.mesh.cython.mesh_core_cython", __pyx_m) < 0))) __PYX_ERR(2, 1, __pyx_L1_error) + } + } + #endif + /*--- Builtin init code ---*/ + if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(2, 1, __pyx_L1_error) + /*--- Constants init code ---*/ + if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(2, 1, __pyx_L1_error) + /*--- Global type/function init code ---*/ + (void)__Pyx_modinit_global_init_code(); + (void)__Pyx_modinit_variable_export_code(); + (void)__Pyx_modinit_function_export_code(); + (void)__Pyx_modinit_type_init_code(); + if (unlikely((__Pyx_modinit_type_import_code() < 0))) __PYX_ERR(2, 1, __pyx_L1_error) + (void)__Pyx_modinit_variable_import_code(); + (void)__Pyx_modinit_function_import_code(); + /*--- Execution code ---*/ + #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) + if (__Pyx_patch_abc() < 0) __PYX_ERR(2, 1, __pyx_L1_error) + #endif + + /* "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx":1 + * import numpy as np # <<<<<<<<<<<<<< + * cimport numpy as np + * from libcpp.string cimport string + */ + __pyx_t_2 = __Pyx_ImportDottedModule(__pyx_n_s_numpy, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_2) < 0) __PYX_ERR(2, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx":6 + * + * # use the Numpy-C-API from Cython + * np.import_array() # <<<<<<<<<<<<<< + * + * # cdefine the signature of our c function + */ + __pyx_t_3 = __pyx_f_5numpy_import_array(); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(2, 6, __pyx_L1_error) + + /* "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx":40 + * int nver, int ntri, int ntexver) + * + * def get_normal_core(np.ndarray[float, ndim=2, mode = "c"] normal not None, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] tri_normal not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_1get_normal_core, 0, __pyx_n_s_get_normal_core, NULL, __pyx_n_s_insightface_thirdparty_face3d_me_2, __pyx_d, ((PyObject *)__pyx_codeobj__5)); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 40, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_get_normal_core, __pyx_t_2) < 0) __PYX_ERR(2, 40, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx":49 + * ntri) + * + * def rasterize_triangles_core( # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_3rasterize_triangles_core, 0, __pyx_n_s_rasterize_triangles_core, NULL, __pyx_n_s_insightface_thirdparty_face3d_me_2, __pyx_d, ((PyObject *)__pyx_codeobj__7)); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 49, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_rasterize_triangles_core, __pyx_t_2) < 0) __PYX_ERR(2, 49, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx":64 + * h, w) + * + * def render_colors_core(np.ndarray[float, ndim=3, mode = "c"] image not None, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_5render_colors_core, 0, __pyx_n_s_render_colors_core, NULL, __pyx_n_s_insightface_thirdparty_face3d_me_2, __pyx_d, ((PyObject *)__pyx_codeobj__9)); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 64, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_render_colors_core, __pyx_t_2) < 0) __PYX_ERR(2, 64, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx":79 + * h, w, c) + * + * def render_texture_core(np.ndarray[float, ndim=3, mode = "c"] image not None, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_7render_texture_core, 0, __pyx_n_s_render_texture_core, NULL, __pyx_n_s_insightface_thirdparty_face3d_me_2, __pyx_d, ((PyObject *)__pyx_codeobj__11)); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 79, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_render_texture_core, __pyx_t_2) < 0) __PYX_ERR(2, 79, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx":100 + * mapping_type) + * + * def write_obj_with_colors_texture_core(string filename, string mtl_name, # <<<<<<<<<<<<<< + * np.ndarray[float, ndim=2, mode = "c"] vertices not None, + * np.ndarray[int, ndim=2, mode="c"] triangles not None, + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_11insightface_10thirdparty_6face3d_4mesh_6cython_16mesh_core_cython_9write_obj_with_colors_texture_core, 0, __pyx_n_s_write_obj_with_colors_texture_co, NULL, __pyx_n_s_insightface_thirdparty_face3d_me_2, __pyx_d, ((PyObject *)__pyx_codeobj__13)); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 100, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_write_obj_with_colors_texture_co, __pyx_t_2) < 0) __PYX_ERR(2, 100, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.pyx":1 + * import numpy as np # <<<<<<<<<<<<<< + * cimport numpy as np + * from libcpp.string cimport string + */ + __pyx_t_2 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_2) < 0) __PYX_ERR(2, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /*--- Wrapped vars code ---*/ + + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + if (__pyx_m) { + if (__pyx_d && stringtab_initialized) { + __Pyx_AddTraceback("init insightface.thirdparty.face3d.mesh.cython.mesh_core_cython", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + #if !CYTHON_USE_MODULE_STATE + Py_CLEAR(__pyx_m); + #else + Py_DECREF(__pyx_m); + if (pystate_addmodule_run) { + PyObject *tp, *value, *tb; + PyErr_Fetch(&tp, &value, &tb); + PyState_RemoveModule(&__pyx_moduledef); + PyErr_Restore(tp, value, tb); + } + #endif + } else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ImportError, "init insightface.thirdparty.face3d.mesh.cython.mesh_core_cython"); + } + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + #if CYTHON_PEP489_MULTI_PHASE_INIT + return (__pyx_m != NULL) ? 0 : -1; + #elif PY_MAJOR_VERSION >= 3 + return __pyx_m; + #else + return; + #endif +} +/* #### Code section: cleanup_globals ### */ +/* #### Code section: cleanup_module ### */ +/* #### Code section: main_method ### */ +/* #### Code section: utility_code_pragmas ### */ +#ifdef _MSC_VER +#pragma warning( push ) +/* Warning 4127: conditional expression is constant + * Cython uses constant conditional expressions to allow in inline functions to be optimized at + * compile-time, so this warning is not useful + */ +#pragma warning( disable : 4127 ) +#endif + + + +/* #### Code section: utility_code_def ### */ + +/* --- Runtime support code --- */ +/* Refnanny */ +#if CYTHON_REFNANNY +static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { + PyObject *m = NULL, *p = NULL; + void *r = NULL; + m = PyImport_ImportModule(modname); + if (!m) goto end; + p = PyObject_GetAttrString(m, "RefNannyAPI"); + if (!p) goto end; + r = PyLong_AsVoidPtr(p); +end: + Py_XDECREF(p); + Py_XDECREF(m); + return (__Pyx_RefNannyAPIStruct *)r; +} +#endif + +/* PyErrExceptionMatches */ +#if CYTHON_FAST_THREAD_STATE +static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(tuple); +#if PY_MAJOR_VERSION >= 3 + for (i=0; i= 0x030C00A6 + PyObject *current_exception = tstate->current_exception; + if (unlikely(!current_exception)) return 0; + exc_type = (PyObject*) Py_TYPE(current_exception); + if (exc_type == err) return 1; +#else + exc_type = tstate->curexc_type; + if (exc_type == err) return 1; + if (unlikely(!exc_type)) return 0; +#endif + #if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(exc_type); + #endif + if (unlikely(PyTuple_Check(err))) { + result = __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err); + } else { + result = __Pyx_PyErr_GivenExceptionMatches(exc_type, err); + } + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(exc_type); + #endif + return result; +} +#endif + +/* PyErrFetchRestore */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { +#if PY_VERSION_HEX >= 0x030C00A6 + PyObject *tmp_value; + assert(type == NULL || (value != NULL && type == (PyObject*) Py_TYPE(value))); + if (value) { + #if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(((PyBaseExceptionObject*) value)->traceback != tb)) + #endif + PyException_SetTraceback(value, tb); + } + tmp_value = tstate->current_exception; + tstate->current_exception = value; + Py_XDECREF(tmp_value); + Py_XDECREF(type); + Py_XDECREF(tb); +#else + PyObject *tmp_type, *tmp_value, *tmp_tb; + tmp_type = tstate->curexc_type; + tmp_value = tstate->curexc_value; + tmp_tb = tstate->curexc_traceback; + tstate->curexc_type = type; + tstate->curexc_value = value; + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +#endif +} +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { +#if PY_VERSION_HEX >= 0x030C00A6 + PyObject* exc_value; + exc_value = tstate->current_exception; + tstate->current_exception = 0; + *value = exc_value; + *type = NULL; + *tb = NULL; + if (exc_value) { + *type = (PyObject*) Py_TYPE(exc_value); + Py_INCREF(*type); + #if CYTHON_COMPILING_IN_CPYTHON + *tb = ((PyBaseExceptionObject*) exc_value)->traceback; + Py_XINCREF(*tb); + #else + *tb = PyException_GetTraceback(exc_value); + #endif + } +#else + *type = tstate->curexc_type; + *value = tstate->curexc_value; + *tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +#endif +} +#endif + +/* PyObjectGetAttrStr */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro)) + return tp->tp_getattro(obj, attr_name); +#if PY_MAJOR_VERSION < 3 + if (likely(tp->tp_getattr)) + return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); +#endif + return PyObject_GetAttr(obj, attr_name); +} +#endif + +/* PyObjectGetAttrStrNoError */ +#if __PYX_LIMITED_VERSION_HEX < 0x030d00A1 +static void __Pyx_PyObject_GetAttrStr_ClearAttributeError(void) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + if (likely(__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) + __Pyx_PyErr_Clear(); +} +#endif +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name) { + PyObject *result; +#if __PYX_LIMITED_VERSION_HEX >= 0x030d00A1 + (void) PyObject_GetOptionalAttr(obj, attr_name, &result); + return result; +#else +#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_TYPE_SLOTS && PY_VERSION_HEX >= 0x030700B1 + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro == PyObject_GenericGetAttr)) { + return _PyObject_GenericGetAttrWithDict(obj, attr_name, NULL, 1); + } +#endif + result = __Pyx_PyObject_GetAttrStr(obj, attr_name); + if (unlikely(!result)) { + __Pyx_PyObject_GetAttrStr_ClearAttributeError(); + } + return result; +#endif +} + +/* GetBuiltinName */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name) { + PyObject* result = __Pyx_PyObject_GetAttrStrNoError(__pyx_b, name); + if (unlikely(!result) && !PyErr_Occurred()) { + PyErr_Format(PyExc_NameError, +#if PY_MAJOR_VERSION >= 3 + "name '%U' is not defined", name); +#else + "name '%.200s' is not defined", PyString_AS_STRING(name)); +#endif + } + return result; +} + +/* GetTopmostException */ +#if CYTHON_USE_EXC_INFO_STACK && CYTHON_FAST_THREAD_STATE +static _PyErr_StackItem * +__Pyx_PyErr_GetTopmostException(PyThreadState *tstate) +{ + _PyErr_StackItem *exc_info = tstate->exc_info; + while ((exc_info->exc_value == NULL || exc_info->exc_value == Py_None) && + exc_info->previous_item != NULL) + { + exc_info = exc_info->previous_item; + } + return exc_info; +} +#endif + +/* SaveResetException */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4 + _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); + PyObject *exc_value = exc_info->exc_value; + if (exc_value == NULL || exc_value == Py_None) { + *value = NULL; + *type = NULL; + *tb = NULL; + } else { + *value = exc_value; + Py_INCREF(*value); + *type = (PyObject*) Py_TYPE(exc_value); + Py_INCREF(*type); + *tb = PyException_GetTraceback(exc_value); + } + #elif CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); + *type = exc_info->exc_type; + *value = exc_info->exc_value; + *tb = exc_info->exc_traceback; + Py_XINCREF(*type); + Py_XINCREF(*value); + Py_XINCREF(*tb); + #else + *type = tstate->exc_type; + *value = tstate->exc_value; + *tb = tstate->exc_traceback; + Py_XINCREF(*type); + Py_XINCREF(*value); + Py_XINCREF(*tb); + #endif +} +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { + #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4 + _PyErr_StackItem *exc_info = tstate->exc_info; + PyObject *tmp_value = exc_info->exc_value; + exc_info->exc_value = value; + Py_XDECREF(tmp_value); + Py_XDECREF(type); + Py_XDECREF(tb); + #else + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = type; + exc_info->exc_value = value; + exc_info->exc_traceback = tb; + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = type; + tstate->exc_value = value; + tstate->exc_traceback = tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); + #endif +} +#endif + +/* GetException */ +#if CYTHON_FAST_THREAD_STATE +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) +#endif +{ + PyObject *local_type = NULL, *local_value, *local_tb = NULL; +#if CYTHON_FAST_THREAD_STATE + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if PY_VERSION_HEX >= 0x030C00A6 + local_value = tstate->current_exception; + tstate->current_exception = 0; + if (likely(local_value)) { + local_type = (PyObject*) Py_TYPE(local_value); + Py_INCREF(local_type); + local_tb = PyException_GetTraceback(local_value); + } + #else + local_type = tstate->curexc_type; + local_value = tstate->curexc_value; + local_tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; + #endif +#else + PyErr_Fetch(&local_type, &local_value, &local_tb); +#endif + PyErr_NormalizeException(&local_type, &local_value, &local_tb); +#if CYTHON_FAST_THREAD_STATE && PY_VERSION_HEX >= 0x030C00A6 + if (unlikely(tstate->current_exception)) +#elif CYTHON_FAST_THREAD_STATE + if (unlikely(tstate->curexc_type)) +#else + if (unlikely(PyErr_Occurred())) +#endif + goto bad; + #if PY_MAJOR_VERSION >= 3 + if (local_tb) { + if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) + goto bad; + } + #endif + Py_XINCREF(local_tb); + Py_XINCREF(local_type); + Py_XINCREF(local_value); + *type = local_type; + *value = local_value; + *tb = local_tb; +#if CYTHON_FAST_THREAD_STATE + #if CYTHON_USE_EXC_INFO_STACK + { + _PyErr_StackItem *exc_info = tstate->exc_info; + #if PY_VERSION_HEX >= 0x030B00a4 + tmp_value = exc_info->exc_value; + exc_info->exc_value = local_value; + tmp_type = NULL; + tmp_tb = NULL; + Py_XDECREF(local_type); + Py_XDECREF(local_tb); + #else + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = local_type; + exc_info->exc_value = local_value; + exc_info->exc_traceback = local_tb; + #endif + } + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = local_type; + tstate->exc_value = local_value; + tstate->exc_traceback = local_tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +#else + PyErr_SetExcInfo(local_type, local_value, local_tb); +#endif + return 0; +bad: + *type = 0; + *value = 0; + *tb = 0; + Py_XDECREF(local_type); + Py_XDECREF(local_value); + Py_XDECREF(local_tb); + return -1; +} + +/* PyObjectCall */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *result; + ternaryfunc call = Py_TYPE(func)->tp_call; + if (unlikely(!call)) + return PyObject_Call(func, arg, kw); + #if PY_MAJOR_VERSION < 3 + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + #else + if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) + return NULL; + #endif + result = (*call)(func, arg, kw); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* RaiseException */ +#if PY_MAJOR_VERSION < 3 +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { + __Pyx_PyThreadState_declare + CYTHON_UNUSED_VAR(cause); + Py_XINCREF(type); + if (!value || value == Py_None) + value = NULL; + else + Py_INCREF(value); + if (!tb || tb == Py_None) + tb = NULL; + else { + Py_INCREF(tb); + if (!PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto raise_error; + } + } + if (PyType_Check(type)) { +#if CYTHON_COMPILING_IN_PYPY + if (!value) { + Py_INCREF(Py_None); + value = Py_None; + } +#endif + PyErr_NormalizeException(&type, &value, &tb); + } else { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto raise_error; + } + value = type; + type = (PyObject*) Py_TYPE(type); + Py_INCREF(type); + if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto raise_error; + } + } + __Pyx_PyThreadState_assign + __Pyx_ErrRestore(type, value, tb); + return; +raise_error: + Py_XDECREF(value); + Py_XDECREF(type); + Py_XDECREF(tb); + return; +} +#else +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { + PyObject* owned_instance = NULL; + if (tb == Py_None) { + tb = 0; + } else if (tb && !PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto bad; + } + if (value == Py_None) + value = 0; + if (PyExceptionInstance_Check(type)) { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto bad; + } + value = type; + type = (PyObject*) Py_TYPE(value); + } else if (PyExceptionClass_Check(type)) { + PyObject *instance_class = NULL; + if (value && PyExceptionInstance_Check(value)) { + instance_class = (PyObject*) Py_TYPE(value); + if (instance_class != type) { + int is_subclass = PyObject_IsSubclass(instance_class, type); + if (!is_subclass) { + instance_class = NULL; + } else if (unlikely(is_subclass == -1)) { + goto bad; + } else { + type = instance_class; + } + } + } + if (!instance_class) { + PyObject *args; + if (!value) + args = PyTuple_New(0); + else if (PyTuple_Check(value)) { + Py_INCREF(value); + args = value; + } else + args = PyTuple_Pack(1, value); + if (!args) + goto bad; + owned_instance = PyObject_Call(type, args, NULL); + Py_DECREF(args); + if (!owned_instance) + goto bad; + value = owned_instance; + if (!PyExceptionInstance_Check(value)) { + PyErr_Format(PyExc_TypeError, + "calling %R should have returned an instance of " + "BaseException, not %R", + type, Py_TYPE(value)); + goto bad; + } + } + } else { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto bad; + } + if (cause) { + PyObject *fixed_cause; + if (cause == Py_None) { + fixed_cause = NULL; + } else if (PyExceptionClass_Check(cause)) { + fixed_cause = PyObject_CallObject(cause, NULL); + if (fixed_cause == NULL) + goto bad; + } else if (PyExceptionInstance_Check(cause)) { + fixed_cause = cause; + Py_INCREF(fixed_cause); + } else { + PyErr_SetString(PyExc_TypeError, + "exception causes must derive from " + "BaseException"); + goto bad; + } + PyException_SetCause(value, fixed_cause); + } + PyErr_SetObject(type, value); + if (tb) { + #if PY_VERSION_HEX >= 0x030C00A6 + PyException_SetTraceback(value, tb); + #elif CYTHON_FAST_THREAD_STATE + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject* tmp_tb = tstate->curexc_traceback; + if (tb != tmp_tb) { + Py_INCREF(tb); + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_tb); + } +#else + PyObject *tmp_type, *tmp_value, *tmp_tb; + PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); + Py_INCREF(tb); + PyErr_Restore(tmp_type, tmp_value, tb); + Py_XDECREF(tmp_tb); +#endif + } +bad: + Py_XDECREF(owned_instance); + return; +} +#endif + +/* TupleAndListFromArray */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE void __Pyx_copy_object_array(PyObject *const *CYTHON_RESTRICT src, PyObject** CYTHON_RESTRICT dest, Py_ssize_t length) { + PyObject *v; + Py_ssize_t i; + for (i = 0; i < length; i++) { + v = dest[i] = src[i]; + Py_INCREF(v); + } +} +static CYTHON_INLINE PyObject * +__Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyObject *res; + if (n <= 0) { + Py_INCREF(__pyx_empty_tuple); + return __pyx_empty_tuple; + } + res = PyTuple_New(n); + if (unlikely(res == NULL)) return NULL; + __Pyx_copy_object_array(src, ((PyTupleObject*)res)->ob_item, n); + return res; +} +static CYTHON_INLINE PyObject * +__Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyObject *res; + if (n <= 0) { + return PyList_New(0); + } + res = PyList_New(n); + if (unlikely(res == NULL)) return NULL; + __Pyx_copy_object_array(src, ((PyListObject*)res)->ob_item, n); + return res; +} +#endif + +/* BytesEquals */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API + return PyObject_RichCompareBool(s1, s2, equals); +#else + if (s1 == s2) { + return (equals == Py_EQ); + } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) { + const char *ps1, *ps2; + Py_ssize_t length = PyBytes_GET_SIZE(s1); + if (length != PyBytes_GET_SIZE(s2)) + return (equals == Py_NE); + ps1 = PyBytes_AS_STRING(s1); + ps2 = PyBytes_AS_STRING(s2); + if (ps1[0] != ps2[0]) { + return (equals == Py_NE); + } else if (length == 1) { + return (equals == Py_EQ); + } else { + int result; +#if CYTHON_USE_UNICODE_INTERNALS && (PY_VERSION_HEX < 0x030B0000) + Py_hash_t hash1, hash2; + hash1 = ((PyBytesObject*)s1)->ob_shash; + hash2 = ((PyBytesObject*)s2)->ob_shash; + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + return (equals == Py_NE); + } +#endif + result = memcmp(ps1, ps2, (size_t)length); + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) { + return (equals == Py_NE); + } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) { + return (equals == Py_NE); + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +#endif +} + +/* UnicodeEquals */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API + return PyObject_RichCompareBool(s1, s2, equals); +#else +#if PY_MAJOR_VERSION < 3 + PyObject* owned_ref = NULL; +#endif + int s1_is_unicode, s2_is_unicode; + if (s1 == s2) { + goto return_eq; + } + s1_is_unicode = PyUnicode_CheckExact(s1); + s2_is_unicode = PyUnicode_CheckExact(s2); +#if PY_MAJOR_VERSION < 3 + if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) { + owned_ref = PyUnicode_FromObject(s2); + if (unlikely(!owned_ref)) + return -1; + s2 = owned_ref; + s2_is_unicode = 1; + } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) { + owned_ref = PyUnicode_FromObject(s1); + if (unlikely(!owned_ref)) + return -1; + s1 = owned_ref; + s1_is_unicode = 1; + } else if (((!s2_is_unicode) & (!s1_is_unicode))) { + return __Pyx_PyBytes_Equals(s1, s2, equals); + } +#endif + if (s1_is_unicode & s2_is_unicode) { + Py_ssize_t length; + int kind; + void *data1, *data2; + if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0)) + return -1; + length = __Pyx_PyUnicode_GET_LENGTH(s1); + if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) { + goto return_ne; + } +#if CYTHON_USE_UNICODE_INTERNALS + { + Py_hash_t hash1, hash2; + #if CYTHON_PEP393_ENABLED + hash1 = ((PyASCIIObject*)s1)->hash; + hash2 = ((PyASCIIObject*)s2)->hash; + #else + hash1 = ((PyUnicodeObject*)s1)->hash; + hash2 = ((PyUnicodeObject*)s2)->hash; + #endif + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + goto return_ne; + } + } +#endif + kind = __Pyx_PyUnicode_KIND(s1); + if (kind != __Pyx_PyUnicode_KIND(s2)) { + goto return_ne; + } + data1 = __Pyx_PyUnicode_DATA(s1); + data2 = __Pyx_PyUnicode_DATA(s2); + if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) { + goto return_ne; + } else if (length == 1) { + goto return_eq; + } else { + int result = memcmp(data1, data2, (size_t)(length * kind)); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & s2_is_unicode) { + goto return_ne; + } else if ((s2 == Py_None) & s1_is_unicode) { + goto return_ne; + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +return_eq: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_EQ); +return_ne: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_NE); +#endif +} + +/* fastcall */ +#if CYTHON_METH_FASTCALL +static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s) +{ + Py_ssize_t i, n = PyTuple_GET_SIZE(kwnames); + for (i = 0; i < n; i++) + { + if (s == PyTuple_GET_ITEM(kwnames, i)) return kwvalues[i]; + } + for (i = 0; i < n; i++) + { + int eq = __Pyx_PyUnicode_Equals(s, PyTuple_GET_ITEM(kwnames, i), Py_EQ); + if (unlikely(eq != 0)) { + if (unlikely(eq < 0)) return NULL; + return kwvalues[i]; + } + } + return NULL; +} +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 +CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues) { + Py_ssize_t i, nkwargs = PyTuple_GET_SIZE(kwnames); + PyObject *dict; + dict = PyDict_New(); + if (unlikely(!dict)) + return NULL; + for (i=0; i= 3 + "%s() got multiple values for keyword argument '%U'", func_name, kw_name); + #else + "%s() got multiple values for keyword argument '%s'", func_name, + PyString_AsString(kw_name)); + #endif +} + +/* ParseKeywords */ +static int __Pyx_ParseOptionalKeywords( + PyObject *kwds, + PyObject *const *kwvalues, + PyObject **argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + const char* function_name) +{ + PyObject *key = 0, *value = 0; + Py_ssize_t pos = 0; + PyObject*** name; + PyObject*** first_kw_arg = argnames + num_pos_args; + int kwds_is_tuple = CYTHON_METH_FASTCALL && likely(PyTuple_Check(kwds)); + while (1) { + Py_XDECREF(key); key = NULL; + Py_XDECREF(value); value = NULL; + if (kwds_is_tuple) { + Py_ssize_t size; +#if CYTHON_ASSUME_SAFE_MACROS + size = PyTuple_GET_SIZE(kwds); +#else + size = PyTuple_Size(kwds); + if (size < 0) goto bad; +#endif + if (pos >= size) break; +#if CYTHON_AVOID_BORROWED_REFS + key = __Pyx_PySequence_ITEM(kwds, pos); + if (!key) goto bad; +#elif CYTHON_ASSUME_SAFE_MACROS + key = PyTuple_GET_ITEM(kwds, pos); +#else + key = PyTuple_GetItem(kwds, pos); + if (!key) goto bad; +#endif + value = kwvalues[pos]; + pos++; + } + else + { + if (!PyDict_Next(kwds, &pos, &key, &value)) break; +#if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(key); +#endif + } + name = first_kw_arg; + while (*name && (**name != key)) name++; + if (*name) { + values[name-argnames] = value; +#if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(value); + Py_DECREF(key); +#endif + key = NULL; + value = NULL; + continue; + } +#if !CYTHON_AVOID_BORROWED_REFS + Py_INCREF(key); +#endif + Py_INCREF(value); + name = first_kw_arg; + #if PY_MAJOR_VERSION < 3 + if (likely(PyString_Check(key))) { + while (*name) { + if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) + && _PyString_Eq(**name, key)) { + values[name-argnames] = value; +#if CYTHON_AVOID_BORROWED_REFS + value = NULL; +#endif + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + if ((**argname == key) || ( + (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) + && _PyString_Eq(**argname, key))) { + goto arg_passed_twice; + } + argname++; + } + } + } else + #endif + if (likely(PyUnicode_Check(key))) { + while (*name) { + int cmp = ( + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (__Pyx_PyUnicode_GET_LENGTH(**name) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : + #endif + PyUnicode_Compare(**name, key) + ); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) { + values[name-argnames] = value; +#if CYTHON_AVOID_BORROWED_REFS + value = NULL; +#endif + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + int cmp = (**argname == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (__Pyx_PyUnicode_GET_LENGTH(**argname) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : + #endif + PyUnicode_Compare(**argname, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) goto arg_passed_twice; + argname++; + } + } + } else + goto invalid_keyword_type; + if (kwds2) { + if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; + } else { + goto invalid_keyword; + } + } + Py_XDECREF(key); + Py_XDECREF(value); + return 0; +arg_passed_twice: + __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; +invalid_keyword_type: + PyErr_Format(PyExc_TypeError, + "%.200s() keywords must be strings", function_name); + goto bad; +invalid_keyword: + #if PY_MAJOR_VERSION < 3 + PyErr_Format(PyExc_TypeError, + "%.200s() got an unexpected keyword argument '%.200s'", + function_name, PyString_AsString(key)); + #else + PyErr_Format(PyExc_TypeError, + "%s() got an unexpected keyword argument '%U'", + function_name, key); + #endif +bad: + Py_XDECREF(key); + Py_XDECREF(value); + return -1; +} + +/* ArgTypeTest */ +static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact) +{ + __Pyx_TypeName type_name; + __Pyx_TypeName obj_type_name; + if (unlikely(!type)) { + PyErr_SetString(PyExc_SystemError, "Missing type object"); + return 0; + } + else if (exact) { + #if PY_MAJOR_VERSION == 2 + if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1; + #endif + } + else { + if (likely(__Pyx_TypeCheck(obj, type))) return 1; + } + type_name = __Pyx_PyType_GetName(type); + obj_type_name = __Pyx_PyType_GetName(Py_TYPE(obj)); + PyErr_Format(PyExc_TypeError, + "Argument '%.200s' has incorrect type (expected " __Pyx_FMT_TYPENAME + ", got " __Pyx_FMT_TYPENAME ")", name, type_name, obj_type_name); + __Pyx_DECREF_TypeName(type_name); + __Pyx_DECREF_TypeName(obj_type_name); + return 0; +} + +/* IsLittleEndian */ +static CYTHON_INLINE int __Pyx_Is_Little_Endian(void) +{ + union { + uint32_t u32; + uint8_t u8[4]; + } S; + S.u32 = 0x01020304; + return S.u8[0] == 4; +} + +/* BufferFormatCheck */ +static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, + __Pyx_BufFmt_StackElem* stack, + __Pyx_TypeInfo* type) { + stack[0].field = &ctx->root; + stack[0].parent_offset = 0; + ctx->root.type = type; + ctx->root.name = "buffer dtype"; + ctx->root.offset = 0; + ctx->head = stack; + ctx->head->field = &ctx->root; + ctx->fmt_offset = 0; + ctx->head->parent_offset = 0; + ctx->new_packmode = '@'; + ctx->enc_packmode = '@'; + ctx->new_count = 1; + ctx->enc_count = 0; + ctx->enc_type = 0; + ctx->is_complex = 0; + ctx->is_valid_array = 0; + ctx->struct_alignment = 0; + while (type->typegroup == 'S') { + ++ctx->head; + ctx->head->field = type->fields; + ctx->head->parent_offset = 0; + type = type->fields->type; + } +} +static int __Pyx_BufFmt_ParseNumber(const char** ts) { + int count; + const char* t = *ts; + if (*t < '0' || *t > '9') { + return -1; + } else { + count = *t++ - '0'; + while (*t >= '0' && *t <= '9') { + count *= 10; + count += *t++ - '0'; + } + } + *ts = t; + return count; +} +static int __Pyx_BufFmt_ExpectNumber(const char **ts) { + int number = __Pyx_BufFmt_ParseNumber(ts); + if (number == -1) + PyErr_Format(PyExc_ValueError,\ + "Does not understand character buffer dtype format string ('%c')", **ts); + return number; +} +static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) { + PyErr_Format(PyExc_ValueError, + "Unexpected format string character: '%c'", ch); +} +static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) { + switch (ch) { + case '?': return "'bool'"; + case 'c': return "'char'"; + case 'b': return "'signed char'"; + case 'B': return "'unsigned char'"; + case 'h': return "'short'"; + case 'H': return "'unsigned short'"; + case 'i': return "'int'"; + case 'I': return "'unsigned int'"; + case 'l': return "'long'"; + case 'L': return "'unsigned long'"; + case 'q': return "'long long'"; + case 'Q': return "'unsigned long long'"; + case 'f': return (is_complex ? "'complex float'" : "'float'"); + case 'd': return (is_complex ? "'complex double'" : "'double'"); + case 'g': return (is_complex ? "'complex long double'" : "'long double'"); + case 'T': return "a struct"; + case 'O': return "Python object"; + case 'P': return "a pointer"; + case 's': case 'p': return "a string"; + case 0: return "end"; + default: return "unparsable format string"; + } +} +static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) { + switch (ch) { + case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; + case 'h': case 'H': return 2; + case 'i': case 'I': case 'l': case 'L': return 4; + case 'q': case 'Q': return 8; + case 'f': return (is_complex ? 8 : 4); + case 'd': return (is_complex ? 16 : 8); + case 'g': { + PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g').."); + return 0; + } + case 'O': case 'P': return sizeof(void*); + default: + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } +} +static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) { + switch (ch) { + case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; + case 'h': case 'H': return sizeof(short); + case 'i': case 'I': return sizeof(int); + case 'l': case 'L': return sizeof(long); + #ifdef HAVE_LONG_LONG + case 'q': case 'Q': return sizeof(PY_LONG_LONG); + #endif + case 'f': return sizeof(float) * (is_complex ? 2 : 1); + case 'd': return sizeof(double) * (is_complex ? 2 : 1); + case 'g': return sizeof(long double) * (is_complex ? 2 : 1); + case 'O': case 'P': return sizeof(void*); + default: { + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } + } +} +typedef struct { char c; short x; } __Pyx_st_short; +typedef struct { char c; int x; } __Pyx_st_int; +typedef struct { char c; long x; } __Pyx_st_long; +typedef struct { char c; float x; } __Pyx_st_float; +typedef struct { char c; double x; } __Pyx_st_double; +typedef struct { char c; long double x; } __Pyx_st_longdouble; +typedef struct { char c; void *x; } __Pyx_st_void_p; +#ifdef HAVE_LONG_LONG +typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong; +#endif +static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, int is_complex) { + CYTHON_UNUSED_VAR(is_complex); + switch (ch) { + case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; + case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short); + case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int); + case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long); +#ifdef HAVE_LONG_LONG + case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG); +#endif + case 'f': return sizeof(__Pyx_st_float) - sizeof(float); + case 'd': return sizeof(__Pyx_st_double) - sizeof(double); + case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double); + case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*); + default: + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } +} +/* These are for computing the padding at the end of the struct to align + on the first member of the struct. This will probably the same as above, + but we don't have any guarantees. + */ +typedef struct { short x; char c; } __Pyx_pad_short; +typedef struct { int x; char c; } __Pyx_pad_int; +typedef struct { long x; char c; } __Pyx_pad_long; +typedef struct { float x; char c; } __Pyx_pad_float; +typedef struct { double x; char c; } __Pyx_pad_double; +typedef struct { long double x; char c; } __Pyx_pad_longdouble; +typedef struct { void *x; char c; } __Pyx_pad_void_p; +#ifdef HAVE_LONG_LONG +typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong; +#endif +static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, int is_complex) { + CYTHON_UNUSED_VAR(is_complex); + switch (ch) { + case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; + case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short); + case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int); + case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long); +#ifdef HAVE_LONG_LONG + case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG); +#endif + case 'f': return sizeof(__Pyx_pad_float) - sizeof(float); + case 'd': return sizeof(__Pyx_pad_double) - sizeof(double); + case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double); + case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*); + default: + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } +} +static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) { + switch (ch) { + case 'c': + return 'H'; + case 'b': case 'h': case 'i': + case 'l': case 'q': case 's': case 'p': + return 'I'; + case '?': case 'B': case 'H': case 'I': case 'L': case 'Q': + return 'U'; + case 'f': case 'd': case 'g': + return (is_complex ? 'C' : 'R'); + case 'O': + return 'O'; + case 'P': + return 'P'; + default: { + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } + } +} +static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) { + if (ctx->head == NULL || ctx->head->field == &ctx->root) { + const char* expected; + const char* quote; + if (ctx->head == NULL) { + expected = "end"; + quote = ""; + } else { + expected = ctx->head->field->type->name; + quote = "'"; + } + PyErr_Format(PyExc_ValueError, + "Buffer dtype mismatch, expected %s%s%s but got %s", + quote, expected, quote, + __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex)); + } else { + __Pyx_StructField* field = ctx->head->field; + __Pyx_StructField* parent = (ctx->head - 1)->field; + PyErr_Format(PyExc_ValueError, + "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'", + field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex), + parent->type->name, field->name); + } +} +static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) { + char group; + size_t size, offset, arraysize = 1; + if (ctx->enc_type == 0) return 0; + if (ctx->head->field->type->arraysize[0]) { + int i, ndim = 0; + if (ctx->enc_type == 's' || ctx->enc_type == 'p') { + ctx->is_valid_array = ctx->head->field->type->ndim == 1; + ndim = 1; + if (ctx->enc_count != ctx->head->field->type->arraysize[0]) { + PyErr_Format(PyExc_ValueError, + "Expected a dimension of size %zu, got %zu", + ctx->head->field->type->arraysize[0], ctx->enc_count); + return -1; + } + } + if (!ctx->is_valid_array) { + PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d", + ctx->head->field->type->ndim, ndim); + return -1; + } + for (i = 0; i < ctx->head->field->type->ndim; i++) { + arraysize *= ctx->head->field->type->arraysize[i]; + } + ctx->is_valid_array = 0; + ctx->enc_count = 1; + } + group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex); + do { + __Pyx_StructField* field = ctx->head->field; + __Pyx_TypeInfo* type = field->type; + if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') { + size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex); + } else { + size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex); + } + if (ctx->enc_packmode == '@') { + size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex); + size_t align_mod_offset; + if (align_at == 0) return -1; + align_mod_offset = ctx->fmt_offset % align_at; + if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset; + if (ctx->struct_alignment == 0) + ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type, + ctx->is_complex); + } + if (type->size != size || type->typegroup != group) { + if (type->typegroup == 'C' && type->fields != NULL) { + size_t parent_offset = ctx->head->parent_offset + field->offset; + ++ctx->head; + ctx->head->field = type->fields; + ctx->head->parent_offset = parent_offset; + continue; + } + if ((type->typegroup == 'H' || group == 'H') && type->size == size) { + } else { + __Pyx_BufFmt_RaiseExpected(ctx); + return -1; + } + } + offset = ctx->head->parent_offset + field->offset; + if (ctx->fmt_offset != offset) { + PyErr_Format(PyExc_ValueError, + "Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected", + (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset); + return -1; + } + ctx->fmt_offset += size; + if (arraysize) + ctx->fmt_offset += (arraysize - 1) * size; + --ctx->enc_count; + while (1) { + if (field == &ctx->root) { + ctx->head = NULL; + if (ctx->enc_count != 0) { + __Pyx_BufFmt_RaiseExpected(ctx); + return -1; + } + break; + } + ctx->head->field = ++field; + if (field->type == NULL) { + --ctx->head; + field = ctx->head->field; + continue; + } else if (field->type->typegroup == 'S') { + size_t parent_offset = ctx->head->parent_offset + field->offset; + if (field->type->fields->type == NULL) continue; + field = field->type->fields; + ++ctx->head; + ctx->head->field = field; + ctx->head->parent_offset = parent_offset; + break; + } else { + break; + } + } + } while (ctx->enc_count); + ctx->enc_type = 0; + ctx->is_complex = 0; + return 0; +} +static int +__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp) +{ + const char *ts = *tsp; + int i = 0, number, ndim; + ++ts; + if (ctx->new_count != 1) { + PyErr_SetString(PyExc_ValueError, + "Cannot handle repeated arrays in format string"); + return -1; + } + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return -1; + ndim = ctx->head->field->type->ndim; + while (*ts && *ts != ')') { + switch (*ts) { + case ' ': case '\f': case '\r': case '\n': case '\t': case '\v': continue; + default: break; + } + number = __Pyx_BufFmt_ExpectNumber(&ts); + if (number == -1) return -1; + if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i]) { + PyErr_Format(PyExc_ValueError, + "Expected a dimension of size %zu, got %d", + ctx->head->field->type->arraysize[i], number); + return -1; + } + if (*ts != ',' && *ts != ')') { + PyErr_Format(PyExc_ValueError, + "Expected a comma in format string, got '%c'", *ts); + return -1; + } + if (*ts == ',') ts++; + i++; + } + if (i != ndim) { + PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d", + ctx->head->field->type->ndim, i); + return -1; + } + if (!*ts) { + PyErr_SetString(PyExc_ValueError, + "Unexpected end of format string, expected ')'"); + return -1; + } + ctx->is_valid_array = 1; + ctx->new_count = 1; + *tsp = ++ts; + return 0; +} +static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) { + int got_Z = 0; + while (1) { + switch(*ts) { + case 0: + if (ctx->enc_type != 0 && ctx->head == NULL) { + __Pyx_BufFmt_RaiseExpected(ctx); + return NULL; + } + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + if (ctx->head != NULL) { + __Pyx_BufFmt_RaiseExpected(ctx); + return NULL; + } + return ts; + case ' ': + case '\r': + case '\n': + ++ts; + break; + case '<': + if (!__Pyx_Is_Little_Endian()) { + PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler"); + return NULL; + } + ctx->new_packmode = '='; + ++ts; + break; + case '>': + case '!': + if (__Pyx_Is_Little_Endian()) { + PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler"); + return NULL; + } + ctx->new_packmode = '='; + ++ts; + break; + case '=': + case '@': + case '^': + ctx->new_packmode = *ts++; + break; + case 'T': + { + const char* ts_after_sub; + size_t i, struct_count = ctx->new_count; + size_t struct_alignment = ctx->struct_alignment; + ctx->new_count = 1; + ++ts; + if (*ts != '{') { + PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'"); + return NULL; + } + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->enc_type = 0; + ctx->enc_count = 0; + ctx->struct_alignment = 0; + ++ts; + ts_after_sub = ts; + for (i = 0; i != struct_count; ++i) { + ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts); + if (!ts_after_sub) return NULL; + } + ts = ts_after_sub; + if (struct_alignment) ctx->struct_alignment = struct_alignment; + } + break; + case '}': + { + size_t alignment = ctx->struct_alignment; + ++ts; + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->enc_type = 0; + if (alignment && ctx->fmt_offset % alignment) { + ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment); + } + } + return ts; + case 'x': + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->fmt_offset += ctx->new_count; + ctx->new_count = 1; + ctx->enc_count = 0; + ctx->enc_type = 0; + ctx->enc_packmode = ctx->new_packmode; + ++ts; + break; + case 'Z': + got_Z = 1; + ++ts; + if (*ts != 'f' && *ts != 'd' && *ts != 'g') { + __Pyx_BufFmt_RaiseUnexpectedChar('Z'); + return NULL; + } + CYTHON_FALLTHROUGH; + case '?': case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I': + case 'l': case 'L': case 'q': case 'Q': + case 'f': case 'd': case 'g': + case 'O': case 'p': + if ((ctx->enc_type == *ts) && (got_Z == ctx->is_complex) && + (ctx->enc_packmode == ctx->new_packmode) && (!ctx->is_valid_array)) { + ctx->enc_count += ctx->new_count; + ctx->new_count = 1; + got_Z = 0; + ++ts; + break; + } + CYTHON_FALLTHROUGH; + case 's': + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->enc_count = ctx->new_count; + ctx->enc_packmode = ctx->new_packmode; + ctx->enc_type = *ts; + ctx->is_complex = got_Z; + ++ts; + ctx->new_count = 1; + got_Z = 0; + break; + case ':': + ++ts; + while(*ts != ':') ++ts; + ++ts; + break; + case '(': + if (__pyx_buffmt_parse_array(ctx, &ts) < 0) return NULL; + break; + default: + { + int number = __Pyx_BufFmt_ExpectNumber(&ts); + if (number == -1) return NULL; + ctx->new_count = (size_t)number; + } + } + } +} + +/* BufferGetAndValidate */ + static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) { + if (unlikely(info->buf == NULL)) return; + if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL; + __Pyx_ReleaseBuffer(info); +} +static void __Pyx_ZeroBuffer(Py_buffer* buf) { + buf->buf = NULL; + buf->obj = NULL; + buf->strides = __Pyx_zeros; + buf->shape = __Pyx_zeros; + buf->suboffsets = __Pyx_minusones; +} +static int __Pyx__GetBufferAndValidate( + Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags, + int nd, int cast, __Pyx_BufFmt_StackElem* stack) +{ + buf->buf = NULL; + if (unlikely(__Pyx_GetBuffer(obj, buf, flags) == -1)) { + __Pyx_ZeroBuffer(buf); + return -1; + } + if (unlikely(buf->ndim != nd)) { + PyErr_Format(PyExc_ValueError, + "Buffer has wrong number of dimensions (expected %d, got %d)", + nd, buf->ndim); + goto fail; + } + if (!cast) { + __Pyx_BufFmt_Context ctx; + __Pyx_BufFmt_Init(&ctx, stack, dtype); + if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail; + } + if (unlikely((size_t)buf->itemsize != dtype->size)) { + PyErr_Format(PyExc_ValueError, + "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "d byte%s) does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "d byte%s)", + buf->itemsize, (buf->itemsize > 1) ? "s" : "", + dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : ""); + goto fail; + } + if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones; + return 0; +fail:; + __Pyx_SafeReleaseBuffer(buf); + return -1; +} + +/* TypeImport */ + #ifndef __PYX_HAVE_RT_ImportType_3_0_9 +#define __PYX_HAVE_RT_ImportType_3_0_9 +static PyTypeObject *__Pyx_ImportType_3_0_9(PyObject *module, const char *module_name, const char *class_name, + size_t size, size_t alignment, enum __Pyx_ImportType_CheckSize_3_0_9 check_size) +{ + PyObject *result = 0; + char warning[200]; + Py_ssize_t basicsize; + Py_ssize_t itemsize; +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *py_basicsize; + PyObject *py_itemsize; +#endif + result = PyObject_GetAttrString(module, class_name); + if (!result) + goto bad; + if (!PyType_Check(result)) { + PyErr_Format(PyExc_TypeError, + "%.200s.%.200s is not a type object", + module_name, class_name); + goto bad; + } +#if !CYTHON_COMPILING_IN_LIMITED_API + basicsize = ((PyTypeObject *)result)->tp_basicsize; + itemsize = ((PyTypeObject *)result)->tp_itemsize; +#else + py_basicsize = PyObject_GetAttrString(result, "__basicsize__"); + if (!py_basicsize) + goto bad; + basicsize = PyLong_AsSsize_t(py_basicsize); + Py_DECREF(py_basicsize); + py_basicsize = 0; + if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred()) + goto bad; + py_itemsize = PyObject_GetAttrString(result, "__itemsize__"); + if (!py_itemsize) + goto bad; + itemsize = PyLong_AsSsize_t(py_itemsize); + Py_DECREF(py_itemsize); + py_itemsize = 0; + if (itemsize == (Py_ssize_t)-1 && PyErr_Occurred()) + goto bad; +#endif + if (itemsize) { + if (size % alignment) { + alignment = size % alignment; + } + if (itemsize < (Py_ssize_t)alignment) + itemsize = (Py_ssize_t)alignment; + } + if ((size_t)(basicsize + itemsize) < size) { + PyErr_Format(PyExc_ValueError, + "%.200s.%.200s size changed, may indicate binary incompatibility. " + "Expected %zd from C header, got %zd from PyObject", + module_name, class_name, size, basicsize+itemsize); + goto bad; + } + if (check_size == __Pyx_ImportType_CheckSize_Error_3_0_9 && + ((size_t)basicsize > size || (size_t)(basicsize + itemsize) < size)) { + PyErr_Format(PyExc_ValueError, + "%.200s.%.200s size changed, may indicate binary incompatibility. " + "Expected %zd from C header, got %zd-%zd from PyObject", + module_name, class_name, size, basicsize, basicsize+itemsize); + goto bad; + } + else if (check_size == __Pyx_ImportType_CheckSize_Warn_3_0_9 && (size_t)basicsize > size) { + PyOS_snprintf(warning, sizeof(warning), + "%s.%s size changed, may indicate binary incompatibility. " + "Expected %zd from C header, got %zd from PyObject", + module_name, class_name, size, basicsize); + if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad; + } + return (PyTypeObject *)result; +bad: + Py_XDECREF(result); + return NULL; +} +#endif + +/* Import */ + static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { + PyObject *module = 0; + PyObject *empty_dict = 0; + PyObject *empty_list = 0; + #if PY_MAJOR_VERSION < 3 + PyObject *py_import; + py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); + if (unlikely(!py_import)) + goto bad; + if (!from_list) { + empty_list = PyList_New(0); + if (unlikely(!empty_list)) + goto bad; + from_list = empty_list; + } + #endif + empty_dict = PyDict_New(); + if (unlikely(!empty_dict)) + goto bad; + { + #if PY_MAJOR_VERSION >= 3 + if (level == -1) { + if (strchr(__Pyx_MODULE_NAME, '.') != NULL) { + module = PyImport_ImportModuleLevelObject( + name, __pyx_d, empty_dict, from_list, 1); + if (unlikely(!module)) { + if (unlikely(!PyErr_ExceptionMatches(PyExc_ImportError))) + goto bad; + PyErr_Clear(); + } + } + level = 0; + } + #endif + if (!module) { + #if PY_MAJOR_VERSION < 3 + PyObject *py_level = PyInt_FromLong(level); + if (unlikely(!py_level)) + goto bad; + module = PyObject_CallFunctionObjArgs(py_import, + name, __pyx_d, empty_dict, from_list, py_level, (PyObject *)NULL); + Py_DECREF(py_level); + #else + module = PyImport_ImportModuleLevelObject( + name, __pyx_d, empty_dict, from_list, level); + #endif + } + } +bad: + Py_XDECREF(empty_dict); + Py_XDECREF(empty_list); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(py_import); + #endif + return module; +} + +/* ImportDottedModule */ + #if PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx__ImportDottedModule_Error(PyObject *name, PyObject *parts_tuple, Py_ssize_t count) { + PyObject *partial_name = NULL, *slice = NULL, *sep = NULL; + if (unlikely(PyErr_Occurred())) { + PyErr_Clear(); + } + if (likely(PyTuple_GET_SIZE(parts_tuple) == count)) { + partial_name = name; + } else { + slice = PySequence_GetSlice(parts_tuple, 0, count); + if (unlikely(!slice)) + goto bad; + sep = PyUnicode_FromStringAndSize(".", 1); + if (unlikely(!sep)) + goto bad; + partial_name = PyUnicode_Join(sep, slice); + } + PyErr_Format( +#if PY_MAJOR_VERSION < 3 + PyExc_ImportError, + "No module named '%s'", PyString_AS_STRING(partial_name)); +#else +#if PY_VERSION_HEX >= 0x030600B1 + PyExc_ModuleNotFoundError, +#else + PyExc_ImportError, +#endif + "No module named '%U'", partial_name); +#endif +bad: + Py_XDECREF(sep); + Py_XDECREF(slice); + Py_XDECREF(partial_name); + return NULL; +} +#endif +#if PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx__ImportDottedModule_Lookup(PyObject *name) { + PyObject *imported_module; +#if PY_VERSION_HEX < 0x030700A1 || (CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM < 0x07030400) + PyObject *modules = PyImport_GetModuleDict(); + if (unlikely(!modules)) + return NULL; + imported_module = __Pyx_PyDict_GetItemStr(modules, name); + Py_XINCREF(imported_module); +#else + imported_module = PyImport_GetModule(name); +#endif + return imported_module; +} +#endif +#if PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx_ImportDottedModule_WalkParts(PyObject *module, PyObject *name, PyObject *parts_tuple) { + Py_ssize_t i, nparts; + nparts = PyTuple_GET_SIZE(parts_tuple); + for (i=1; i < nparts && module; i++) { + PyObject *part, *submodule; +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + part = PyTuple_GET_ITEM(parts_tuple, i); +#else + part = PySequence_ITEM(parts_tuple, i); +#endif + submodule = __Pyx_PyObject_GetAttrStrNoError(module, part); +#if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) + Py_DECREF(part); +#endif + Py_DECREF(module); + module = submodule; + } + if (unlikely(!module)) { + return __Pyx__ImportDottedModule_Error(name, parts_tuple, i); + } + return module; +} +#endif +static PyObject *__Pyx__ImportDottedModule(PyObject *name, PyObject *parts_tuple) { +#if PY_MAJOR_VERSION < 3 + PyObject *module, *from_list, *star = __pyx_n_s__3; + CYTHON_UNUSED_VAR(parts_tuple); + from_list = PyList_New(1); + if (unlikely(!from_list)) + return NULL; + Py_INCREF(star); + PyList_SET_ITEM(from_list, 0, star); + module = __Pyx_Import(name, from_list, 0); + Py_DECREF(from_list); + return module; +#else + PyObject *imported_module; + PyObject *module = __Pyx_Import(name, NULL, 0); + if (!parts_tuple || unlikely(!module)) + return module; + imported_module = __Pyx__ImportDottedModule_Lookup(name); + if (likely(imported_module)) { + Py_DECREF(module); + return imported_module; + } + PyErr_Clear(); + return __Pyx_ImportDottedModule_WalkParts(module, name, parts_tuple); +#endif +} +static PyObject *__Pyx_ImportDottedModule(PyObject *name, PyObject *parts_tuple) { +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030400B1 + PyObject *module = __Pyx__ImportDottedModule_Lookup(name); + if (likely(module)) { + PyObject *spec = __Pyx_PyObject_GetAttrStrNoError(module, __pyx_n_s_spec); + if (likely(spec)) { + PyObject *unsafe = __Pyx_PyObject_GetAttrStrNoError(spec, __pyx_n_s_initializing); + if (likely(!unsafe || !__Pyx_PyObject_IsTrue(unsafe))) { + Py_DECREF(spec); + spec = NULL; + } + Py_XDECREF(unsafe); + } + if (likely(!spec)) { + PyErr_Clear(); + return module; + } + Py_DECREF(spec); + Py_DECREF(module); + } else if (PyErr_Occurred()) { + PyErr_Clear(); + } +#endif + return __Pyx__ImportDottedModule(name, parts_tuple); +} + +/* FixUpExtensionType */ + #if CYTHON_USE_TYPE_SPECS +static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type) { +#if PY_VERSION_HEX > 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + CYTHON_UNUSED_VAR(spec); + CYTHON_UNUSED_VAR(type); +#else + const PyType_Slot *slot = spec->slots; + while (slot && slot->slot && slot->slot != Py_tp_members) + slot++; + if (slot && slot->slot == Py_tp_members) { + int changed = 0; +#if !(PY_VERSION_HEX <= 0x030900b1 && CYTHON_COMPILING_IN_CPYTHON) + const +#endif + PyMemberDef *memb = (PyMemberDef*) slot->pfunc; + while (memb && memb->name) { + if (memb->name[0] == '_' && memb->name[1] == '_') { +#if PY_VERSION_HEX < 0x030900b1 + if (strcmp(memb->name, "__weaklistoffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + type->tp_weaklistoffset = memb->offset; + changed = 1; + } + else if (strcmp(memb->name, "__dictoffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + type->tp_dictoffset = memb->offset; + changed = 1; + } +#if CYTHON_METH_FASTCALL + else if (strcmp(memb->name, "__vectorcalloffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); +#if PY_VERSION_HEX >= 0x030800b4 + type->tp_vectorcall_offset = memb->offset; +#else + type->tp_print = (printfunc) memb->offset; +#endif + changed = 1; + } +#endif +#else + if ((0)); +#endif +#if PY_VERSION_HEX <= 0x030900b1 && CYTHON_COMPILING_IN_CPYTHON + else if (strcmp(memb->name, "__module__") == 0) { + PyObject *descr; + assert(memb->type == T_OBJECT); + assert(memb->flags == 0 || memb->flags == READONLY); + descr = PyDescr_NewMember(type, memb); + if (unlikely(!descr)) + return -1; + if (unlikely(PyDict_SetItem(type->tp_dict, PyDescr_NAME(descr), descr) < 0)) { + Py_DECREF(descr); + return -1; + } + Py_DECREF(descr); + changed = 1; + } +#endif + } + memb++; + } + if (changed) + PyType_Modified(type); + } +#endif + return 0; +} +#endif + +/* FetchSharedCythonModule */ + static PyObject *__Pyx_FetchSharedCythonABIModule(void) { + return __Pyx_PyImport_AddModuleRef((char*) __PYX_ABI_MODULE_NAME); +} + +/* FetchCommonType */ + static int __Pyx_VerifyCachedType(PyObject *cached_type, + const char *name, + Py_ssize_t basicsize, + Py_ssize_t expected_basicsize) { + if (!PyType_Check(cached_type)) { + PyErr_Format(PyExc_TypeError, + "Shared Cython type %.200s is not a type object", name); + return -1; + } + if (basicsize != expected_basicsize) { + PyErr_Format(PyExc_TypeError, + "Shared Cython type %.200s has the wrong size, try recompiling", + name); + return -1; + } + return 0; +} +#if !CYTHON_USE_TYPE_SPECS +static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) { + PyObject* abi_module; + const char* object_name; + PyTypeObject *cached_type = NULL; + abi_module = __Pyx_FetchSharedCythonABIModule(); + if (!abi_module) return NULL; + object_name = strrchr(type->tp_name, '.'); + object_name = object_name ? object_name+1 : type->tp_name; + cached_type = (PyTypeObject*) PyObject_GetAttrString(abi_module, object_name); + if (cached_type) { + if (__Pyx_VerifyCachedType( + (PyObject *)cached_type, + object_name, + cached_type->tp_basicsize, + type->tp_basicsize) < 0) { + goto bad; + } + goto done; + } + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad; + PyErr_Clear(); + if (PyType_Ready(type) < 0) goto bad; + if (PyObject_SetAttrString(abi_module, object_name, (PyObject *)type) < 0) + goto bad; + Py_INCREF(type); + cached_type = type; +done: + Py_DECREF(abi_module); + return cached_type; +bad: + Py_XDECREF(cached_type); + cached_type = NULL; + goto done; +} +#else +static PyTypeObject *__Pyx_FetchCommonTypeFromSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) { + PyObject *abi_module, *cached_type = NULL; + const char* object_name = strrchr(spec->name, '.'); + object_name = object_name ? object_name+1 : spec->name; + abi_module = __Pyx_FetchSharedCythonABIModule(); + if (!abi_module) return NULL; + cached_type = PyObject_GetAttrString(abi_module, object_name); + if (cached_type) { + Py_ssize_t basicsize; +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *py_basicsize; + py_basicsize = PyObject_GetAttrString(cached_type, "__basicsize__"); + if (unlikely(!py_basicsize)) goto bad; + basicsize = PyLong_AsSsize_t(py_basicsize); + Py_DECREF(py_basicsize); + py_basicsize = 0; + if (unlikely(basicsize == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad; +#else + basicsize = likely(PyType_Check(cached_type)) ? ((PyTypeObject*) cached_type)->tp_basicsize : -1; +#endif + if (__Pyx_VerifyCachedType( + cached_type, + object_name, + basicsize, + spec->basicsize) < 0) { + goto bad; + } + goto done; + } + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad; + PyErr_Clear(); + CYTHON_UNUSED_VAR(module); + cached_type = __Pyx_PyType_FromModuleAndSpec(abi_module, spec, bases); + if (unlikely(!cached_type)) goto bad; + if (unlikely(__Pyx_fix_up_extension_type_from_spec(spec, (PyTypeObject *) cached_type) < 0)) goto bad; + if (PyObject_SetAttrString(abi_module, object_name, cached_type) < 0) goto bad; +done: + Py_DECREF(abi_module); + assert(cached_type == NULL || PyType_Check(cached_type)); + return (PyTypeObject *) cached_type; +bad: + Py_XDECREF(cached_type); + cached_type = NULL; + goto done; +} +#endif + +/* PyVectorcallFastCallDict */ + #if CYTHON_METH_FASTCALL +static PyObject *__Pyx_PyVectorcall_FastCallDict_kw(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw) +{ + PyObject *res = NULL; + PyObject *kwnames; + PyObject **newargs; + PyObject **kwvalues; + Py_ssize_t i, pos; + size_t j; + PyObject *key, *value; + unsigned long keys_are_strings; + Py_ssize_t nkw = PyDict_GET_SIZE(kw); + newargs = (PyObject **)PyMem_Malloc((nargs + (size_t)nkw) * sizeof(args[0])); + if (unlikely(newargs == NULL)) { + PyErr_NoMemory(); + return NULL; + } + for (j = 0; j < nargs; j++) newargs[j] = args[j]; + kwnames = PyTuple_New(nkw); + if (unlikely(kwnames == NULL)) { + PyMem_Free(newargs); + return NULL; + } + kwvalues = newargs + nargs; + pos = i = 0; + keys_are_strings = Py_TPFLAGS_UNICODE_SUBCLASS; + while (PyDict_Next(kw, &pos, &key, &value)) { + keys_are_strings &= Py_TYPE(key)->tp_flags; + Py_INCREF(key); + Py_INCREF(value); + PyTuple_SET_ITEM(kwnames, i, key); + kwvalues[i] = value; + i++; + } + if (unlikely(!keys_are_strings)) { + PyErr_SetString(PyExc_TypeError, "keywords must be strings"); + goto cleanup; + } + res = vc(func, newargs, nargs, kwnames); +cleanup: + Py_DECREF(kwnames); + for (i = 0; i < nkw; i++) + Py_DECREF(kwvalues[i]); + PyMem_Free(newargs); + return res; +} +static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw) +{ + if (likely(kw == NULL) || PyDict_GET_SIZE(kw) == 0) { + return vc(func, args, nargs, NULL); + } + return __Pyx_PyVectorcall_FastCallDict_kw(func, vc, args, nargs, kw); +} +#endif + +/* CythonFunctionShared */ + #if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc) { + if (__Pyx_CyFunction_Check(func)) { + return PyCFunction_GetFunction(((__pyx_CyFunctionObject*)func)->func) == (PyCFunction) cfunc; + } else if (PyCFunction_Check(func)) { + return PyCFunction_GetFunction(func) == (PyCFunction) cfunc; + } + return 0; +} +#else +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc) { + return __Pyx_CyOrPyCFunction_Check(func) && __Pyx_CyOrPyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc; +} +#endif +static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj) { +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + __Pyx_Py_XDECREF_SET( + __Pyx_CyFunction_GetClassObj(f), + ((classobj) ? __Pyx_NewRef(classobj) : NULL)); +#else + __Pyx_Py_XDECREF_SET( + ((PyCMethodObject *) (f))->mm_class, + (PyTypeObject*)((classobj) ? __Pyx_NewRef(classobj) : NULL)); +#endif +} +static PyObject * +__Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, void *closure) +{ + CYTHON_UNUSED_VAR(closure); + if (unlikely(op->func_doc == NULL)) { +#if CYTHON_COMPILING_IN_LIMITED_API + op->func_doc = PyObject_GetAttrString(op->func, "__doc__"); + if (unlikely(!op->func_doc)) return NULL; +#else + if (((PyCFunctionObject*)op)->m_ml->ml_doc) { +#if PY_MAJOR_VERSION >= 3 + op->func_doc = PyUnicode_FromString(((PyCFunctionObject*)op)->m_ml->ml_doc); +#else + op->func_doc = PyString_FromString(((PyCFunctionObject*)op)->m_ml->ml_doc); +#endif + if (unlikely(op->func_doc == NULL)) + return NULL; + } else { + Py_INCREF(Py_None); + return Py_None; + } +#endif + } + Py_INCREF(op->func_doc); + return op->func_doc; +} +static int +__Pyx_CyFunction_set_doc(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (value == NULL) { + value = Py_None; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->func_doc, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_name(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(op->func_name == NULL)) { +#if CYTHON_COMPILING_IN_LIMITED_API + op->func_name = PyObject_GetAttrString(op->func, "__name__"); +#elif PY_MAJOR_VERSION >= 3 + op->func_name = PyUnicode_InternFromString(((PyCFunctionObject*)op)->m_ml->ml_name); +#else + op->func_name = PyString_InternFromString(((PyCFunctionObject*)op)->m_ml->ml_name); +#endif + if (unlikely(op->func_name == NULL)) + return NULL; + } + Py_INCREF(op->func_name); + return op->func_name; +} +static int +__Pyx_CyFunction_set_name(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); +#if PY_MAJOR_VERSION >= 3 + if (unlikely(value == NULL || !PyUnicode_Check(value))) +#else + if (unlikely(value == NULL || !PyString_Check(value))) +#endif + { + PyErr_SetString(PyExc_TypeError, + "__name__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->func_name, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_qualname(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + Py_INCREF(op->func_qualname); + return op->func_qualname; +} +static int +__Pyx_CyFunction_set_qualname(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); +#if PY_MAJOR_VERSION >= 3 + if (unlikely(value == NULL || !PyUnicode_Check(value))) +#else + if (unlikely(value == NULL || !PyString_Check(value))) +#endif + { + PyErr_SetString(PyExc_TypeError, + "__qualname__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->func_qualname, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_dict(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(op->func_dict == NULL)) { + op->func_dict = PyDict_New(); + if (unlikely(op->func_dict == NULL)) + return NULL; + } + Py_INCREF(op->func_dict); + return op->func_dict; +} +static int +__Pyx_CyFunction_set_dict(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(value == NULL)) { + PyErr_SetString(PyExc_TypeError, + "function's dictionary may not be deleted"); + return -1; + } + if (unlikely(!PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "setting function's dictionary to a non-dict"); + return -1; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->func_dict, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_globals(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + Py_INCREF(op->func_globals); + return op->func_globals; +} +static PyObject * +__Pyx_CyFunction_get_closure(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(op); + CYTHON_UNUSED_VAR(context); + Py_INCREF(Py_None); + return Py_None; +} +static PyObject * +__Pyx_CyFunction_get_code(__pyx_CyFunctionObject *op, void *context) +{ + PyObject* result = (op->func_code) ? op->func_code : Py_None; + CYTHON_UNUSED_VAR(context); + Py_INCREF(result); + return result; +} +static int +__Pyx_CyFunction_init_defaults(__pyx_CyFunctionObject *op) { + int result = 0; + PyObject *res = op->defaults_getter((PyObject *) op); + if (unlikely(!res)) + return -1; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + op->defaults_tuple = PyTuple_GET_ITEM(res, 0); + Py_INCREF(op->defaults_tuple); + op->defaults_kwdict = PyTuple_GET_ITEM(res, 1); + Py_INCREF(op->defaults_kwdict); + #else + op->defaults_tuple = __Pyx_PySequence_ITEM(res, 0); + if (unlikely(!op->defaults_tuple)) result = -1; + else { + op->defaults_kwdict = __Pyx_PySequence_ITEM(res, 1); + if (unlikely(!op->defaults_kwdict)) result = -1; + } + #endif + Py_DECREF(res); + return result; +} +static int +__Pyx_CyFunction_set_defaults(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value) { + value = Py_None; + } else if (unlikely(value != Py_None && !PyTuple_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__defaults__ must be set to a tuple object"); + return -1; + } + PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__defaults__ will not " + "currently affect the values used in function calls", 1); + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->defaults_tuple, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_defaults(__pyx_CyFunctionObject *op, void *context) { + PyObject* result = op->defaults_tuple; + CYTHON_UNUSED_VAR(context); + if (unlikely(!result)) { + if (op->defaults_getter) { + if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL; + result = op->defaults_tuple; + } else { + result = Py_None; + } + } + Py_INCREF(result); + return result; +} +static int +__Pyx_CyFunction_set_kwdefaults(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value) { + value = Py_None; + } else if (unlikely(value != Py_None && !PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__kwdefaults__ must be set to a dict object"); + return -1; + } + PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__kwdefaults__ will not " + "currently affect the values used in function calls", 1); + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->defaults_kwdict, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_kwdefaults(__pyx_CyFunctionObject *op, void *context) { + PyObject* result = op->defaults_kwdict; + CYTHON_UNUSED_VAR(context); + if (unlikely(!result)) { + if (op->defaults_getter) { + if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL; + result = op->defaults_kwdict; + } else { + result = Py_None; + } + } + Py_INCREF(result); + return result; +} +static int +__Pyx_CyFunction_set_annotations(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value || value == Py_None) { + value = NULL; + } else if (unlikely(!PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__annotations__ must be set to a dict object"); + return -1; + } + Py_XINCREF(value); + __Pyx_Py_XDECREF_SET(op->func_annotations, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_annotations(__pyx_CyFunctionObject *op, void *context) { + PyObject* result = op->func_annotations; + CYTHON_UNUSED_VAR(context); + if (unlikely(!result)) { + result = PyDict_New(); + if (unlikely(!result)) return NULL; + op->func_annotations = result; + } + Py_INCREF(result); + return result; +} +static PyObject * +__Pyx_CyFunction_get_is_coroutine(__pyx_CyFunctionObject *op, void *context) { + int is_coroutine; + CYTHON_UNUSED_VAR(context); + if (op->func_is_coroutine) { + return __Pyx_NewRef(op->func_is_coroutine); + } + is_coroutine = op->flags & __Pyx_CYFUNCTION_COROUTINE; +#if PY_VERSION_HEX >= 0x03050000 + if (is_coroutine) { + PyObject *module, *fromlist, *marker = __pyx_n_s_is_coroutine; + fromlist = PyList_New(1); + if (unlikely(!fromlist)) return NULL; + Py_INCREF(marker); +#if CYTHON_ASSUME_SAFE_MACROS + PyList_SET_ITEM(fromlist, 0, marker); +#else + if (unlikely(PyList_SetItem(fromlist, 0, marker) < 0)) { + Py_DECREF(marker); + Py_DECREF(fromlist); + return NULL; + } +#endif + module = PyImport_ImportModuleLevelObject(__pyx_n_s_asyncio_coroutines, NULL, NULL, fromlist, 0); + Py_DECREF(fromlist); + if (unlikely(!module)) goto ignore; + op->func_is_coroutine = __Pyx_PyObject_GetAttrStr(module, marker); + Py_DECREF(module); + if (likely(op->func_is_coroutine)) { + return __Pyx_NewRef(op->func_is_coroutine); + } +ignore: + PyErr_Clear(); + } +#endif + op->func_is_coroutine = __Pyx_PyBool_FromLong(is_coroutine); + return __Pyx_NewRef(op->func_is_coroutine); +} +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject * +__Pyx_CyFunction_get_module(__pyx_CyFunctionObject *op, void *context) { + CYTHON_UNUSED_VAR(context); + return PyObject_GetAttrString(op->func, "__module__"); +} +static int +__Pyx_CyFunction_set_module(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + return PyObject_SetAttrString(op->func, "__module__", value); +} +#endif +static PyGetSetDef __pyx_CyFunction_getsets[] = { + {(char *) "func_doc", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, + {(char *) "__doc__", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, + {(char *) "func_name", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, + {(char *) "__name__", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, + {(char *) "__qualname__", (getter)__Pyx_CyFunction_get_qualname, (setter)__Pyx_CyFunction_set_qualname, 0, 0}, + {(char *) "func_dict", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0}, + {(char *) "__dict__", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0}, + {(char *) "func_globals", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, + {(char *) "__globals__", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, + {(char *) "func_closure", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, + {(char *) "__closure__", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, + {(char *) "func_code", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, + {(char *) "__code__", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, + {(char *) "func_defaults", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, + {(char *) "__defaults__", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, + {(char *) "__kwdefaults__", (getter)__Pyx_CyFunction_get_kwdefaults, (setter)__Pyx_CyFunction_set_kwdefaults, 0, 0}, + {(char *) "__annotations__", (getter)__Pyx_CyFunction_get_annotations, (setter)__Pyx_CyFunction_set_annotations, 0, 0}, + {(char *) "_is_coroutine", (getter)__Pyx_CyFunction_get_is_coroutine, 0, 0, 0}, +#if CYTHON_COMPILING_IN_LIMITED_API + {"__module__", (getter)__Pyx_CyFunction_get_module, (setter)__Pyx_CyFunction_set_module, 0, 0}, +#endif + {0, 0, 0, 0, 0} +}; +static PyMemberDef __pyx_CyFunction_members[] = { +#if !CYTHON_COMPILING_IN_LIMITED_API + {(char *) "__module__", T_OBJECT, offsetof(PyCFunctionObject, m_module), 0, 0}, +#endif +#if CYTHON_USE_TYPE_SPECS + {(char *) "__dictoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_dict), READONLY, 0}, +#if CYTHON_METH_FASTCALL +#if CYTHON_BACKPORT_VECTORCALL + {(char *) "__vectorcalloffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_vectorcall), READONLY, 0}, +#else +#if !CYTHON_COMPILING_IN_LIMITED_API + {(char *) "__vectorcalloffset__", T_PYSSIZET, offsetof(PyCFunctionObject, vectorcall), READONLY, 0}, +#endif +#endif +#endif +#if PY_VERSION_HEX < 0x030500A0 || CYTHON_COMPILING_IN_LIMITED_API + {(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_weakreflist), READONLY, 0}, +#else + {(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(PyCFunctionObject, m_weakreflist), READONLY, 0}, +#endif +#endif + {0, 0, 0, 0, 0} +}; +static PyObject * +__Pyx_CyFunction_reduce(__pyx_CyFunctionObject *m, PyObject *args) +{ + CYTHON_UNUSED_VAR(args); +#if PY_MAJOR_VERSION >= 3 + Py_INCREF(m->func_qualname); + return m->func_qualname; +#else + return PyString_FromString(((PyCFunctionObject*)m)->m_ml->ml_name); +#endif +} +static PyMethodDef __pyx_CyFunction_methods[] = { + {"__reduce__", (PyCFunction)__Pyx_CyFunction_reduce, METH_VARARGS, 0}, + {0, 0, 0, 0} +}; +#if PY_VERSION_HEX < 0x030500A0 || CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func_weakreflist) +#else +#define __Pyx_CyFunction_weakreflist(cyfunc) (((PyCFunctionObject*)cyfunc)->m_weakreflist) +#endif +static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject *op, PyMethodDef *ml, int flags, PyObject* qualname, + PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { +#if !CYTHON_COMPILING_IN_LIMITED_API + PyCFunctionObject *cf = (PyCFunctionObject*) op; +#endif + if (unlikely(op == NULL)) + return NULL; +#if CYTHON_COMPILING_IN_LIMITED_API + op->func = PyCFunction_NewEx(ml, (PyObject*)op, module); + if (unlikely(!op->func)) return NULL; +#endif + op->flags = flags; + __Pyx_CyFunction_weakreflist(op) = NULL; +#if !CYTHON_COMPILING_IN_LIMITED_API + cf->m_ml = ml; + cf->m_self = (PyObject *) op; +#endif + Py_XINCREF(closure); + op->func_closure = closure; +#if !CYTHON_COMPILING_IN_LIMITED_API + Py_XINCREF(module); + cf->m_module = module; +#endif + op->func_dict = NULL; + op->func_name = NULL; + Py_INCREF(qualname); + op->func_qualname = qualname; + op->func_doc = NULL; +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + op->func_classobj = NULL; +#else + ((PyCMethodObject*)op)->mm_class = NULL; +#endif + op->func_globals = globals; + Py_INCREF(op->func_globals); + Py_XINCREF(code); + op->func_code = code; + op->defaults_pyobjects = 0; + op->defaults_size = 0; + op->defaults = NULL; + op->defaults_tuple = NULL; + op->defaults_kwdict = NULL; + op->defaults_getter = NULL; + op->func_annotations = NULL; + op->func_is_coroutine = NULL; +#if CYTHON_METH_FASTCALL + switch (ml->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS | METH_METHOD)) { + case METH_NOARGS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_NOARGS; + break; + case METH_O: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_O; + break; + case METH_METHOD | METH_FASTCALL | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD; + break; + case METH_FASTCALL | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS; + break; + case METH_VARARGS | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = NULL; + break; + default: + PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction"); + Py_DECREF(op); + return NULL; + } +#endif + return (PyObject *) op; +} +static int +__Pyx_CyFunction_clear(__pyx_CyFunctionObject *m) +{ + Py_CLEAR(m->func_closure); +#if CYTHON_COMPILING_IN_LIMITED_API + Py_CLEAR(m->func); +#else + Py_CLEAR(((PyCFunctionObject*)m)->m_module); +#endif + Py_CLEAR(m->func_dict); + Py_CLEAR(m->func_name); + Py_CLEAR(m->func_qualname); + Py_CLEAR(m->func_doc); + Py_CLEAR(m->func_globals); + Py_CLEAR(m->func_code); +#if !CYTHON_COMPILING_IN_LIMITED_API +#if PY_VERSION_HEX < 0x030900B1 + Py_CLEAR(__Pyx_CyFunction_GetClassObj(m)); +#else + { + PyObject *cls = (PyObject*) ((PyCMethodObject *) (m))->mm_class; + ((PyCMethodObject *) (m))->mm_class = NULL; + Py_XDECREF(cls); + } +#endif +#endif + Py_CLEAR(m->defaults_tuple); + Py_CLEAR(m->defaults_kwdict); + Py_CLEAR(m->func_annotations); + Py_CLEAR(m->func_is_coroutine); + if (m->defaults) { + PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m); + int i; + for (i = 0; i < m->defaults_pyobjects; i++) + Py_XDECREF(pydefaults[i]); + PyObject_Free(m->defaults); + m->defaults = NULL; + } + return 0; +} +static void __Pyx__CyFunction_dealloc(__pyx_CyFunctionObject *m) +{ + if (__Pyx_CyFunction_weakreflist(m) != NULL) + PyObject_ClearWeakRefs((PyObject *) m); + __Pyx_CyFunction_clear(m); + __Pyx_PyHeapTypeObject_GC_Del(m); +} +static void __Pyx_CyFunction_dealloc(__pyx_CyFunctionObject *m) +{ + PyObject_GC_UnTrack(m); + __Pyx__CyFunction_dealloc(m); +} +static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit, void *arg) +{ + Py_VISIT(m->func_closure); +#if CYTHON_COMPILING_IN_LIMITED_API + Py_VISIT(m->func); +#else + Py_VISIT(((PyCFunctionObject*)m)->m_module); +#endif + Py_VISIT(m->func_dict); + Py_VISIT(m->func_name); + Py_VISIT(m->func_qualname); + Py_VISIT(m->func_doc); + Py_VISIT(m->func_globals); + Py_VISIT(m->func_code); +#if !CYTHON_COMPILING_IN_LIMITED_API + Py_VISIT(__Pyx_CyFunction_GetClassObj(m)); +#endif + Py_VISIT(m->defaults_tuple); + Py_VISIT(m->defaults_kwdict); + Py_VISIT(m->func_is_coroutine); + if (m->defaults) { + PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m); + int i; + for (i = 0; i < m->defaults_pyobjects; i++) + Py_VISIT(pydefaults[i]); + } + return 0; +} +static PyObject* +__Pyx_CyFunction_repr(__pyx_CyFunctionObject *op) +{ +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromFormat("", + op->func_qualname, (void *)op); +#else + return PyString_FromFormat("", + PyString_AsString(op->func_qualname), (void *)op); +#endif +} +static PyObject * __Pyx_CyFunction_CallMethod(PyObject *func, PyObject *self, PyObject *arg, PyObject *kw) { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *f = ((__pyx_CyFunctionObject*)func)->func; + PyObject *py_name = NULL; + PyCFunction meth; + int flags; + meth = PyCFunction_GetFunction(f); + if (unlikely(!meth)) return NULL; + flags = PyCFunction_GetFlags(f); + if (unlikely(flags < 0)) return NULL; +#else + PyCFunctionObject* f = (PyCFunctionObject*)func; + PyCFunction meth = f->m_ml->ml_meth; + int flags = f->m_ml->ml_flags; +#endif + Py_ssize_t size; + switch (flags & (METH_VARARGS | METH_KEYWORDS | METH_NOARGS | METH_O)) { + case METH_VARARGS: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) + return (*meth)(self, arg); + break; + case METH_VARARGS | METH_KEYWORDS: + return (*(PyCFunctionWithKeywords)(void*)meth)(self, arg, kw); + case METH_NOARGS: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) { +#if CYTHON_ASSUME_SAFE_MACROS + size = PyTuple_GET_SIZE(arg); +#else + size = PyTuple_Size(arg); + if (unlikely(size < 0)) return NULL; +#endif + if (likely(size == 0)) + return (*meth)(self, NULL); +#if CYTHON_COMPILING_IN_LIMITED_API + py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL); + if (!py_name) return NULL; + PyErr_Format(PyExc_TypeError, + "%.200S() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", + py_name, size); + Py_DECREF(py_name); +#else + PyErr_Format(PyExc_TypeError, + "%.200s() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", + f->m_ml->ml_name, size); +#endif + return NULL; + } + break; + case METH_O: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) { +#if CYTHON_ASSUME_SAFE_MACROS + size = PyTuple_GET_SIZE(arg); +#else + size = PyTuple_Size(arg); + if (unlikely(size < 0)) return NULL; +#endif + if (likely(size == 1)) { + PyObject *result, *arg0; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + arg0 = PyTuple_GET_ITEM(arg, 0); + #else + arg0 = __Pyx_PySequence_ITEM(arg, 0); if (unlikely(!arg0)) return NULL; + #endif + result = (*meth)(self, arg0); + #if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) + Py_DECREF(arg0); + #endif + return result; + } +#if CYTHON_COMPILING_IN_LIMITED_API + py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL); + if (!py_name) return NULL; + PyErr_Format(PyExc_TypeError, + "%.200S() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", + py_name, size); + Py_DECREF(py_name); +#else + PyErr_Format(PyExc_TypeError, + "%.200s() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", + f->m_ml->ml_name, size); +#endif + return NULL; + } + break; + default: + PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction"); + return NULL; + } +#if CYTHON_COMPILING_IN_LIMITED_API + py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL); + if (!py_name) return NULL; + PyErr_Format(PyExc_TypeError, "%.200S() takes no keyword arguments", + py_name); + Py_DECREF(py_name); +#else + PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", + f->m_ml->ml_name); +#endif + return NULL; +} +static CYTHON_INLINE PyObject *__Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *self, *result; +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)func)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)func)->m_self; +#endif + result = __Pyx_CyFunction_CallMethod(func, self, arg, kw); + return result; +} +static PyObject *__Pyx_CyFunction_CallAsMethod(PyObject *func, PyObject *args, PyObject *kw) { + PyObject *result; + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *) func; +#if CYTHON_METH_FASTCALL + __pyx_vectorcallfunc vc = __Pyx_CyFunction_func_vectorcall(cyfunc); + if (vc) { +#if CYTHON_ASSUME_SAFE_MACROS + return __Pyx_PyVectorcall_FastCallDict(func, vc, &PyTuple_GET_ITEM(args, 0), (size_t)PyTuple_GET_SIZE(args), kw); +#else + (void) &__Pyx_PyVectorcall_FastCallDict; + return PyVectorcall_Call(func, args, kw); +#endif + } +#endif + if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { + Py_ssize_t argc; + PyObject *new_args; + PyObject *self; +#if CYTHON_ASSUME_SAFE_MACROS + argc = PyTuple_GET_SIZE(args); +#else + argc = PyTuple_Size(args); + if (unlikely(!argc) < 0) return NULL; +#endif + new_args = PyTuple_GetSlice(args, 1, argc); + if (unlikely(!new_args)) + return NULL; + self = PyTuple_GetItem(args, 0); + if (unlikely(!self)) { + Py_DECREF(new_args); +#if PY_MAJOR_VERSION > 2 + PyErr_Format(PyExc_TypeError, + "unbound method %.200S() needs an argument", + cyfunc->func_qualname); +#else + PyErr_SetString(PyExc_TypeError, + "unbound method needs an argument"); +#endif + return NULL; + } + result = __Pyx_CyFunction_CallMethod(func, self, new_args, kw); + Py_DECREF(new_args); + } else { + result = __Pyx_CyFunction_Call(func, args, kw); + } + return result; +} +#if CYTHON_METH_FASTCALL +static CYTHON_INLINE int __Pyx_CyFunction_Vectorcall_CheckArgs(__pyx_CyFunctionObject *cyfunc, Py_ssize_t nargs, PyObject *kwnames) +{ + int ret = 0; + if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { + if (unlikely(nargs < 1)) { + PyErr_Format(PyExc_TypeError, "%.200s() needs an argument", + ((PyCFunctionObject*)cyfunc)->m_ml->ml_name); + return -1; + } + ret = 1; + } + if (unlikely(kwnames) && unlikely(PyTuple_GET_SIZE(kwnames))) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes no keyword arguments", ((PyCFunctionObject*)cyfunc)->m_ml->ml_name); + return -1; + } + return ret; +} +static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; +#if CYTHON_BACKPORT_VECTORCALL + Py_ssize_t nargs = (Py_ssize_t)nargsf; +#else + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); +#endif + PyObject *self; + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: + self = ((PyCFunctionObject*)cyfunc)->m_self; + break; + default: + return NULL; + } + if (unlikely(nargs != 0)) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", + def->ml_name, nargs); + return NULL; + } + return def->ml_meth(self, NULL); +} +static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; +#if CYTHON_BACKPORT_VECTORCALL + Py_ssize_t nargs = (Py_ssize_t)nargsf; +#else + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); +#endif + PyObject *self; + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: + self = ((PyCFunctionObject*)cyfunc)->m_self; + break; + default: + return NULL; + } + if (unlikely(nargs != 1)) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", + def->ml_name, nargs); + return NULL; + } + return def->ml_meth(self, args[0]); +} +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; +#if CYTHON_BACKPORT_VECTORCALL + Py_ssize_t nargs = (Py_ssize_t)nargsf; +#else + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); +#endif + PyObject *self; + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: + self = ((PyCFunctionObject*)cyfunc)->m_self; + break; + default: + return NULL; + } + return ((__Pyx_PyCFunctionFastWithKeywords)(void(*)(void))def->ml_meth)(self, args, nargs, kwnames); +} +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; + PyTypeObject *cls = (PyTypeObject *) __Pyx_CyFunction_GetClassObj(cyfunc); +#if CYTHON_BACKPORT_VECTORCALL + Py_ssize_t nargs = (Py_ssize_t)nargsf; +#else + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); +#endif + PyObject *self; + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: + self = ((PyCFunctionObject*)cyfunc)->m_self; + break; + default: + return NULL; + } + return ((__Pyx_PyCMethod)(void(*)(void))def->ml_meth)(self, cls, args, (size_t)nargs, kwnames); +} +#endif +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_CyFunctionType_slots[] = { + {Py_tp_dealloc, (void *)__Pyx_CyFunction_dealloc}, + {Py_tp_repr, (void *)__Pyx_CyFunction_repr}, + {Py_tp_call, (void *)__Pyx_CyFunction_CallAsMethod}, + {Py_tp_traverse, (void *)__Pyx_CyFunction_traverse}, + {Py_tp_clear, (void *)__Pyx_CyFunction_clear}, + {Py_tp_methods, (void *)__pyx_CyFunction_methods}, + {Py_tp_members, (void *)__pyx_CyFunction_members}, + {Py_tp_getset, (void *)__pyx_CyFunction_getsets}, + {Py_tp_descr_get, (void *)__Pyx_PyMethod_New}, + {0, 0}, +}; +static PyType_Spec __pyx_CyFunctionType_spec = { + __PYX_TYPE_MODULE_PREFIX "cython_function_or_method", + sizeof(__pyx_CyFunctionObject), + 0, +#ifdef Py_TPFLAGS_METHOD_DESCRIPTOR + Py_TPFLAGS_METHOD_DESCRIPTOR | +#endif +#if (defined(_Py_TPFLAGS_HAVE_VECTORCALL) && CYTHON_METH_FASTCALL) + _Py_TPFLAGS_HAVE_VECTORCALL | +#endif + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + __pyx_CyFunctionType_slots +}; +#else +static PyTypeObject __pyx_CyFunctionType_type = { + PyVarObject_HEAD_INIT(0, 0) + __PYX_TYPE_MODULE_PREFIX "cython_function_or_method", + sizeof(__pyx_CyFunctionObject), + 0, + (destructor) __Pyx_CyFunction_dealloc, +#if !CYTHON_METH_FASTCALL + 0, +#elif CYTHON_BACKPORT_VECTORCALL + (printfunc)offsetof(__pyx_CyFunctionObject, func_vectorcall), +#else + offsetof(PyCFunctionObject, vectorcall), +#endif + 0, + 0, +#if PY_MAJOR_VERSION < 3 + 0, +#else + 0, +#endif + (reprfunc) __Pyx_CyFunction_repr, + 0, + 0, + 0, + 0, + __Pyx_CyFunction_CallAsMethod, + 0, + 0, + 0, + 0, +#ifdef Py_TPFLAGS_METHOD_DESCRIPTOR + Py_TPFLAGS_METHOD_DESCRIPTOR | +#endif +#if defined(_Py_TPFLAGS_HAVE_VECTORCALL) && CYTHON_METH_FASTCALL + _Py_TPFLAGS_HAVE_VECTORCALL | +#endif + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + 0, + (traverseproc) __Pyx_CyFunction_traverse, + (inquiry) __Pyx_CyFunction_clear, + 0, +#if PY_VERSION_HEX < 0x030500A0 + offsetof(__pyx_CyFunctionObject, func_weakreflist), +#else + offsetof(PyCFunctionObject, m_weakreflist), +#endif + 0, + 0, + __pyx_CyFunction_methods, + __pyx_CyFunction_members, + __pyx_CyFunction_getsets, + 0, + 0, + __Pyx_PyMethod_New, + 0, + offsetof(__pyx_CyFunctionObject, func_dict), + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +#if PY_VERSION_HEX >= 0x030400a1 + 0, +#endif +#if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, +#endif +#if __PYX_NEED_TP_PRINT_SLOT + 0, +#endif +#if PY_VERSION_HEX >= 0x030C0000 + 0, +#endif +#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, +#endif +}; +#endif +static int __pyx_CyFunction_init(PyObject *module) { +#if CYTHON_USE_TYPE_SPECS + __pyx_CyFunctionType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx_CyFunctionType_spec, NULL); +#else + CYTHON_UNUSED_VAR(module); + __pyx_CyFunctionType = __Pyx_FetchCommonType(&__pyx_CyFunctionType_type); +#endif + if (unlikely(__pyx_CyFunctionType == NULL)) { + return -1; + } + return 0; +} +static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *func, size_t size, int pyobjects) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults = PyObject_Malloc(size); + if (unlikely(!m->defaults)) + return PyErr_NoMemory(); + memset(m->defaults, 0, size); + m->defaults_pyobjects = pyobjects; + m->defaults_size = size; + return m->defaults; +} +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *func, PyObject *tuple) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults_tuple = tuple; + Py_INCREF(tuple); +} +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *func, PyObject *dict) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults_kwdict = dict; + Py_INCREF(dict); +} +static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *func, PyObject *dict) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->func_annotations = dict; + Py_INCREF(dict); +} + +/* CythonFunction */ + static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, int flags, PyObject* qualname, + PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { + PyObject *op = __Pyx_CyFunction_Init( + PyObject_GC_New(__pyx_CyFunctionObject, __pyx_CyFunctionType), + ml, flags, qualname, closure, module, globals, code + ); + if (likely(op)) { + PyObject_GC_Track(op); + } + return op; +} + +/* PyDictVersioning */ + #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { + PyObject **dictptr = NULL; + Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; + if (offset) { +#if CYTHON_COMPILING_IN_CPYTHON + dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); +#else + dictptr = _PyObject_GetDictPtr(obj); +#endif + } + return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; +} +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) + return 0; + return obj_dict_version == __Pyx_get_object_dict_version(obj); +} +#endif + +/* CLineInTraceback */ + #ifndef CYTHON_CLINE_IN_TRACEBACK +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line) { + PyObject *use_cline; + PyObject *ptype, *pvalue, *ptraceback; +#if CYTHON_COMPILING_IN_CPYTHON + PyObject **cython_runtime_dict; +#endif + CYTHON_MAYBE_UNUSED_VAR(tstate); + if (unlikely(!__pyx_cython_runtime)) { + return c_line; + } + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); +#if CYTHON_COMPILING_IN_CPYTHON + cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); + if (likely(cython_runtime_dict)) { + __PYX_PY_DICT_LOOKUP_IF_MODIFIED( + use_cline, *cython_runtime_dict, + __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback)) + } else +#endif + { + PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStrNoError(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback); + if (use_cline_obj) { + use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True; + Py_DECREF(use_cline_obj); + } else { + PyErr_Clear(); + use_cline = NULL; + } + } + if (!use_cline) { + c_line = 0; + (void) PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); + } + else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { + c_line = 0; + } + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + return c_line; +} +#endif + +/* CodeObjectCache */ + #if !CYTHON_COMPILING_IN_LIMITED_API +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { + int start = 0, mid = 0, end = count - 1; + if (end >= 0 && code_line > entries[end].code_line) { + return count; + } + while (start < end) { + mid = start + (end - start) / 2; + if (code_line < entries[mid].code_line) { + end = mid; + } else if (code_line > entries[mid].code_line) { + start = mid + 1; + } else { + return mid; + } + } + if (code_line <= entries[mid].code_line) { + return mid; + } else { + return mid + 1; + } +} +static PyCodeObject *__pyx_find_code_object(int code_line) { + PyCodeObject* code_object; + int pos; + if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { + return NULL; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { + return NULL; + } + code_object = __pyx_code_cache.entries[pos].code_object; + Py_INCREF(code_object); + return code_object; +} +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { + int pos, i; + __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; + if (unlikely(!code_line)) { + return; + } + if (unlikely(!entries)) { + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); + if (likely(entries)) { + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = 64; + __pyx_code_cache.count = 1; + entries[0].code_line = code_line; + entries[0].code_object = code_object; + Py_INCREF(code_object); + } + return; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { + PyCodeObject* tmp = entries[pos].code_object; + entries[pos].code_object = code_object; + Py_DECREF(tmp); + return; + } + if (__pyx_code_cache.count == __pyx_code_cache.max_count) { + int new_max = __pyx_code_cache.max_count + 64; + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( + __pyx_code_cache.entries, ((size_t)new_max) * sizeof(__Pyx_CodeObjectCacheEntry)); + if (unlikely(!entries)) { + return; + } + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = new_max; + } + for (i=__pyx_code_cache.count; i>pos; i--) { + entries[i] = entries[i-1]; + } + entries[pos].code_line = code_line; + entries[pos].code_object = code_object; + __pyx_code_cache.count++; + Py_INCREF(code_object); +} +#endif + +/* AddTraceback */ + #include "compile.h" +#include "frameobject.h" +#include "traceback.h" +#if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API + #ifndef Py_BUILD_CORE + #define Py_BUILD_CORE 1 + #endif + #include "internal/pycore_frame.h" +#endif +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject *__Pyx_PyCode_Replace_For_AddTraceback(PyObject *code, PyObject *scratch_dict, + PyObject *firstlineno, PyObject *name) { + PyObject *replace = NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "co_firstlineno", firstlineno))) return NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "co_name", name))) return NULL; + replace = PyObject_GetAttrString(code, "replace"); + if (likely(replace)) { + PyObject *result; + result = PyObject_Call(replace, __pyx_empty_tuple, scratch_dict); + Py_DECREF(replace); + return result; + } + PyErr_Clear(); + #if __PYX_LIMITED_VERSION_HEX < 0x030780000 + { + PyObject *compiled = NULL, *result = NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "code", code))) return NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "type", (PyObject*)(&PyType_Type)))) return NULL; + compiled = Py_CompileString( + "out = type(code)(\n" + " code.co_argcount, code.co_kwonlyargcount, code.co_nlocals, code.co_stacksize,\n" + " code.co_flags, code.co_code, code.co_consts, code.co_names,\n" + " code.co_varnames, code.co_filename, co_name, co_firstlineno,\n" + " code.co_lnotab)\n", "", Py_file_input); + if (!compiled) return NULL; + result = PyEval_EvalCode(compiled, scratch_dict, scratch_dict); + Py_DECREF(compiled); + if (!result) PyErr_Print(); + Py_DECREF(result); + result = PyDict_GetItemString(scratch_dict, "out"); + if (result) Py_INCREF(result); + return result; + } + #else + return NULL; + #endif +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyObject *code_object = NULL, *py_py_line = NULL, *py_funcname = NULL, *dict = NULL; + PyObject *replace = NULL, *getframe = NULL, *frame = NULL; + PyObject *exc_type, *exc_value, *exc_traceback; + int success = 0; + if (c_line) { + (void) __pyx_cfilenm; + (void) __Pyx_CLineForTraceback(__Pyx_PyThreadState_Current, c_line); + } + PyErr_Fetch(&exc_type, &exc_value, &exc_traceback); + code_object = Py_CompileString("_getframe()", filename, Py_eval_input); + if (unlikely(!code_object)) goto bad; + py_py_line = PyLong_FromLong(py_line); + if (unlikely(!py_py_line)) goto bad; + py_funcname = PyUnicode_FromString(funcname); + if (unlikely(!py_funcname)) goto bad; + dict = PyDict_New(); + if (unlikely(!dict)) goto bad; + { + PyObject *old_code_object = code_object; + code_object = __Pyx_PyCode_Replace_For_AddTraceback(code_object, dict, py_py_line, py_funcname); + Py_DECREF(old_code_object); + } + if (unlikely(!code_object)) goto bad; + getframe = PySys_GetObject("_getframe"); + if (unlikely(!getframe)) goto bad; + if (unlikely(PyDict_SetItemString(dict, "_getframe", getframe))) goto bad; + frame = PyEval_EvalCode(code_object, dict, dict); + if (unlikely(!frame) || frame == Py_None) goto bad; + success = 1; + bad: + PyErr_Restore(exc_type, exc_value, exc_traceback); + Py_XDECREF(code_object); + Py_XDECREF(py_py_line); + Py_XDECREF(py_funcname); + Py_XDECREF(dict); + Py_XDECREF(replace); + if (success) { + PyTraceBack_Here( + (struct _frame*)frame); + } + Py_XDECREF(frame); +} +#else +static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( + const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = NULL; + PyObject *py_funcname = NULL; + #if PY_MAJOR_VERSION < 3 + PyObject *py_srcfile = NULL; + py_srcfile = PyString_FromString(filename); + if (!py_srcfile) goto bad; + #endif + if (c_line) { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + if (!py_funcname) goto bad; + #else + py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + if (!py_funcname) goto bad; + funcname = PyUnicode_AsUTF8(py_funcname); + if (!funcname) goto bad; + #endif + } + else { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromString(funcname); + if (!py_funcname) goto bad; + #endif + } + #if PY_MAJOR_VERSION < 3 + py_code = __Pyx_PyCode_New( + 0, + 0, + 0, + 0, + 0, + 0, + __pyx_empty_bytes, /*PyObject *code,*/ + __pyx_empty_tuple, /*PyObject *consts,*/ + __pyx_empty_tuple, /*PyObject *names,*/ + __pyx_empty_tuple, /*PyObject *varnames,*/ + __pyx_empty_tuple, /*PyObject *freevars,*/ + __pyx_empty_tuple, /*PyObject *cellvars,*/ + py_srcfile, /*PyObject *filename,*/ + py_funcname, /*PyObject *name,*/ + py_line, + __pyx_empty_bytes /*PyObject *lnotab*/ + ); + Py_DECREF(py_srcfile); + #else + py_code = PyCode_NewEmpty(filename, funcname, py_line); + #endif + Py_XDECREF(py_funcname); + return py_code; +bad: + Py_XDECREF(py_funcname); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(py_srcfile); + #endif + return NULL; +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyFrameObject *py_frame = 0; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject *ptype, *pvalue, *ptraceback; + if (c_line) { + c_line = __Pyx_CLineForTraceback(tstate, c_line); + } + py_code = __pyx_find_code_object(c_line ? -c_line : py_line); + if (!py_code) { + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); + py_code = __Pyx_CreateCodeObjectForTraceback( + funcname, c_line, py_line, filename); + if (!py_code) { + /* If the code object creation fails, then we should clear the + fetched exception references and propagate the new exception */ + Py_XDECREF(ptype); + Py_XDECREF(pvalue); + Py_XDECREF(ptraceback); + goto bad; + } + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); + } + py_frame = PyFrame_New( + tstate, /*PyThreadState *tstate,*/ + py_code, /*PyCodeObject *code,*/ + __pyx_d, /*PyObject *globals,*/ + 0 /*PyObject *locals*/ + ); + if (!py_frame) goto bad; + __Pyx_PyFrame_SetLineNumber(py_frame, py_line); + PyTraceBack_Here(py_frame); +bad: + Py_XDECREF(py_code); + Py_XDECREF(py_frame); +} +#endif + +#if PY_MAJOR_VERSION < 3 +static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) { + __Pyx_TypeName obj_type_name; + if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags); + obj_type_name = __Pyx_PyType_GetName(Py_TYPE(obj)); + PyErr_Format(PyExc_TypeError, + "'" __Pyx_FMT_TYPENAME "' does not have the buffer interface", + obj_type_name); + __Pyx_DECREF_TypeName(obj_type_name); + return -1; +} +static void __Pyx_ReleaseBuffer(Py_buffer *view) { + PyObject *obj = view->obj; + if (!obj) return; + if (PyObject_CheckBuffer(obj)) { + PyBuffer_Release(view); + return; + } + if ((0)) {} + view->obj = NULL; + Py_DECREF(obj); +} +#endif + + + /* CIntFromPyVerify */ + #define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) +#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) +#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ + {\ + func_type value = func_value;\ + if (sizeof(target_type) < sizeof(func_type)) {\ + if (unlikely(value != (func_type) (target_type) value)) {\ + func_type zero = 0;\ + if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ + return (target_type) -1;\ + if (is_unsigned && unlikely(value < zero))\ + goto raise_neg_overflow;\ + else\ + goto raise_overflow;\ + }\ + }\ + return (target_type) value;\ + } + +/* Declarations */ + #if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) + #ifdef __cplusplus + static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { + return ::std::complex< float >(x, y); + } + #else + static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { + return x + y*(__pyx_t_float_complex)_Complex_I; + } + #endif +#else + static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { + __pyx_t_float_complex z; + z.real = x; + z.imag = y; + return z; + } +#endif + +/* Arithmetic */ + #if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) +#else + static CYTHON_INLINE int __Pyx_c_eq_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { + return (a.real == b.real) && (a.imag == b.imag); + } + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sum_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { + __pyx_t_float_complex z; + z.real = a.real + b.real; + z.imag = a.imag + b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_diff_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { + __pyx_t_float_complex z; + z.real = a.real - b.real; + z.imag = a.imag - b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prod_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { + __pyx_t_float_complex z; + z.real = a.real * b.real - a.imag * b.imag; + z.imag = a.real * b.imag + a.imag * b.real; + return z; + } + #if 1 + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quot_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { + if (b.imag == 0) { + return __pyx_t_float_complex_from_parts(a.real / b.real, a.imag / b.real); + } else if (fabsf(b.real) >= fabsf(b.imag)) { + if (b.real == 0 && b.imag == 0) { + return __pyx_t_float_complex_from_parts(a.real / b.real, a.imag / b.imag); + } else { + float r = b.imag / b.real; + float s = (float)(1.0) / (b.real + b.imag * r); + return __pyx_t_float_complex_from_parts( + (a.real + a.imag * r) * s, (a.imag - a.real * r) * s); + } + } else { + float r = b.real / b.imag; + float s = (float)(1.0) / (b.imag + b.real * r); + return __pyx_t_float_complex_from_parts( + (a.real * r + a.imag) * s, (a.imag * r - a.real) * s); + } + } + #else + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quot_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { + if (b.imag == 0) { + return __pyx_t_float_complex_from_parts(a.real / b.real, a.imag / b.real); + } else { + float denom = b.real * b.real + b.imag * b.imag; + return __pyx_t_float_complex_from_parts( + (a.real * b.real + a.imag * b.imag) / denom, + (a.imag * b.real - a.real * b.imag) / denom); + } + } + #endif + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_neg_float(__pyx_t_float_complex a) { + __pyx_t_float_complex z; + z.real = -a.real; + z.imag = -a.imag; + return z; + } + static CYTHON_INLINE int __Pyx_c_is_zero_float(__pyx_t_float_complex a) { + return (a.real == 0) && (a.imag == 0); + } + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conj_float(__pyx_t_float_complex a) { + __pyx_t_float_complex z; + z.real = a.real; + z.imag = -a.imag; + return z; + } + #if 1 + static CYTHON_INLINE float __Pyx_c_abs_float(__pyx_t_float_complex z) { + #if !defined(HAVE_HYPOT) || defined(_MSC_VER) + return sqrtf(z.real*z.real + z.imag*z.imag); + #else + return hypotf(z.real, z.imag); + #endif + } + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_pow_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { + __pyx_t_float_complex z; + float r, lnr, theta, z_r, z_theta; + if (b.imag == 0 && b.real == (int)b.real) { + if (b.real < 0) { + float denom = a.real * a.real + a.imag * a.imag; + a.real = a.real / denom; + a.imag = -a.imag / denom; + b.real = -b.real; + } + switch ((int)b.real) { + case 0: + z.real = 1; + z.imag = 0; + return z; + case 1: + return a; + case 2: + return __Pyx_c_prod_float(a, a); + case 3: + z = __Pyx_c_prod_float(a, a); + return __Pyx_c_prod_float(z, a); + case 4: + z = __Pyx_c_prod_float(a, a); + return __Pyx_c_prod_float(z, z); + } + } + if (a.imag == 0) { + if (a.real == 0) { + return a; + } else if ((b.imag == 0) && (a.real >= 0)) { + z.real = powf(a.real, b.real); + z.imag = 0; + return z; + } else if (a.real > 0) { + r = a.real; + theta = 0; + } else { + r = -a.real; + theta = atan2f(0.0, -1.0); + } + } else { + r = __Pyx_c_abs_float(a); + theta = atan2f(a.imag, a.real); + } + lnr = logf(r); + z_r = expf(lnr * b.real - theta * b.imag); + z_theta = theta * b.real + lnr * b.imag; + z.real = z_r * cosf(z_theta); + z.imag = z_r * sinf(z_theta); + return z; + } + #endif +#endif + +/* Declarations */ + #if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) + #ifdef __cplusplus + static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { + return ::std::complex< double >(x, y); + } + #else + static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { + return x + y*(__pyx_t_double_complex)_Complex_I; + } + #endif +#else + static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { + __pyx_t_double_complex z; + z.real = x; + z.imag = y; + return z; + } +#endif + +/* Arithmetic */ + #if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) +#else + static CYTHON_INLINE int __Pyx_c_eq_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + return (a.real == b.real) && (a.imag == b.imag); + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + z.real = a.real + b.real; + z.imag = a.imag + b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + z.real = a.real - b.real; + z.imag = a.imag - b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + z.real = a.real * b.real - a.imag * b.imag; + z.imag = a.real * b.imag + a.imag * b.real; + return z; + } + #if 1 + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + if (b.imag == 0) { + return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.real); + } else if (fabs(b.real) >= fabs(b.imag)) { + if (b.real == 0 && b.imag == 0) { + return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.imag); + } else { + double r = b.imag / b.real; + double s = (double)(1.0) / (b.real + b.imag * r); + return __pyx_t_double_complex_from_parts( + (a.real + a.imag * r) * s, (a.imag - a.real * r) * s); + } + } else { + double r = b.real / b.imag; + double s = (double)(1.0) / (b.imag + b.real * r); + return __pyx_t_double_complex_from_parts( + (a.real * r + a.imag) * s, (a.imag * r - a.real) * s); + } + } + #else + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + if (b.imag == 0) { + return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.real); + } else { + double denom = b.real * b.real + b.imag * b.imag; + return __pyx_t_double_complex_from_parts( + (a.real * b.real + a.imag * b.imag) / denom, + (a.imag * b.real - a.real * b.imag) / denom); + } + } + #endif + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg_double(__pyx_t_double_complex a) { + __pyx_t_double_complex z; + z.real = -a.real; + z.imag = -a.imag; + return z; + } + static CYTHON_INLINE int __Pyx_c_is_zero_double(__pyx_t_double_complex a) { + return (a.real == 0) && (a.imag == 0); + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj_double(__pyx_t_double_complex a) { + __pyx_t_double_complex z; + z.real = a.real; + z.imag = -a.imag; + return z; + } + #if 1 + static CYTHON_INLINE double __Pyx_c_abs_double(__pyx_t_double_complex z) { + #if !defined(HAVE_HYPOT) || defined(_MSC_VER) + return sqrt(z.real*z.real + z.imag*z.imag); + #else + return hypot(z.real, z.imag); + #endif + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + double r, lnr, theta, z_r, z_theta; + if (b.imag == 0 && b.real == (int)b.real) { + if (b.real < 0) { + double denom = a.real * a.real + a.imag * a.imag; + a.real = a.real / denom; + a.imag = -a.imag / denom; + b.real = -b.real; + } + switch ((int)b.real) { + case 0: + z.real = 1; + z.imag = 0; + return z; + case 1: + return a; + case 2: + return __Pyx_c_prod_double(a, a); + case 3: + z = __Pyx_c_prod_double(a, a); + return __Pyx_c_prod_double(z, a); + case 4: + z = __Pyx_c_prod_double(a, a); + return __Pyx_c_prod_double(z, z); + } + } + if (a.imag == 0) { + if (a.real == 0) { + return a; + } else if ((b.imag == 0) && (a.real >= 0)) { + z.real = pow(a.real, b.real); + z.imag = 0; + return z; + } else if (a.real > 0) { + r = a.real; + theta = 0; + } else { + r = -a.real; + theta = atan2(0.0, -1.0); + } + } else { + r = __Pyx_c_abs_double(a); + theta = atan2(a.imag, a.real); + } + lnr = log(r); + z_r = exp(lnr * b.real - theta * b.imag); + z_theta = theta * b.real + lnr * b.imag; + z.real = z_r * cos(z_theta); + z.imag = z_r * sin(z_theta); + return z; + } + #endif +#endif + +/* CIntFromPy */ + static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const int neg_one = (int) -1, const_zero = (int) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if ((sizeof(int) < sizeof(long))) { + __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (int) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + if (unlikely(__Pyx_PyLong_IsNeg(x))) { + goto raise_neg_overflow; + } else if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_DigitCount(x)) { + case 2: + if ((8 * sizeof(int) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 2 * PyLong_SHIFT)) { + return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 3: + if ((8 * sizeof(int) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 3 * PyLong_SHIFT)) { + return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 4: + if ((8 * sizeof(int) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 4 * PyLong_SHIFT)) { + return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + } + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if ((sizeof(int) <= sizeof(unsigned long))) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if ((sizeof(int) <= sizeof(unsigned PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_SignedDigitCount(x)) { + case -2: + if ((8 * sizeof(int) - 1 > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 2: + if ((8 * sizeof(int) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -3: + if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 3: + if ((8 * sizeof(int) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -4: + if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 4 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 4: + if ((8 * sizeof(int) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 4 * PyLong_SHIFT)) { + return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + } + } +#endif + if ((sizeof(int) <= sizeof(long))) { + __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if ((sizeof(int) <= sizeof(PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { + int val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); +#if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } +#endif + if (likely(v)) { + int ret = -1; +#if PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); +#else + PyObject *stepval = NULL, *mask = NULL, *shift = NULL; + int bits, remaining_bits, is_negative = 0; + long idigit; + int chunk_size = (sizeof(long) < 8) ? 30 : 62; + if (unlikely(!PyLong_CheckExact(v))) { + PyObject *tmp = v; + v = PyNumber_Long(v); + assert(PyLong_CheckExact(v)); + Py_DECREF(tmp); + if (unlikely(!v)) return (int) -1; + } +#if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + if (Py_SIZE(x) == 0) + return (int) 0; + is_negative = Py_SIZE(x) < 0; +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + is_negative = result == 1; + } +#endif + if (is_unsigned && unlikely(is_negative)) { + goto raise_neg_overflow; + } else if (is_negative) { + stepval = PyNumber_Invert(v); + if (unlikely(!stepval)) + return (int) -1; + } else { + stepval = __Pyx_NewRef(v); + } + val = (int) 0; + mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; + shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; + for (bits = 0; bits < (int) sizeof(int) * 8 - chunk_size; bits += chunk_size) { + PyObject *tmp, *digit; + digit = PyNumber_And(stepval, mask); + if (unlikely(!digit)) goto done; + idigit = PyLong_AsLong(digit); + Py_DECREF(digit); + if (unlikely(idigit < 0)) goto done; + tmp = PyNumber_Rshift(stepval, shift); + if (unlikely(!tmp)) goto done; + Py_DECREF(stepval); stepval = tmp; + val |= ((int) idigit) << bits; + #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + if (Py_SIZE(stepval) == 0) + goto unpacking_done; + #endif + } + idigit = PyLong_AsLong(stepval); + if (unlikely(idigit < 0)) goto done; + remaining_bits = ((int) sizeof(int) * 8) - bits - (is_unsigned ? 0 : 1); + if (unlikely(idigit >= (1L << remaining_bits))) + goto raise_overflow; + val |= ((int) idigit) << bits; + #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + unpacking_done: + #endif + if (!is_unsigned) { + if (unlikely(val & (((int) 1) << (sizeof(int) * 8 - 1)))) + goto raise_overflow; + if (is_negative) + val = ~val; + } + ret = 0; + done: + Py_XDECREF(shift); + Py_XDECREF(mask); + Py_XDECREF(stepval); +#endif + Py_DECREF(v); + if (likely(!ret)) + return val; + } + return (int) -1; + } + } else { + int val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (int) -1; + val = __Pyx_PyInt_As_int(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to int"); + return (int) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to int"); + return (int) -1; +} + +/* FormatTypeName */ + #if CYTHON_COMPILING_IN_LIMITED_API +static __Pyx_TypeName +__Pyx_PyType_GetName(PyTypeObject* tp) +{ + PyObject *name = __Pyx_PyObject_GetAttrStr((PyObject *)tp, + __pyx_n_s_name); + if (unlikely(name == NULL) || unlikely(!PyUnicode_Check(name))) { + PyErr_Clear(); + Py_XDECREF(name); + name = __Pyx_NewRef(__pyx_n_s__14); + } + return name; +} +#endif + +/* CIntToPy */ + static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const long neg_one = (long) -1, const_zero = (long) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(long) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(long) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(long) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; +#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030d0000 + return _PyLong_FromByteArray(bytes, sizeof(long), + little, !is_unsigned); +#else + PyObject *from_bytes, *result = NULL; + PyObject *py_bytes = NULL, *arg_tuple = NULL, *kwds = NULL, *order_str = NULL; + from_bytes = PyObject_GetAttrString((PyObject*)&PyLong_Type, "from_bytes"); + if (!from_bytes) return NULL; + py_bytes = PyBytes_FromStringAndSize((char*)bytes, sizeof(long)); + if (!py_bytes) goto limited_bad; + order_str = PyUnicode_FromString(little ? "little" : "big"); + if (!order_str) goto limited_bad; + arg_tuple = PyTuple_Pack(2, py_bytes, order_str); + if (!arg_tuple) goto limited_bad; + if (!is_unsigned) { + kwds = PyDict_New(); + if (!kwds) goto limited_bad; + if (PyDict_SetItemString(kwds, "signed", __Pyx_NewRef(Py_True))) goto limited_bad; + } + result = PyObject_Call(from_bytes, arg_tuple, kwds); + limited_bad: + Py_XDECREF(kwds); + Py_XDECREF(arg_tuple); + Py_XDECREF(order_str); + Py_XDECREF(py_bytes); + Py_XDECREF(from_bytes); + return result; +#endif + } +} + +/* CIntFromPy */ + static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const long neg_one = (long) -1, const_zero = (long) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if ((sizeof(long) < sizeof(long))) { + __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (long) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + if (unlikely(__Pyx_PyLong_IsNeg(x))) { + goto raise_neg_overflow; + } else if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_DigitCount(x)) { + case 2: + if ((8 * sizeof(long) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 2 * PyLong_SHIFT)) { + return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 3: + if ((8 * sizeof(long) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 3 * PyLong_SHIFT)) { + return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 4: + if ((8 * sizeof(long) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 4 * PyLong_SHIFT)) { + return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + } + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if ((sizeof(long) <= sizeof(unsigned long))) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if ((sizeof(long) <= sizeof(unsigned PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_SignedDigitCount(x)) { + case -2: + if ((8 * sizeof(long) - 1 > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 2: + if ((8 * sizeof(long) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -3: + if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 3: + if ((8 * sizeof(long) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -4: + if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 4 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 4: + if ((8 * sizeof(long) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 4 * PyLong_SHIFT)) { + return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + } + } +#endif + if ((sizeof(long) <= sizeof(long))) { + __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if ((sizeof(long) <= sizeof(PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { + long val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); +#if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } +#endif + if (likely(v)) { + int ret = -1; +#if PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); +#else + PyObject *stepval = NULL, *mask = NULL, *shift = NULL; + int bits, remaining_bits, is_negative = 0; + long idigit; + int chunk_size = (sizeof(long) < 8) ? 30 : 62; + if (unlikely(!PyLong_CheckExact(v))) { + PyObject *tmp = v; + v = PyNumber_Long(v); + assert(PyLong_CheckExact(v)); + Py_DECREF(tmp); + if (unlikely(!v)) return (long) -1; + } +#if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + if (Py_SIZE(x) == 0) + return (long) 0; + is_negative = Py_SIZE(x) < 0; +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + is_negative = result == 1; + } +#endif + if (is_unsigned && unlikely(is_negative)) { + goto raise_neg_overflow; + } else if (is_negative) { + stepval = PyNumber_Invert(v); + if (unlikely(!stepval)) + return (long) -1; + } else { + stepval = __Pyx_NewRef(v); + } + val = (long) 0; + mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; + shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; + for (bits = 0; bits < (int) sizeof(long) * 8 - chunk_size; bits += chunk_size) { + PyObject *tmp, *digit; + digit = PyNumber_And(stepval, mask); + if (unlikely(!digit)) goto done; + idigit = PyLong_AsLong(digit); + Py_DECREF(digit); + if (unlikely(idigit < 0)) goto done; + tmp = PyNumber_Rshift(stepval, shift); + if (unlikely(!tmp)) goto done; + Py_DECREF(stepval); stepval = tmp; + val |= ((long) idigit) << bits; + #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + if (Py_SIZE(stepval) == 0) + goto unpacking_done; + #endif + } + idigit = PyLong_AsLong(stepval); + if (unlikely(idigit < 0)) goto done; + remaining_bits = ((int) sizeof(long) * 8) - bits - (is_unsigned ? 0 : 1); + if (unlikely(idigit >= (1L << remaining_bits))) + goto raise_overflow; + val |= ((long) idigit) << bits; + #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + unpacking_done: + #endif + if (!is_unsigned) { + if (unlikely(val & (((long) 1) << (sizeof(long) * 8 - 1)))) + goto raise_overflow; + if (is_negative) + val = ~val; + } + ret = 0; + done: + Py_XDECREF(shift); + Py_XDECREF(mask); + Py_XDECREF(stepval); +#endif + Py_DECREF(v); + if (likely(!ret)) + return val; + } + return (long) -1; + } + } else { + long val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (long) -1; + val = __Pyx_PyInt_As_long(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to long"); + return (long) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to long"); + return (long) -1; +} + +/* FastTypeChecks */ + #if CYTHON_COMPILING_IN_CPYTHON +static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { + while (a) { + a = __Pyx_PyType_GetSlot(a, tp_base, PyTypeObject*); + if (a == b) + return 1; + } + return b == &PyBaseObject_Type; +} +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (a == b) return 1; + mro = a->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(a, b); +} +static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (cls == a || cls == b) return 1; + mro = cls->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + PyObject *base = PyTuple_GET_ITEM(mro, i); + if (base == (PyObject *)a || base == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(cls, a) || __Pyx_InBases(cls, b); +} +#if PY_MAJOR_VERSION == 2 +static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) { + PyObject *exception, *value, *tb; + int res; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&exception, &value, &tb); + res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0; + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + if (!res) { + res = PyObject_IsSubclass(err, exc_type2); + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + } + __Pyx_ErrRestore(exception, value, tb); + return res; +} +#else +static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { + if (exc_type1) { + return __Pyx_IsAnySubtype2((PyTypeObject*)err, (PyTypeObject*)exc_type1, (PyTypeObject*)exc_type2); + } else { + return __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); + } +} +#endif +static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + assert(PyExceptionClass_Check(exc_type)); + n = PyTuple_GET_SIZE(tuple); +#if PY_MAJOR_VERSION >= 3 + for (i=0; i= 0x030B00A4 + return Py_Version & ~0xFFUL; +#else + const char* rt_version = Py_GetVersion(); + unsigned long version = 0; + unsigned long factor = 0x01000000UL; + unsigned int digit = 0; + int i = 0; + while (factor) { + while ('0' <= rt_version[i] && rt_version[i] <= '9') { + digit = digit * 10 + (unsigned int) (rt_version[i] - '0'); + ++i; + } + version += factor * digit; + if (rt_version[i] != '.') + break; + digit = 0; + factor >>= 8; + ++i; + } + return version; +#endif +} +static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer) { + const unsigned long MAJOR_MINOR = 0xFFFF0000UL; + if ((rt_version & MAJOR_MINOR) == (ct_version & MAJOR_MINOR)) + return 0; + if (likely(allow_newer && (rt_version & MAJOR_MINOR) > (ct_version & MAJOR_MINOR))) + return 1; + { + char message[200]; + PyOS_snprintf(message, sizeof(message), + "compile time Python version %d.%d " + "of module '%.100s' " + "%s " + "runtime version %d.%d", + (int) (ct_version >> 24), (int) ((ct_version >> 16) & 0xFF), + __Pyx_MODULE_NAME, + (allow_newer) ? "was newer than" : "does not match", + (int) (rt_version >> 24), (int) ((rt_version >> 16) & 0xFF) + ); + return PyErr_WarnEx(NULL, message, 1); + } +} + +/* InitStrings */ + #if PY_MAJOR_VERSION >= 3 +static int __Pyx_InitString(__Pyx_StringTabEntry t, PyObject **str) { + if (t.is_unicode | t.is_str) { + if (t.intern) { + *str = PyUnicode_InternFromString(t.s); + } else if (t.encoding) { + *str = PyUnicode_Decode(t.s, t.n - 1, t.encoding, NULL); + } else { + *str = PyUnicode_FromStringAndSize(t.s, t.n - 1); + } + } else { + *str = PyBytes_FromStringAndSize(t.s, t.n - 1); + } + if (!*str) + return -1; + if (PyObject_Hash(*str) == -1) + return -1; + return 0; +} +#endif +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { + while (t->p) { + #if PY_MAJOR_VERSION >= 3 + __Pyx_InitString(*t, t->p); + #else + if (t->is_unicode) { + *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); + } else if (t->intern) { + *t->p = PyString_InternFromString(t->s); + } else { + *t->p = PyString_FromStringAndSize(t->s, t->n - 1); + } + if (!*t->p) + return -1; + if (PyObject_Hash(*t->p) == -1) + return -1; + #endif + ++t; + } + return 0; +} + +#include +static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s) { + size_t len = strlen(s); + if (unlikely(len > (size_t) PY_SSIZE_T_MAX)) { + PyErr_SetString(PyExc_OverflowError, "byte string is too long"); + return -1; + } + return (Py_ssize_t) len; +} +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { + Py_ssize_t len = __Pyx_ssize_strlen(c_str); + if (unlikely(len < 0)) return NULL; + return __Pyx_PyUnicode_FromStringAndSize(c_str, len); +} +static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char* c_str) { + Py_ssize_t len = __Pyx_ssize_strlen(c_str); + if (unlikely(len < 0)) return NULL; + return PyByteArray_FromStringAndSize(c_str, len); +} +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { + Py_ssize_t ignore; + return __Pyx_PyObject_AsStringAndSize(o, &ignore); +} +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +#if !CYTHON_PEP393_ENABLED +static const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + char* defenc_c; + PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); + if (!defenc) return NULL; + defenc_c = PyBytes_AS_STRING(defenc); +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + { + char* end = defenc_c + PyBytes_GET_SIZE(defenc); + char* c; + for (c = defenc_c; c < end; c++) { + if ((unsigned char) (*c) >= 128) { + PyUnicode_AsASCIIString(o); + return NULL; + } + } + } +#endif + *length = PyBytes_GET_SIZE(defenc); + return defenc_c; +} +#else +static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + if (likely(PyUnicode_IS_ASCII(o))) { + *length = PyUnicode_GET_LENGTH(o); + return PyUnicode_AsUTF8(o); + } else { + PyUnicode_AsASCIIString(o); + return NULL; + } +#else + return PyUnicode_AsUTF8AndSize(o, length); +#endif +} +#endif +#endif +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT + if ( +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + __Pyx_sys_getdefaultencoding_not_ascii && +#endif + PyUnicode_Check(o)) { + return __Pyx_PyUnicode_AsStringAndSize(o, length); + } else +#endif +#if (!CYTHON_COMPILING_IN_PYPY && !CYTHON_COMPILING_IN_LIMITED_API) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) + if (PyByteArray_Check(o)) { + *length = PyByteArray_GET_SIZE(o); + return PyByteArray_AS_STRING(o); + } else +#endif + { + char* result; + int r = PyBytes_AsStringAndSize(o, &result, length); + if (unlikely(r < 0)) { + return NULL; + } else { + return result; + } + } +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { + int is_true = x == Py_True; + if (is_true | (x == Py_False) | (x == Py_None)) return is_true; + else return PyObject_IsTrue(x); +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { + int retval; + if (unlikely(!x)) return -1; + retval = __Pyx_PyObject_IsTrue(x); + Py_DECREF(x); + return retval; +} +static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { + __Pyx_TypeName result_type_name = __Pyx_PyType_GetName(Py_TYPE(result)); +#if PY_MAJOR_VERSION >= 3 + if (PyLong_Check(result)) { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "__int__ returned non-int (type " __Pyx_FMT_TYPENAME "). " + "The ability to return an instance of a strict subclass of int is deprecated, " + "and may be removed in a future version of Python.", + result_type_name)) { + __Pyx_DECREF_TypeName(result_type_name); + Py_DECREF(result); + return NULL; + } + __Pyx_DECREF_TypeName(result_type_name); + return result; + } +#endif + PyErr_Format(PyExc_TypeError, + "__%.4s__ returned non-%.4s (type " __Pyx_FMT_TYPENAME ")", + type_name, type_name, result_type_name); + __Pyx_DECREF_TypeName(result_type_name); + Py_DECREF(result); + return NULL; +} +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { +#if CYTHON_USE_TYPE_SLOTS + PyNumberMethods *m; +#endif + const char *name = NULL; + PyObject *res = NULL; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x) || PyLong_Check(x))) +#else + if (likely(PyLong_Check(x))) +#endif + return __Pyx_NewRef(x); +#if CYTHON_USE_TYPE_SLOTS + m = Py_TYPE(x)->tp_as_number; + #if PY_MAJOR_VERSION < 3 + if (m && m->nb_int) { + name = "int"; + res = m->nb_int(x); + } + else if (m && m->nb_long) { + name = "long"; + res = m->nb_long(x); + } + #else + if (likely(m && m->nb_int)) { + name = "int"; + res = m->nb_int(x); + } + #endif +#else + if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { + res = PyNumber_Int(x); + } +#endif + if (likely(res)) { +#if PY_MAJOR_VERSION < 3 + if (unlikely(!PyInt_Check(res) && !PyLong_Check(res))) { +#else + if (unlikely(!PyLong_CheckExact(res))) { +#endif + return __Pyx_PyNumber_IntOrLongWrongResultType(res, name); + } + } + else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); + } + return res; +} +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { + Py_ssize_t ival; + PyObject *x; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(b))) { + if (sizeof(Py_ssize_t) >= sizeof(long)) + return PyInt_AS_LONG(b); + else + return PyInt_AsSsize_t(b); + } +#endif + if (likely(PyLong_CheckExact(b))) { + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(__Pyx_PyLong_IsCompact(b))) { + return __Pyx_PyLong_CompactValue(b); + } else { + const digit* digits = __Pyx_PyLong_Digits(b); + const Py_ssize_t size = __Pyx_PyLong_SignedDigitCount(b); + switch (size) { + case 2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + } + } + #endif + return PyLong_AsSsize_t(b); + } + x = PyNumber_Index(b); + if (!x) return -1; + ival = PyInt_AsSsize_t(x); + Py_DECREF(x); + return ival; +} +static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject* o) { + if (sizeof(Py_hash_t) == sizeof(Py_ssize_t)) { + return (Py_hash_t) __Pyx_PyIndex_AsSsize_t(o); +#if PY_MAJOR_VERSION < 3 + } else if (likely(PyInt_CheckExact(o))) { + return PyInt_AS_LONG(o); +#endif + } else { + Py_ssize_t ival; + PyObject *x; + x = PyNumber_Index(o); + if (!x) return -1; + ival = PyInt_AsLong(x); + Py_DECREF(x); + return ival; + } +} +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { + return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False); +} +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { + return PyInt_FromSize_t(ival); +} + + +/* #### Code section: utility_code_pragmas_end ### */ +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + + + +/* #### Code section: end ### */ +#endif /* Py_PYTHON_H */ diff --git a/src/utils/dependencies/insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.cpython-39-x86_64-linux-gnu.so b/src/utils/dependencies/insightface/thirdparty/face3d/mesh/cython/mesh_core_cython.cpython-39-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..b89b1fa30ede4aa6be1b42c0ea7d7b905d372e66 GIT binary patch literal 156864 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 np.PyArray_DATA(normal), np.PyArray_DATA(tri_normal), np.PyArray_DATA(triangles), + ntri) + +def rasterize_triangles_core( + np.ndarray[float, ndim=2, mode = "c"] vertices not None, + np.ndarray[int, ndim=2, mode="c"] triangles not None, + np.ndarray[float, ndim=2, mode = "c"] depth_buffer not None, + np.ndarray[int, ndim=2, mode = "c"] triangle_buffer not None, + np.ndarray[float, ndim=2, mode = "c"] barycentric_weight not None, + int nver, int ntri, + int h, int w + ): + _rasterize_triangles_core( + np.PyArray_DATA(vertices), np.PyArray_DATA(triangles), + np.PyArray_DATA(depth_buffer), np.PyArray_DATA(triangle_buffer), np.PyArray_DATA(barycentric_weight), + nver, ntri, + h, w) + +def render_colors_core(np.ndarray[float, ndim=3, mode = "c"] image not None, + np.ndarray[float, ndim=2, mode = "c"] vertices not None, + np.ndarray[int, ndim=2, mode="c"] triangles not None, + np.ndarray[float, ndim=2, mode = "c"] colors not None, + np.ndarray[float, ndim=2, mode = "c"] depth_buffer not None, + int nver, int ntri, + int h, int w, int c + ): + _render_colors_core( + np.PyArray_DATA(image), np.PyArray_DATA(vertices), np.PyArray_DATA(triangles), + np.PyArray_DATA(colors), + np.PyArray_DATA(depth_buffer), + nver, ntri, + h, w, c) + +def render_texture_core(np.ndarray[float, ndim=3, mode = "c"] image not None, + np.ndarray[float, ndim=2, mode = "c"] vertices not None, + np.ndarray[int, ndim=2, mode="c"] triangles not None, + np.ndarray[float, ndim=3, mode = "c"] texture not None, + np.ndarray[float, ndim=2, mode = "c"] tex_coords not None, + np.ndarray[int, ndim=2, mode="c"] tex_triangles not None, + np.ndarray[float, ndim=2, mode = "c"] depth_buffer not None, + int nver, int tex_nver, int ntri, + int h, int w, int c, + int tex_h, int tex_w, int tex_c, + int mapping_type + ): + _render_texture_core( + np.PyArray_DATA(image), np.PyArray_DATA(vertices), np.PyArray_DATA(triangles), + np.PyArray_DATA(texture), np.PyArray_DATA(tex_coords), np.PyArray_DATA(tex_triangles), + np.PyArray_DATA(depth_buffer), + nver, tex_nver, ntri, + h, w, c, + tex_h, tex_w, tex_c, + mapping_type) + +def write_obj_with_colors_texture_core(string filename, string mtl_name, + np.ndarray[float, ndim=2, mode = "c"] vertices not None, + np.ndarray[int, ndim=2, mode="c"] triangles not None, + np.ndarray[float, ndim=2, mode = "c"] colors not None, + np.ndarray[float, ndim=2, mode = "c"] uv_coords not None, + int nver, int ntri, int ntexver + ): + _write_obj_with_colors_texture(filename, mtl_name, + np.PyArray_DATA(vertices), np.PyArray_DATA(triangles), np.PyArray_DATA(colors), np.PyArray_DATA(uv_coords), + nver, ntri, ntexver) diff --git a/src/utils/dependencies/insightface/thirdparty/face3d/mesh/cython/setup.py b/src/utils/dependencies/insightface/thirdparty/face3d/mesh/cython/setup.py new file mode 100644 index 0000000..fc1ede1 --- /dev/null +++ b/src/utils/dependencies/insightface/thirdparty/face3d/mesh/cython/setup.py @@ -0,0 +1,20 @@ +''' +python setup.py build_ext -i +to compile +''' + +# setup.py +from distutils.core import setup, Extension +from Cython.Build import cythonize +from Cython.Distutils import build_ext +import numpy + +setup( + name = 'mesh_core_cython', + cmdclass={'build_ext': build_ext}, + ext_modules=[Extension("mesh_core_cython", + sources=["mesh_core_cython.pyx", "mesh_core.cpp"], + language='c++', + include_dirs=[numpy.get_include()])], +) + diff --git a/src/utils/dependencies/insightface/thirdparty/face3d/mesh/io.py b/src/utils/dependencies/insightface/thirdparty/face3d/mesh/io.py new file mode 100644 index 0000000..4bb1460 --- /dev/null +++ b/src/utils/dependencies/insightface/thirdparty/face3d/mesh/io.py @@ -0,0 +1,142 @@ +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import numpy as np +import os +from skimage import io +from time import time + +from .cython import mesh_core_cython + +## TODO +## TODO: c++ version +def read_obj(obj_name): + ''' read mesh + ''' + return 0 + +# ------------------------- write +def write_asc(path, vertices): + ''' + Args: + vertices: shape = (nver, 3) + ''' + if path.split('.')[-1] == 'asc': + np.savetxt(path, vertices) + else: + np.savetxt(path + '.asc', vertices) + +def write_obj_with_colors(obj_name, vertices, triangles, colors): + ''' Save 3D face model with texture represented by colors. + Args: + obj_name: str + vertices: shape = (nver, 3) + triangles: shape = (ntri, 3) + colors: shape = (nver, 3) + ''' + triangles = triangles.copy() + triangles += 1 # meshlab start with 1 + + if obj_name.split('.')[-1] != 'obj': + obj_name = obj_name + '.obj' + + # write obj + with open(obj_name, 'w') as f: + + # write vertices & colors + for i in range(vertices.shape[0]): + # s = 'v {} {} {} \n'.format(vertices[0,i], vertices[1,i], vertices[2,i]) + s = 'v {} {} {} {} {} {}\n'.format(vertices[i, 0], vertices[i, 1], vertices[i, 2], colors[i, 0], colors[i, 1], colors[i, 2]) + f.write(s) + + # write f: ver ind/ uv ind + [k, ntri] = triangles.shape + for i in range(triangles.shape[0]): + # s = 'f {} {} {}\n'.format(triangles[i, 0], triangles[i, 1], triangles[i, 2]) + s = 'f {} {} {}\n'.format(triangles[i, 2], triangles[i, 1], triangles[i, 0]) + f.write(s) + +## TODO: c++ version +def write_obj_with_texture(obj_name, vertices, triangles, texture, uv_coords): + ''' Save 3D face model with texture represented by texture map. + Ref: https://github.com/patrikhuber/eos/blob/bd00155ebae4b1a13b08bf5a991694d682abbada/include/eos/core/Mesh.hpp + Args: + obj_name: str + vertices: shape = (nver, 3) + triangles: shape = (ntri, 3) + texture: shape = (256,256,3) + uv_coords: shape = (nver, 3) max value<=1 + ''' + if obj_name.split('.')[-1] != 'obj': + obj_name = obj_name + '.obj' + mtl_name = obj_name.replace('.obj', '.mtl') + texture_name = obj_name.replace('.obj', '_texture.png') + + triangles = triangles.copy() + triangles += 1 # mesh lab start with 1 + + # write obj + with open(obj_name, 'w') as f: + # first line: write mtlib(material library) + s = "mtllib {}\n".format(os.path.abspath(mtl_name)) + f.write(s) + + # write vertices + for i in range(vertices.shape[0]): + s = 'v {} {} {}\n'.format(vertices[i, 0], vertices[i, 1], vertices[i, 2]) + f.write(s) + + # write uv coords + for i in range(uv_coords.shape[0]): + s = 'vt {} {}\n'.format(uv_coords[i,0], 1 - uv_coords[i,1]) + f.write(s) + + f.write("usemtl FaceTexture\n") + + # write f: ver ind/ uv ind + for i in range(triangles.shape[0]): + s = 'f {}/{} {}/{} {}/{}\n'.format(triangles[i,2], triangles[i,2], triangles[i,1], triangles[i,1], triangles[i,0], triangles[i,0]) + f.write(s) + + # write mtl + with open(mtl_name, 'w') as f: + f.write("newmtl FaceTexture\n") + s = 'map_Kd {}\n'.format(os.path.abspath(texture_name)) # map to image + f.write(s) + + # write texture as png + imsave(texture_name, texture) + +# c++ version +def write_obj_with_colors_texture(obj_name, vertices, triangles, colors, texture, uv_coords): + ''' Save 3D face model with texture. + Ref: https://github.com/patrikhuber/eos/blob/bd00155ebae4b1a13b08bf5a991694d682abbada/include/eos/core/Mesh.hpp + Args: + obj_name: str + vertices: shape = (nver, 3) + triangles: shape = (ntri, 3) + colors: shape = (nver, 3) + texture: shape = (256,256,3) + uv_coords: shape = (nver, 3) max value<=1 + ''' + if obj_name.split('.')[-1] != 'obj': + obj_name = obj_name + '.obj' + mtl_name = obj_name.replace('.obj', '.mtl') + texture_name = obj_name.replace('.obj', '_texture.png') + + triangles = triangles.copy() + triangles += 1 # mesh lab start with 1 + + # write obj + vertices, colors, uv_coords = vertices.astype(np.float32).copy(), colors.astype(np.float32).copy(), uv_coords.astype(np.float32).copy() + mesh_core_cython.write_obj_with_colors_texture_core(str.encode(obj_name), str.encode(os.path.abspath(mtl_name)), vertices, triangles, colors, uv_coords, vertices.shape[0], triangles.shape[0], uv_coords.shape[0]) + + # write mtl + with open(mtl_name, 'w') as f: + f.write("newmtl FaceTexture\n") + s = 'map_Kd {}\n'.format(os.path.abspath(texture_name)) # map to image + f.write(s) + + # write texture as png + io.imsave(texture_name, texture) \ No newline at end of file diff --git a/src/utils/dependencies/insightface/thirdparty/face3d/mesh/light.py b/src/utils/dependencies/insightface/thirdparty/face3d/mesh/light.py new file mode 100644 index 0000000..5f0da63 --- /dev/null +++ b/src/utils/dependencies/insightface/thirdparty/face3d/mesh/light.py @@ -0,0 +1,213 @@ +''' +Functions about lighting mesh(changing colors/texture of mesh). +1. add light to colors/texture (shade each vertex) +2. fit light according to colors/texture & image. +''' + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import numpy as np +from .cython import mesh_core_cython + +def get_normal(vertices, triangles): + ''' calculate normal direction in each vertex + Args: + vertices: [nver, 3] + triangles: [ntri, 3] + Returns: + normal: [nver, 3] + ''' + pt0 = vertices[triangles[:, 0], :] # [ntri, 3] + pt1 = vertices[triangles[:, 1], :] # [ntri, 3] + pt2 = vertices[triangles[:, 2], :] # [ntri, 3] + tri_normal = np.cross(pt0 - pt1, pt0 - pt2) # [ntri, 3]. normal of each triangle + + normal = np.zeros_like(vertices, dtype = np.float32).copy() # [nver, 3] + # for i in range(triangles.shape[0]): + # normal[triangles[i, 0], :] = normal[triangles[i, 0], :] + tri_normal[i, :] + # normal[triangles[i, 1], :] = normal[triangles[i, 1], :] + tri_normal[i, :] + # normal[triangles[i, 2], :] = normal[triangles[i, 2], :] + tri_normal[i, :] + mesh_core_cython.get_normal_core(normal, tri_normal.astype(np.float32).copy(), triangles.copy(), triangles.shape[0]) + + # normalize to unit length + mag = np.sum(normal**2, 1) # [nver] + zero_ind = (mag == 0) + mag[zero_ind] = 1; + normal[zero_ind, 0] = np.ones((np.sum(zero_ind))) + + normal = normal/np.sqrt(mag[:,np.newaxis]) + + return normal + +# TODO: test +def add_light_sh(vertices, triangles, colors, sh_coeff): + ''' + In 3d face, usually assume: + 1. The surface of face is Lambertian(reflect only the low frequencies of lighting) + 2. Lighting can be an arbitrary combination of point sources + --> can be expressed in terms of spherical harmonics(omit the lighting coefficients) + I = albedo * (sh(n) x sh_coeff) + + albedo: n x 1 + sh_coeff: 9 x 1 + Y(n) = (1, n_x, n_y, n_z, n_xn_y, n_xn_z, n_yn_z, n_x^2 - n_y^2, 3n_z^2 - 1)': n x 9 + # Y(n) = (1, n_x, n_y, n_z)': n x 4 + + Args: + vertices: [nver, 3] + triangles: [ntri, 3] + colors: [nver, 3] albedo + sh_coeff: [9, 1] spherical harmonics coefficients + + Returns: + lit_colors: [nver, 3] + ''' + assert vertices.shape[0] == colors.shape[0] + nver = vertices.shape[0] + normal = get_normal(vertices, triangles) # [nver, 3] + sh = np.array((np.ones(nver), n[:,0], n[:,1], n[:,2], n[:,0]*n[:,1], n[:,0]*n[:,2], n[:,1]*n[:,2], n[:,0]**2 - n[:,1]**2, 3*(n[:,2]**2) - 1)) # [nver, 9] + ref = sh.dot(sh_coeff) #[nver, 1] + lit_colors = colors*ref + return lit_colors + + +def add_light(vertices, triangles, colors, light_positions = 0, light_intensities = 0): + ''' Gouraud shading. add point lights. + In 3d face, usually assume: + 1. The surface of face is Lambertian(reflect only the low frequencies of lighting) + 2. Lighting can be an arbitrary combination of point sources + 3. No specular (unless skin is oil, 23333) + + Ref: https://cs184.eecs.berkeley.edu/lecture/pipeline + Args: + vertices: [nver, 3] + triangles: [ntri, 3] + light_positions: [nlight, 3] + light_intensities: [nlight, 3] + Returns: + lit_colors: [nver, 3] + ''' + nver = vertices.shape[0] + normals = get_normal(vertices, triangles) # [nver, 3] + + # ambient + # La = ka*Ia + + # diffuse + # Ld = kd*(I/r^2)max(0, nxl) + direction_to_lights = vertices[np.newaxis, :, :] - light_positions[:, np.newaxis, :] # [nlight, nver, 3] + direction_to_lights_n = np.sqrt(np.sum(direction_to_lights**2, axis = 2)) # [nlight, nver] + direction_to_lights = direction_to_lights/direction_to_lights_n[:, :, np.newaxis] + normals_dot_lights = normals[np.newaxis, :, :]*direction_to_lights # [nlight, nver, 3] + normals_dot_lights = np.sum(normals_dot_lights, axis = 2) # [nlight, nver] + diffuse_output = colors[np.newaxis, :, :]*normals_dot_lights[:, :, np.newaxis]*light_intensities[:, np.newaxis, :] + diffuse_output = np.sum(diffuse_output, axis = 0) # [nver, 3] + + # specular + # h = (v + l)/(|v + l|) bisector + # Ls = ks*(I/r^2)max(0, nxh)^p + # increasing p narrows the reflectionlob + + lit_colors = diffuse_output # only diffuse part here. + lit_colors = np.minimum(np.maximum(lit_colors, 0), 1) + return lit_colors + + + +## TODO. estimate light(sh coeff) +## -------------------------------- estimate. can not use now. +def fit_light(image, vertices, colors, triangles, vis_ind, lamb = 10, max_iter = 3): + [h, w, c] = image.shape + + # surface normal + norm = get_normal(vertices, triangles) + + nver = vertices.shape[1] + + # vertices --> corresponding image pixel + pt2d = vertices[:2, :] + + pt2d[0,:] = np.minimum(np.maximum(pt2d[0,:], 0), w - 1) + pt2d[1,:] = np.minimum(np.maximum(pt2d[1,:], 0), h - 1) + pt2d = np.round(pt2d).astype(np.int32) # 2 x nver + + image_pixel = image[pt2d[1,:], pt2d[0,:], :] # nver x 3 + image_pixel = image_pixel.T # 3 x nver + + # vertices --> corresponding mean texture pixel with illumination + # Spherical Harmonic Basis + harmonic_dim = 9 + nx = norm[0,:]; + ny = norm[1,:]; + nz = norm[2,:]; + harmonic = np.zeros((nver, harmonic_dim)) + + pi = np.pi + harmonic[:,0] = np.sqrt(1/(4*pi)) * np.ones((nver,)); + harmonic[:,1] = np.sqrt(3/(4*pi)) * nx; + harmonic[:,2] = np.sqrt(3/(4*pi)) * ny; + harmonic[:,3] = np.sqrt(3/(4*pi)) * nz; + harmonic[:,4] = 1/2. * np.sqrt(3/(4*pi)) * (2*nz**2 - nx**2 - ny**2); + harmonic[:,5] = 3 * np.sqrt(5/(12*pi)) * (ny*nz); + harmonic[:,6] = 3 * np.sqrt(5/(12*pi)) * (nx*nz); + harmonic[:,7] = 3 * np.sqrt(5/(12*pi)) * (nx*ny); + harmonic[:,8] = 3/2. * np.sqrt(5/(12*pi)) * (nx*nx - ny*ny); + + ''' + I' = sum(albedo * lj * hj) j = 0:9 (albedo = tex) + set A = albedo*h (n x 9) + alpha = lj (9 x 1) + Y = I (n x 1) + Y' = A.dot(alpha) + + opt function: + ||Y - A*alpha|| + lambda*(alpha'*alpha) + result: + A'*(Y - A*alpha) + lambda*alpha = 0 + ==> + (A'*A*alpha - lambda)*alpha = A'*Y + left: 9 x 9 + right: 9 x 1 + ''' + n_vis_ind = len(vis_ind) + n = n_vis_ind*c + + Y = np.zeros((n, 1)) + A = np.zeros((n, 9)) + light = np.zeros((3, 1)) + + for k in range(c): + Y[k*n_vis_ind:(k+1)*n_vis_ind, :] = image_pixel[k, vis_ind][:, np.newaxis] + A[k*n_vis_ind:(k+1)*n_vis_ind, :] = texture[k, vis_ind][:, np.newaxis] * harmonic[vis_ind, :] + Ac = texture[k, vis_ind][:, np.newaxis] + Yc = image_pixel[k, vis_ind][:, np.newaxis] + light[k] = (Ac.T.dot(Yc))/(Ac.T.dot(Ac)) + + for i in range(max_iter): + + Yc = Y.copy() + for k in range(c): + Yc[k*n_vis_ind:(k+1)*n_vis_ind, :] /= light[k] + + # update alpha + equation_left = np.dot(A.T, A) + lamb*np.eye(harmonic_dim); # why + ? + equation_right = np.dot(A.T, Yc) + alpha = np.dot(np.linalg.inv(equation_left), equation_right) + + # update light + for k in range(c): + Ac = A[k*n_vis_ind:(k+1)*n_vis_ind, :].dot(alpha) + Yc = Y[k*n_vis_ind:(k+1)*n_vis_ind, :] + light[k] = (Ac.T.dot(Yc))/(Ac.T.dot(Ac)) + + appearance = np.zeros_like(texture) + for k in range(c): + tmp = np.dot(harmonic*texture[k, :][:, np.newaxis], alpha*light[k]) + appearance[k,:] = tmp.T + + appearance = np.minimum(np.maximum(appearance, 0), 1) + + return appearance + diff --git a/src/utils/dependencies/insightface/thirdparty/face3d/mesh/render.py b/src/utils/dependencies/insightface/thirdparty/face3d/mesh/render.py new file mode 100644 index 0000000..1995722 --- /dev/null +++ b/src/utils/dependencies/insightface/thirdparty/face3d/mesh/render.py @@ -0,0 +1,135 @@ +''' +functions about rendering mesh(from 3d obj to 2d image). +only use rasterization render here. +Note that: +1. Generally, render func includes camera, light, raterize. Here no camera and light(I write these in other files) +2. Generally, the input vertices are normalized to [-1,1] and cetered on [0, 0]. (in world space) + Here, the vertices are using image coords, which centers on [w/2, h/2] with the y-axis pointing to oppisite direction. + Means: render here only conducts interpolation.(I just want to make the input flexible) + +Author: Yao Feng +Mail: yaofeng1995@gmail.com +''' +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import numpy as np +from time import time + +from .cython import mesh_core_cython + +def rasterize_triangles(vertices, triangles, h, w): + ''' + Args: + vertices: [nver, 3] + triangles: [ntri, 3] + h: height + w: width + Returns: + depth_buffer: [h, w] saves the depth, here, the bigger the z, the fronter the point. + triangle_buffer: [h, w] saves the tri id(-1 for no triangle). + barycentric_weight: [h, w, 3] saves corresponding barycentric weight. + + # Each triangle has 3 vertices & Each vertex has 3 coordinates x, y, z. + # h, w is the size of rendering + ''' + + # initial + depth_buffer = np.zeros([h, w]) - 999999. #set the initial z to the farest position + triangle_buffer = np.zeros([h, w], dtype = np.int32) - 1 # if tri id = -1, the pixel has no triangle correspondance + barycentric_weight = np.zeros([h, w, 3], dtype = np.float32) # + + vertices = vertices.astype(np.float32).copy() + triangles = triangles.astype(np.int32).copy() + + mesh_core_cython.rasterize_triangles_core( + vertices, triangles, + depth_buffer, triangle_buffer, barycentric_weight, + vertices.shape[0], triangles.shape[0], + h, w) + +def render_colors(vertices, triangles, colors, h, w, c = 3, BG = None): + ''' render mesh with colors + Args: + vertices: [nver, 3] + triangles: [ntri, 3] + colors: [nver, 3] + h: height + w: width + c: channel + BG: background image + Returns: + image: [h, w, c]. rendered image./rendering. + ''' + + # initial + if BG is None: + image = np.zeros((h, w, c), dtype = np.float32) + else: + assert BG.shape[0] == h and BG.shape[1] == w and BG.shape[2] == c + image = BG + depth_buffer = np.zeros([h, w], dtype = np.float32, order = 'C') - 999999. + + # change orders. --> C-contiguous order(column major) + vertices = vertices.astype(np.float32).copy() + triangles = triangles.astype(np.int32).copy() + colors = colors.astype(np.float32).copy() + ### + st = time() + mesh_core_cython.render_colors_core( + image, vertices, triangles, + colors, + depth_buffer, + vertices.shape[0], triangles.shape[0], + h, w, c) + return image + + +def render_texture(vertices, triangles, texture, tex_coords, tex_triangles, h, w, c = 3, mapping_type = 'nearest', BG = None): + ''' render mesh with texture map + Args: + vertices: [3, nver] + triangles: [3, ntri] + texture: [tex_h, tex_w, 3] + tex_coords: [ntexcoords, 3] + tex_triangles: [ntri, 3] + h: height of rendering + w: width of rendering + c: channel + mapping_type: 'bilinear' or 'nearest' + ''' + # initial + if BG is None: + image = np.zeros((h, w, c), dtype = np.float32) + else: + assert BG.shape[0] == h and BG.shape[1] == w and BG.shape[2] == c + image = BG + + depth_buffer = np.zeros([h, w], dtype = np.float32, order = 'C') - 999999. + + tex_h, tex_w, tex_c = texture.shape + if mapping_type == 'nearest': + mt = int(0) + elif mapping_type == 'bilinear': + mt = int(1) + else: + mt = int(0) + + # -> C order + vertices = vertices.astype(np.float32).copy() + triangles = triangles.astype(np.int32).copy() + texture = texture.astype(np.float32).copy() + tex_coords = tex_coords.astype(np.float32).copy() + tex_triangles = tex_triangles.astype(np.int32).copy() + + mesh_core_cython.render_texture_core( + image, vertices, triangles, + texture, tex_coords, tex_triangles, + depth_buffer, + vertices.shape[0], tex_coords.shape[0], triangles.shape[0], + h, w, c, + tex_h, tex_w, tex_c, + mt) + return image + diff --git a/src/utils/dependencies/insightface/thirdparty/face3d/mesh/transform.py b/src/utils/dependencies/insightface/thirdparty/face3d/mesh/transform.py new file mode 100644 index 0000000..d91b09f --- /dev/null +++ b/src/utils/dependencies/insightface/thirdparty/face3d/mesh/transform.py @@ -0,0 +1,383 @@ +''' +Functions about transforming mesh(changing the position: modify vertices). +1. forward: transform(transform, camera, project). +2. backward: estimate transform matrix from correspondences. + +Author: Yao Feng +Mail: yaofeng1995@gmail.com +''' + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import numpy as np +import math +from math import cos, sin + +def angle2matrix(angles): + ''' get rotation matrix from three rotation angles(degree). right-handed. + Args: + angles: [3,]. x, y, z angles + x: pitch. positive for looking down. + y: yaw. positive for looking left. + z: roll. positive for tilting head right. + Returns: + R: [3, 3]. rotation matrix. + ''' + x, y, z = np.deg2rad(angles[0]), np.deg2rad(angles[1]), np.deg2rad(angles[2]) + # x + Rx=np.array([[1, 0, 0], + [0, cos(x), -sin(x)], + [0, sin(x), cos(x)]]) + # y + Ry=np.array([[ cos(y), 0, sin(y)], + [ 0, 1, 0], + [-sin(y), 0, cos(y)]]) + # z + Rz=np.array([[cos(z), -sin(z), 0], + [sin(z), cos(z), 0], + [ 0, 0, 1]]) + + R=Rz.dot(Ry.dot(Rx)) + return R.astype(np.float32) + +def angle2matrix_3ddfa(angles): + ''' get rotation matrix from three rotation angles(radian). The same as in 3DDFA. + Args: + angles: [3,]. x, y, z angles + x: pitch. + y: yaw. + z: roll. + Returns: + R: 3x3. rotation matrix. + ''' + # x, y, z = np.deg2rad(angles[0]), np.deg2rad(angles[1]), np.deg2rad(angles[2]) + x, y, z = angles[0], angles[1], angles[2] + + # x + Rx=np.array([[1, 0, 0], + [0, cos(x), sin(x)], + [0, -sin(x), cos(x)]]) + # y + Ry=np.array([[ cos(y), 0, -sin(y)], + [ 0, 1, 0], + [sin(y), 0, cos(y)]]) + # z + Rz=np.array([[cos(z), sin(z), 0], + [-sin(z), cos(z), 0], + [ 0, 0, 1]]) + R = Rx.dot(Ry).dot(Rz) + return R.astype(np.float32) + + +## ------------------------------------------ 1. transform(transform, project, camera). +## ---------- 3d-3d transform. Transform obj in world space +def rotate(vertices, angles): + ''' rotate vertices. + X_new = R.dot(X). X: 3 x 1 + Args: + vertices: [nver, 3]. + rx, ry, rz: degree angles + rx: pitch. positive for looking down + ry: yaw. positive for looking left + rz: roll. positive for tilting head right + Returns: + rotated vertices: [nver, 3] + ''' + R = angle2matrix(angles) + rotated_vertices = vertices.dot(R.T) + + return rotated_vertices + +def similarity_transform(vertices, s, R, t3d): + ''' similarity transform. dof = 7. + 3D: s*R.dot(X) + t + Homo: M = [[sR, t],[0^T, 1]]. M.dot(X) + Args:(float32) + vertices: [nver, 3]. + s: [1,]. scale factor. + R: [3,3]. rotation matrix. + t3d: [3,]. 3d translation vector. + Returns: + transformed vertices: [nver, 3] + ''' + t3d = np.squeeze(np.array(t3d, dtype = np.float32)) + transformed_vertices = s * vertices.dot(R.T) + t3d[np.newaxis, :] + + return transformed_vertices + + +## -------------- Camera. from world space to camera space +# Ref: https://cs184.eecs.berkeley.edu/lecture/transforms-2 +def normalize(x): + epsilon = 1e-12 + norm = np.sqrt(np.sum(x**2, axis = 0)) + norm = np.maximum(norm, epsilon) + return x/norm + +def lookat_camera(vertices, eye, at = None, up = None): + """ 'look at' transformation: from world space to camera space + standard camera space: + camera located at the origin. + looking down negative z-axis. + vertical vector is y-axis. + Xcam = R(X - C) + Homo: [[R, -RC], [0, 1]] + Args: + vertices: [nver, 3] + eye: [3,] the XYZ world space position of the camera. + at: [3,] a position along the center of the camera's gaze. + up: [3,] up direction + Returns: + transformed_vertices: [nver, 3] + """ + if at is None: + at = np.array([0, 0, 0], np.float32) + if up is None: + up = np.array([0, 1, 0], np.float32) + + eye = np.array(eye).astype(np.float32) + at = np.array(at).astype(np.float32) + z_aixs = -normalize(at - eye) # look forward + x_aixs = normalize(np.cross(up, z_aixs)) # look right + y_axis = np.cross(z_aixs, x_aixs) # look up + + R = np.stack((x_aixs, y_axis, z_aixs))#, axis = 0) # 3 x 3 + transformed_vertices = vertices - eye # translation + transformed_vertices = transformed_vertices.dot(R.T) # rotation + return transformed_vertices + +## --------- 3d-2d project. from camera space to image plane +# generally, image plane only keeps x,y channels, here reserve z channel for calculating z-buffer. +def orthographic_project(vertices): + ''' scaled orthographic projection(just delete z) + assumes: variations in depth over the object is small relative to the mean distance from camera to object + x -> x*f/z, y -> x*f/z, z -> f. + for point i,j. zi~=zj. so just delete z + ** often used in face + Homo: P = [[1,0,0,0], [0,1,0,0], [0,0,1,0]] + Args: + vertices: [nver, 3] + Returns: + projected_vertices: [nver, 3] if isKeepZ=True. [nver, 2] if isKeepZ=False. + ''' + return vertices.copy() + +def perspective_project(vertices, fovy, aspect_ratio = 1., near = 0.1, far = 1000.): + ''' perspective projection. + Args: + vertices: [nver, 3] + fovy: vertical angular field of view. degree. + aspect_ratio : width / height of field of view + near : depth of near clipping plane + far : depth of far clipping plane + Returns: + projected_vertices: [nver, 3] + ''' + fovy = np.deg2rad(fovy) + top = near*np.tan(fovy) + bottom = -top + right = top*aspect_ratio + left = -right + + #-- homo + P = np.array([[near/right, 0, 0, 0], + [0, near/top, 0, 0], + [0, 0, -(far+near)/(far-near), -2*far*near/(far-near)], + [0, 0, -1, 0]]) + vertices_homo = np.hstack((vertices, np.ones((vertices.shape[0], 1)))) # [nver, 4] + projected_vertices = vertices_homo.dot(P.T) + projected_vertices = projected_vertices/projected_vertices[:,3:] + projected_vertices = projected_vertices[:,:3] + projected_vertices[:,2] = -projected_vertices[:,2] + + #-- non homo. only fovy + # projected_vertices = vertices.copy() + # projected_vertices[:,0] = -(near/right)*vertices[:,0]/vertices[:,2] + # projected_vertices[:,1] = -(near/top)*vertices[:,1]/vertices[:,2] + return projected_vertices + + +def to_image(vertices, h, w, is_perspective = False): + ''' change vertices to image coord system + 3d system: XYZ, center(0, 0, 0) + 2d image: x(u), y(v). center(w/2, h/2), flip y-axis. + Args: + vertices: [nver, 3] + h: height of the rendering + w : width of the rendering + Returns: + projected_vertices: [nver, 3] + ''' + image_vertices = vertices.copy() + if is_perspective: + # if perspective, the projected vertices are normalized to [-1, 1]. so change it to image size first. + image_vertices[:,0] = image_vertices[:,0]*w/2 + image_vertices[:,1] = image_vertices[:,1]*h/2 + # move to center of image + image_vertices[:,0] = image_vertices[:,0] + w/2 + image_vertices[:,1] = image_vertices[:,1] + h/2 + # flip vertices along y-axis. + image_vertices[:,1] = h - image_vertices[:,1] - 1 + return image_vertices + + +#### -------------------------------------------2. estimate transform matrix from correspondences. +def estimate_affine_matrix_3d23d(X, Y): + ''' Using least-squares solution + Args: + X: [n, 3]. 3d points(fixed) + Y: [n, 3]. corresponding 3d points(moving). Y = PX + Returns: + P_Affine: (3, 4). Affine camera matrix (the third row is [0, 0, 0, 1]). + ''' + X_homo = np.hstack((X, np.ones([X.shape[1],1]))) #n x 4 + P = np.linalg.lstsq(X_homo, Y)[0].T # Affine matrix. 3 x 4 + return P + +def estimate_affine_matrix_3d22d(X, x): + ''' Using Golden Standard Algorithm for estimating an affine camera + matrix P from world to image correspondences. + See Alg.7.2. in MVGCV + Code Ref: https://github.com/patrikhuber/eos/blob/master/include/eos/fitting/affine_camera_estimation.hpp + x_homo = X_homo.dot(P_Affine) + Args: + X: [n, 3]. corresponding 3d points(fixed) + x: [n, 2]. n>=4. 2d points(moving). x = PX + Returns: + P_Affine: [3, 4]. Affine camera matrix + ''' + X = X.T; x = x.T + assert(x.shape[1] == X.shape[1]) + n = x.shape[1] + assert(n >= 4) + + #--- 1. normalization + # 2d points + mean = np.mean(x, 1) # (2,) + x = x - np.tile(mean[:, np.newaxis], [1, n]) + average_norm = np.mean(np.sqrt(np.sum(x**2, 0))) + scale = np.sqrt(2) / average_norm + x = scale * x + + T = np.zeros((3,3), dtype = np.float32) + T[0, 0] = T[1, 1] = scale + T[:2, 2] = -mean*scale + T[2, 2] = 1 + + # 3d points + X_homo = np.vstack((X, np.ones((1, n)))) + mean = np.mean(X, 1) # (3,) + X = X - np.tile(mean[:, np.newaxis], [1, n]) + m = X_homo[:3,:] - X + average_norm = np.mean(np.sqrt(np.sum(X**2, 0))) + scale = np.sqrt(3) / average_norm + X = scale * X + + U = np.zeros((4,4), dtype = np.float32) + U[0, 0] = U[1, 1] = U[2, 2] = scale + U[:3, 3] = -mean*scale + U[3, 3] = 1 + + # --- 2. equations + A = np.zeros((n*2, 8), dtype = np.float32); + X_homo = np.vstack((X, np.ones((1, n)))).T + A[:n, :4] = X_homo + A[n:, 4:] = X_homo + b = np.reshape(x, [-1, 1]) + + # --- 3. solution + p_8 = np.linalg.pinv(A).dot(b) + P = np.zeros((3, 4), dtype = np.float32) + P[0, :] = p_8[:4, 0] + P[1, :] = p_8[4:, 0] + P[-1, -1] = 1 + + # --- 4. denormalization + P_Affine = np.linalg.inv(T).dot(P.dot(U)) + return P_Affine + +def P2sRt(P): + ''' decompositing camera matrix P + Args: + P: (3, 4). Affine Camera Matrix. + Returns: + s: scale factor. + R: (3, 3). rotation matrix. + t: (3,). translation. + ''' + t = P[:, 3] + R1 = P[0:1, :3] + R2 = P[1:2, :3] + s = (np.linalg.norm(R1) + np.linalg.norm(R2))/2.0 + r1 = R1/np.linalg.norm(R1) + r2 = R2/np.linalg.norm(R2) + r3 = np.cross(r1, r2) + + R = np.concatenate((r1, r2, r3), 0) + return s, R, t + +#Ref: https://www.learnopencv.com/rotation-matrix-to-euler-angles/ +def isRotationMatrix(R): + ''' checks if a matrix is a valid rotation matrix(whether orthogonal or not) + ''' + Rt = np.transpose(R) + shouldBeIdentity = np.dot(Rt, R) + I = np.identity(3, dtype = R.dtype) + n = np.linalg.norm(I - shouldBeIdentity) + return n < 1e-6 + +def matrix2angle(R): + ''' get three Euler angles from Rotation Matrix + Args: + R: (3,3). rotation matrix + Returns: + x: pitch + y: yaw + z: roll + ''' + assert(isRotationMatrix) + sy = math.sqrt(R[0,0] * R[0,0] + R[1,0] * R[1,0]) + + singular = sy < 1e-6 + + if not singular : + x = math.atan2(R[2,1] , R[2,2]) + y = math.atan2(-R[2,0], sy) + z = math.atan2(R[1,0], R[0,0]) + else : + x = math.atan2(-R[1,2], R[1,1]) + y = math.atan2(-R[2,0], sy) + z = 0 + + # rx, ry, rz = np.rad2deg(x), np.rad2deg(y), np.rad2deg(z) + rx, ry, rz = x*180/np.pi, y*180/np.pi, z*180/np.pi + return rx, ry, rz + +# def matrix2angle(R): +# ''' compute three Euler angles from a Rotation Matrix. Ref: http://www.gregslabaugh.net/publications/euler.pdf +# Args: +# R: (3,3). rotation matrix +# Returns: +# x: yaw +# y: pitch +# z: roll +# ''' +# # assert(isRotationMatrix(R)) + +# if R[2,0] !=1 or R[2,0] != -1: +# x = math.asin(R[2,0]) +# y = math.atan2(R[2,1]/cos(x), R[2,2]/cos(x)) +# z = math.atan2(R[1,0]/cos(x), R[0,0]/cos(x)) + +# else:# Gimbal lock +# z = 0 #can be anything +# if R[2,0] == -1: +# x = np.pi/2 +# y = z + math.atan2(R[0,1], R[0,2]) +# else: +# x = -np.pi/2 +# y = -z + math.atan2(-R[0,1], -R[0,2]) + +# return x, y, z \ No newline at end of file diff --git a/src/utils/dependencies/insightface/thirdparty/face3d/mesh/vis.py b/src/utils/dependencies/insightface/thirdparty/face3d/mesh/vis.py new file mode 100644 index 0000000..9db972f --- /dev/null +++ b/src/utils/dependencies/insightface/thirdparty/face3d/mesh/vis.py @@ -0,0 +1,24 @@ +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import numpy as np +import matplotlib.pyplot as plt +from skimage import measure +from mpl_toolkits.mplot3d import Axes3D + +def plot_mesh(vertices, triangles, subplot = [1,1,1], title = 'mesh', el = 90, az = -90, lwdt=.1, dist = 6, color = "grey"): + ''' + plot the mesh + Args: + vertices: [nver, 3] + triangles: [ntri, 3] + ''' + ax = plt.subplot(subplot[0], subplot[1], subplot[2], projection = '3d') + ax.plot_trisurf(vertices[:, 0], vertices[:, 1], vertices[:, 2], triangles = triangles, lw = lwdt, color = color, alpha = 1) + ax.axis("off") + ax.view_init(elev = el, azim = az) + ax.dist = dist + plt.title(title) + +### -------------- Todo: use vtk to visualize mesh? or visvis? or VisPy? diff --git a/src/utils/dependencies/insightface/thirdparty/face3d/mesh_numpy/__init__.py b/src/utils/dependencies/insightface/thirdparty/face3d/mesh_numpy/__init__.py new file mode 100644 index 0000000..65d5039 --- /dev/null +++ b/src/utils/dependencies/insightface/thirdparty/face3d/mesh_numpy/__init__.py @@ -0,0 +1,10 @@ +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +from . import io +from . import vis +from . import transform +from . import light +from . import render + diff --git a/src/utils/dependencies/insightface/thirdparty/face3d/mesh_numpy/io.py b/src/utils/dependencies/insightface/thirdparty/face3d/mesh_numpy/io.py new file mode 100644 index 0000000..0e48a76 --- /dev/null +++ b/src/utils/dependencies/insightface/thirdparty/face3d/mesh_numpy/io.py @@ -0,0 +1,170 @@ +''' io: read&write mesh +1. read obj as array(TODO) +2. write arrays to obj + +Preparation knowledge: +representations of 3d face: mesh, point cloud... +storage format: obj, ply, bin, asc, mat... +''' + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import numpy as np +import os +from skimage import io + +## TODO +## TODO: c++ version +def read_obj(obj_name): + ''' read mesh + ''' + return 0 + +# ------------------------- write +def write_asc(path, vertices): + ''' + Args: + vertices: shape = (nver, 3) + ''' + if path.split('.')[-1] == 'asc': + np.savetxt(path, vertices) + else: + np.savetxt(path + '.asc', vertices) + +def write_obj_with_colors(obj_name, vertices, triangles, colors): + ''' Save 3D face model with texture represented by colors. + Args: + obj_name: str + vertices: shape = (nver, 3) + triangles: shape = (ntri, 3) + colors: shape = (nver, 3) + ''' + triangles = triangles.copy() + triangles += 1 # meshlab start with 1 + + if obj_name.split('.')[-1] != 'obj': + obj_name = obj_name + '.obj' + + # write obj + with open(obj_name, 'w') as f: + + # write vertices & colors + for i in range(vertices.shape[0]): + # s = 'v {} {} {} \n'.format(vertices[0,i], vertices[1,i], vertices[2,i]) + s = 'v {} {} {} {} {} {}\n'.format(vertices[i, 0], vertices[i, 1], vertices[i, 2], colors[i, 0], colors[i, 1], colors[i, 2]) + f.write(s) + + # write f: ver ind/ uv ind + [k, ntri] = triangles.shape + for i in range(triangles.shape[0]): + # s = 'f {} {} {}\n'.format(triangles[i, 0], triangles[i, 1], triangles[i, 2]) + s = 'f {} {} {}\n'.format(triangles[i, 2], triangles[i, 1], triangles[i, 0]) + f.write(s) + +## TODO: c++ version +def write_obj_with_texture(obj_name, vertices, triangles, texture, uv_coords): + ''' Save 3D face model with texture represented by texture map. + Ref: https://github.com/patrikhuber/eos/blob/bd00155ebae4b1a13b08bf5a991694d682abbada/include/eos/core/Mesh.hpp + Args: + obj_name: str + vertices: shape = (nver, 3) + triangles: shape = (ntri, 3) + texture: shape = (256,256,3) + uv_coords: shape = (nver, 3) max value<=1 + ''' + if obj_name.split('.')[-1] != 'obj': + obj_name = obj_name + '.obj' + mtl_name = obj_name.replace('.obj', '.mtl') + texture_name = obj_name.replace('.obj', '_texture.png') + + triangles = triangles.copy() + triangles += 1 # mesh lab start with 1 + + # write obj + with open(obj_name, 'w') as f: + # first line: write mtlib(material library) + s = "mtllib {}\n".format(os.path.abspath(mtl_name)) + f.write(s) + + # write vertices + for i in range(vertices.shape[0]): + s = 'v {} {} {}\n'.format(vertices[i, 0], vertices[i, 1], vertices[i, 2]) + f.write(s) + + # write uv coords + for i in range(uv_coords.shape[0]): + # s = 'vt {} {}\n'.format(uv_coords[i,0], 1 - uv_coords[i,1]) + s = 'vt {} {}\n'.format(uv_coords[i,0], uv_coords[i,1]) + f.write(s) + + f.write("usemtl FaceTexture\n") + + # write f: ver ind/ uv ind + for i in range(triangles.shape[0]): + s = 'f {}/{} {}/{} {}/{}\n'.format(triangles[i,2], triangles[i,2], triangles[i,1], triangles[i,1], triangles[i,0], triangles[i,0]) + f.write(s) + + # write mtl + with open(mtl_name, 'w') as f: + f.write("newmtl FaceTexture\n") + s = 'map_Kd {}\n'.format(os.path.abspath(texture_name)) # map to image + f.write(s) + + # write texture as png + imsave(texture_name, texture) + + +def write_obj_with_colors_texture(obj_name, vertices, triangles, colors, texture, uv_coords): + ''' Save 3D face model with texture. + Ref: https://github.com/patrikhuber/eos/blob/bd00155ebae4b1a13b08bf5a991694d682abbada/include/eos/core/Mesh.hpp + Args: + obj_name: str + vertices: shape = (nver, 3) + triangles: shape = (ntri, 3) + colors: shape = (nver, 3) + texture: shape = (256,256,3) + uv_coords: shape = (nver, 3) max value<=1 + ''' + if obj_name.split('.')[-1] != 'obj': + obj_name = obj_name + '.obj' + mtl_name = obj_name.replace('.obj', '.mtl') + texture_name = obj_name.replace('.obj', '_texture.png') + + triangles = triangles.copy() + triangles += 1 # mesh lab start with 1 + + # write obj + with open(obj_name, 'w') as f: + # first line: write mtlib(material library) + s = "mtllib {}\n".format(os.path.abspath(mtl_name)) + f.write(s) + + # write vertices + for i in range(vertices.shape[0]): + s = 'v {} {} {} {} {} {}\n'.format(vertices[i, 0], vertices[i, 1], vertices[i, 2], colors[i, 0], colors[i, 1], colors[i, 2]) + f.write(s) + + # write uv coords + for i in range(uv_coords.shape[0]): + # s = 'vt {} {}\n'.format(uv_coords[i,0], 1 - uv_coords[i,1]) + s = 'vt {} {}\n'.format(uv_coords[i,0], uv_coords[i,1]) + f.write(s) + + f.write("usemtl FaceTexture\n") + + # write f: ver ind/ uv ind + for i in range(triangles.shape[0]): + # s = 'f {}/{} {}/{} {}/{}\n'.format(triangles[i,0], triangles[i,0], triangles[i,1], triangles[i,1], triangles[i,2], triangles[i,2]) + s = 'f {}/{} {}/{} {}/{}\n'.format(triangles[i,2], triangles[i,2], triangles[i,1], triangles[i,1], triangles[i,0], triangles[i,0]) + f.write(s) + + # write mtl + with open(mtl_name, 'w') as f: + f.write("newmtl FaceTexture\n") + s = 'map_Kd {}\n'.format(os.path.abspath(texture_name)) # map to image + f.write(s) + + # write texture as png + io.imsave(texture_name, texture) \ No newline at end of file diff --git a/src/utils/dependencies/insightface/thirdparty/face3d/mesh_numpy/light.py b/src/utils/dependencies/insightface/thirdparty/face3d/mesh_numpy/light.py new file mode 100644 index 0000000..bde5711 --- /dev/null +++ b/src/utils/dependencies/insightface/thirdparty/face3d/mesh_numpy/light.py @@ -0,0 +1,215 @@ +''' +Functions about lighting mesh(changing colors/texture of mesh). +1. add light to colors/texture (shade each vertex) +2. fit light according to colors/texture & image. + +Preparation knowledge: +lighting: https://cs184.eecs.berkeley.edu/lecture/pipeline +spherical harmonics in human face: '3D Face Reconstruction from a Single Image Using a Single Reference Face Shape' +''' + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import numpy as np + +def get_normal(vertices, triangles): + ''' calculate normal direction in each vertex + Args: + vertices: [nver, 3] + triangles: [ntri, 3] + Returns: + normal: [nver, 3] + ''' + pt0 = vertices[triangles[:, 0], :] # [ntri, 3] + pt1 = vertices[triangles[:, 1], :] # [ntri, 3] + pt2 = vertices[triangles[:, 2], :] # [ntri, 3] + tri_normal = np.cross(pt0 - pt1, pt0 - pt2) # [ntri, 3]. normal of each triangle + + normal = np.zeros_like(vertices) # [nver, 3] + for i in range(triangles.shape[0]): + normal[triangles[i, 0], :] = normal[triangles[i, 0], :] + tri_normal[i, :] + normal[triangles[i, 1], :] = normal[triangles[i, 1], :] + tri_normal[i, :] + normal[triangles[i, 2], :] = normal[triangles[i, 2], :] + tri_normal[i, :] + + # normalize to unit length + mag = np.sum(normal**2, 1) # [nver] + zero_ind = (mag == 0) + mag[zero_ind] = 1; + normal[zero_ind, 0] = np.ones((np.sum(zero_ind))) + + normal = normal/np.sqrt(mag[:,np.newaxis]) + + return normal + +# TODO: test +def add_light_sh(vertices, triangles, colors, sh_coeff): + ''' + In 3d face, usually assume: + 1. The surface of face is Lambertian(reflect only the low frequencies of lighting) + 2. Lighting can be an arbitrary combination of point sources + --> can be expressed in terms of spherical harmonics(omit the lighting coefficients) + I = albedo * (sh(n) x sh_coeff) + + albedo: n x 1 + sh_coeff: 9 x 1 + Y(n) = (1, n_x, n_y, n_z, n_xn_y, n_xn_z, n_yn_z, n_x^2 - n_y^2, 3n_z^2 - 1)': n x 9 + # Y(n) = (1, n_x, n_y, n_z)': n x 4 + + Args: + vertices: [nver, 3] + triangles: [ntri, 3] + colors: [nver, 3] albedo + sh_coeff: [9, 1] spherical harmonics coefficients + + Returns: + lit_colors: [nver, 3] + ''' + assert vertices.shape[0] == colors.shape[0] + nver = vertices.shape[0] + normal = get_normal(vertices, triangles) # [nver, 3] + sh = np.array((np.ones(nver), n[:,0], n[:,1], n[:,2], n[:,0]*n[:,1], n[:,0]*n[:,2], n[:,1]*n[:,2], n[:,0]**2 - n[:,1]**2, 3*(n[:,2]**2) - 1)) # [nver, 9] + ref = sh.dot(sh_coeff) #[nver, 1] + lit_colors = colors*ref + return lit_colors + + +def add_light(vertices, triangles, colors, light_positions = 0, light_intensities = 0): + ''' Gouraud shading. add point lights. + In 3d face, usually assume: + 1. The surface of face is Lambertian(reflect only the low frequencies of lighting) + 2. Lighting can be an arbitrary combination of point sources + 3. No specular (unless skin is oil, 23333) + + Ref: https://cs184.eecs.berkeley.edu/lecture/pipeline + Args: + vertices: [nver, 3] + triangles: [ntri, 3] + light_positions: [nlight, 3] + light_intensities: [nlight, 3] + Returns: + lit_colors: [nver, 3] + ''' + nver = vertices.shape[0] + normals = get_normal(vertices, triangles) # [nver, 3] + + # ambient + # La = ka*Ia + + # diffuse + # Ld = kd*(I/r^2)max(0, nxl) + direction_to_lights = vertices[np.newaxis, :, :] - light_positions[:, np.newaxis, :] # [nlight, nver, 3] + direction_to_lights_n = np.sqrt(np.sum(direction_to_lights**2, axis = 2)) # [nlight, nver] + direction_to_lights = direction_to_lights/direction_to_lights_n[:, :, np.newaxis] + normals_dot_lights = normals[np.newaxis, :, :]*direction_to_lights # [nlight, nver, 3] + normals_dot_lights = np.sum(normals_dot_lights, axis = 2) # [nlight, nver] + diffuse_output = colors[np.newaxis, :, :]*normals_dot_lights[:, :, np.newaxis]*light_intensities[:, np.newaxis, :] + diffuse_output = np.sum(diffuse_output, axis = 0) # [nver, 3] + + # specular + # h = (v + l)/(|v + l|) bisector + # Ls = ks*(I/r^2)max(0, nxh)^p + # increasing p narrows the reflectionlob + + lit_colors = diffuse_output # only diffuse part here. + lit_colors = np.minimum(np.maximum(lit_colors, 0), 1) + return lit_colors + + + +## TODO. estimate light(sh coeff) +## -------------------------------- estimate. can not use now. +def fit_light(image, vertices, colors, triangles, vis_ind, lamb = 10, max_iter = 3): + [h, w, c] = image.shape + + # surface normal + norm = get_normal(vertices, triangles) + + nver = vertices.shape[1] + + # vertices --> corresponding image pixel + pt2d = vertices[:2, :] + + pt2d[0,:] = np.minimum(np.maximum(pt2d[0,:], 0), w - 1) + pt2d[1,:] = np.minimum(np.maximum(pt2d[1,:], 0), h - 1) + pt2d = np.round(pt2d).astype(np.int32) # 2 x nver + + image_pixel = image[pt2d[1,:], pt2d[0,:], :] # nver x 3 + image_pixel = image_pixel.T # 3 x nver + + # vertices --> corresponding mean texture pixel with illumination + # Spherical Harmonic Basis + harmonic_dim = 9 + nx = norm[0,:]; + ny = norm[1,:]; + nz = norm[2,:]; + harmonic = np.zeros((nver, harmonic_dim)) + + pi = np.pi + harmonic[:,0] = np.sqrt(1/(4*pi)) * np.ones((nver,)); + harmonic[:,1] = np.sqrt(3/(4*pi)) * nx; + harmonic[:,2] = np.sqrt(3/(4*pi)) * ny; + harmonic[:,3] = np.sqrt(3/(4*pi)) * nz; + harmonic[:,4] = 1/2. * np.sqrt(3/(4*pi)) * (2*nz**2 - nx**2 - ny**2); + harmonic[:,5] = 3 * np.sqrt(5/(12*pi)) * (ny*nz); + harmonic[:,6] = 3 * np.sqrt(5/(12*pi)) * (nx*nz); + harmonic[:,7] = 3 * np.sqrt(5/(12*pi)) * (nx*ny); + harmonic[:,8] = 3/2. * np.sqrt(5/(12*pi)) * (nx*nx - ny*ny); + + ''' + I' = sum(albedo * lj * hj) j = 0:9 (albedo = tex) + set A = albedo*h (n x 9) + alpha = lj (9 x 1) + Y = I (n x 1) + Y' = A.dot(alpha) + + opt function: + ||Y - A*alpha|| + lambda*(alpha'*alpha) + result: + A'*(Y - A*alpha) + lambda*alpha = 0 + ==> + (A'*A*alpha - lambda)*alpha = A'*Y + left: 9 x 9 + right: 9 x 1 + ''' + n_vis_ind = len(vis_ind) + n = n_vis_ind*c + + Y = np.zeros((n, 1)) + A = np.zeros((n, 9)) + light = np.zeros((3, 1)) + + for k in range(c): + Y[k*n_vis_ind:(k+1)*n_vis_ind, :] = image_pixel[k, vis_ind][:, np.newaxis] + A[k*n_vis_ind:(k+1)*n_vis_ind, :] = texture[k, vis_ind][:, np.newaxis] * harmonic[vis_ind, :] + Ac = texture[k, vis_ind][:, np.newaxis] + Yc = image_pixel[k, vis_ind][:, np.newaxis] + light[k] = (Ac.T.dot(Yc))/(Ac.T.dot(Ac)) + + for i in range(max_iter): + + Yc = Y.copy() + for k in range(c): + Yc[k*n_vis_ind:(k+1)*n_vis_ind, :] /= light[k] + + # update alpha + equation_left = np.dot(A.T, A) + lamb*np.eye(harmonic_dim); # why + ? + equation_right = np.dot(A.T, Yc) + alpha = np.dot(np.linalg.inv(equation_left), equation_right) + + # update light + for k in range(c): + Ac = A[k*n_vis_ind:(k+1)*n_vis_ind, :].dot(alpha) + Yc = Y[k*n_vis_ind:(k+1)*n_vis_ind, :] + light[k] = (Ac.T.dot(Yc))/(Ac.T.dot(Ac)) + + appearance = np.zeros_like(texture) + for k in range(c): + tmp = np.dot(harmonic*texture[k, :][:, np.newaxis], alpha*light[k]) + appearance[k,:] = tmp.T + + appearance = np.minimum(np.maximum(appearance, 0), 1) + + return appearance + diff --git a/src/utils/dependencies/insightface/thirdparty/face3d/mesh_numpy/render.py b/src/utils/dependencies/insightface/thirdparty/face3d/mesh_numpy/render.py new file mode 100644 index 0000000..eb0d92d --- /dev/null +++ b/src/utils/dependencies/insightface/thirdparty/face3d/mesh_numpy/render.py @@ -0,0 +1,287 @@ +''' +functions about rendering mesh(from 3d obj to 2d image). +only use rasterization render here. +Note that: +1. Generally, render func includes camera, light, raterize. Here no camera and light(I write these in other files) +2. Generally, the input vertices are normalized to [-1,1] and cetered on [0, 0]. (in world space) + Here, the vertices are using image coords, which centers on [w/2, h/2] with the y-axis pointing to oppisite direction. +Means: render here only conducts interpolation.(I just want to make the input flexible) + +Preparation knowledge: +z-buffer: https://cs184.eecs.berkeley.edu/lecture/pipeline + +Author: Yao Feng +Mail: yaofeng1995@gmail.com +''' +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import numpy as np +from time import time + +def isPointInTri(point, tri_points): + ''' Judge whether the point is in the triangle + Method: + http://blackpawn.com/texts/pointinpoly/ + Args: + point: (2,). [u, v] or [x, y] + tri_points: (3 vertices, 2 coords). three vertices(2d points) of a triangle. + Returns: + bool: true for in triangle + ''' + tp = tri_points + + # vectors + v0 = tp[2,:] - tp[0,:] + v1 = tp[1,:] - tp[0,:] + v2 = point - tp[0,:] + + # dot products + dot00 = np.dot(v0.T, v0) + dot01 = np.dot(v0.T, v1) + dot02 = np.dot(v0.T, v2) + dot11 = np.dot(v1.T, v1) + dot12 = np.dot(v1.T, v2) + + # barycentric coordinates + if dot00*dot11 - dot01*dot01 == 0: + inverDeno = 0 + else: + inverDeno = 1/(dot00*dot11 - dot01*dot01) + + u = (dot11*dot02 - dot01*dot12)*inverDeno + v = (dot00*dot12 - dot01*dot02)*inverDeno + + # check if point in triangle + return (u >= 0) & (v >= 0) & (u + v < 1) + +def get_point_weight(point, tri_points): + ''' Get the weights of the position + Methods: https://gamedev.stackexchange.com/questions/23743/whats-the-most-efficient-way-to-find-barycentric-coordinates + -m1.compute the area of the triangles formed by embedding the point P inside the triangle + -m2.Christer Ericson's book "Real-Time Collision Detection". faster.(used) + Args: + point: (2,). [u, v] or [x, y] + tri_points: (3 vertices, 2 coords). three vertices(2d points) of a triangle. + Returns: + w0: weight of v0 + w1: weight of v1 + w2: weight of v3 + ''' + tp = tri_points + # vectors + v0 = tp[2,:] - tp[0,:] + v1 = tp[1,:] - tp[0,:] + v2 = point - tp[0,:] + + # dot products + dot00 = np.dot(v0.T, v0) + dot01 = np.dot(v0.T, v1) + dot02 = np.dot(v0.T, v2) + dot11 = np.dot(v1.T, v1) + dot12 = np.dot(v1.T, v2) + + # barycentric coordinates + if dot00*dot11 - dot01*dot01 == 0: + inverDeno = 0 + else: + inverDeno = 1/(dot00*dot11 - dot01*dot01) + + u = (dot11*dot02 - dot01*dot12)*inverDeno + v = (dot00*dot12 - dot01*dot02)*inverDeno + + w0 = 1 - u - v + w1 = v + w2 = u + + return w0, w1, w2 + +def rasterize_triangles(vertices, triangles, h, w): + ''' + Args: + vertices: [nver, 3] + triangles: [ntri, 3] + h: height + w: width + Returns: + depth_buffer: [h, w] saves the depth, here, the bigger the z, the fronter the point. + triangle_buffer: [h, w] saves the tri id(-1 for no triangle). + barycentric_weight: [h, w, 3] saves corresponding barycentric weight. + + # Each triangle has 3 vertices & Each vertex has 3 coordinates x, y, z. + # h, w is the size of rendering + ''' + # initial + depth_buffer = np.zeros([h, w]) - 999999. #+ np.min(vertices[2,:]) - 999999. # set the initial z to the farest position + triangle_buffer = np.zeros([h, w], dtype = np.int32) - 1 # if tri id = -1, the pixel has no triangle correspondance + barycentric_weight = np.zeros([h, w, 3], dtype = np.float32) # + + for i in range(triangles.shape[0]): + tri = triangles[i, :] # 3 vertex indices + + # the inner bounding box + umin = max(int(np.ceil(np.min(vertices[tri, 0]))), 0) + umax = min(int(np.floor(np.max(vertices[tri, 0]))), w-1) + + vmin = max(int(np.ceil(np.min(vertices[tri, 1]))), 0) + vmax = min(int(np.floor(np.max(vertices[tri, 1]))), h-1) + + if umax depth_buffer[v, u]: + depth_buffer[v, u] = point_depth + triangle_buffer[v, u] = i + barycentric_weight[v, u, :] = np.array([w0, w1, w2]) + + return depth_buffer, triangle_buffer, barycentric_weight + + +def render_colors_ras(vertices, triangles, colors, h, w, c = 3): + ''' render mesh with colors(rasterize triangle first) + Args: + vertices: [nver, 3] + triangles: [ntri, 3] + colors: [nver, 3] + h: height + w: width + c: channel + Returns: + image: [h, w, c]. rendering. + ''' + assert vertices.shape[0] == colors.shape[0] + + depth_buffer, triangle_buffer, barycentric_weight = rasterize_triangles(vertices, triangles, h, w) + + triangle_buffer_flat = np.reshape(triangle_buffer, [-1]) # [h*w] + barycentric_weight_flat = np.reshape(barycentric_weight, [-1, c]) #[h*w, c] + weight = barycentric_weight_flat[:, :, np.newaxis] # [h*w, 3(ver in tri), 1] + + colors_flat = colors[triangles[triangle_buffer_flat, :], :] # [h*w(tri id in pixel), 3(ver in tri), c(color in ver)] + colors_flat = weight*colors_flat # [h*w, 3, 3] + colors_flat = np.sum(colors_flat, 1) #[h*w, 3]. add tri. + + image = np.reshape(colors_flat, [h, w, c]) + # mask = (triangle_buffer[:,:] > -1).astype(np.float32) + # image = image*mask[:,:,np.newaxis] + return image + + +def render_colors(vertices, triangles, colors, h, w, c = 3): + ''' render mesh with colors + Args: + vertices: [nver, 3] + triangles: [ntri, 3] + colors: [nver, 3] + h: height + w: width + Returns: + image: [h, w, c]. + ''' + assert vertices.shape[0] == colors.shape[0] + + # initial + image = np.zeros((h, w, c)) + depth_buffer = np.zeros([h, w]) - 999999. + + for i in range(triangles.shape[0]): + tri = triangles[i, :] # 3 vertex indices + + # the inner bounding box + umin = max(int(np.ceil(np.min(vertices[tri, 0]))), 0) + umax = min(int(np.floor(np.max(vertices[tri, 0]))), w-1) + + vmin = max(int(np.ceil(np.min(vertices[tri, 1]))), 0) + vmax = min(int(np.floor(np.max(vertices[tri, 1]))), h-1) + + if umax depth_buffer[v, u]: + depth_buffer[v, u] = point_depth + image[v, u, :] = w0*colors[tri[0], :] + w1*colors[tri[1], :] + w2*colors[tri[2], :] + return image + + +def render_texture(vertices, triangles, texture, tex_coords, tex_triangles, h, w, c = 3, mapping_type = 'nearest'): + ''' render mesh with texture map + Args: + vertices: [nver], 3 + triangles: [ntri, 3] + texture: [tex_h, tex_w, 3] + tex_coords: [ntexcoords, 3] + tex_triangles: [ntri, 3] + h: height of rendering + w: width of rendering + c: channel + mapping_type: 'bilinear' or 'nearest' + ''' + assert triangles.shape[0] == tex_triangles.shape[0] + tex_h, tex_w, _ = texture.shape + + # initial + image = np.zeros((h, w, c)) + depth_buffer = np.zeros([h, w]) - 999999. + + for i in range(triangles.shape[0]): + tri = triangles[i, :] # 3 vertex indices + tex_tri = tex_triangles[i, :] # 3 tex indice + + # the inner bounding box + umin = max(int(np.ceil(np.min(vertices[tri, 0]))), 0) + umax = min(int(np.floor(np.max(vertices[tri, 0]))), w-1) + + vmin = max(int(np.ceil(np.min(vertices[tri, 1]))), 0) + vmax = min(int(np.floor(np.max(vertices[tri, 1]))), h-1) + + if umax depth_buffer[v, u]: + # update depth + depth_buffer[v, u] = point_depth + + # tex coord + tex_xy = w0*tex_coords[tex_tri[0], :] + w1*tex_coords[tex_tri[1], :] + w2*tex_coords[tex_tri[2], :] + tex_xy[0] = max(min(tex_xy[0], float(tex_w - 1)), 0.0); + tex_xy[1] = max(min(tex_xy[1], float(tex_h - 1)), 0.0); + + # nearest + if mapping_type == 'nearest': + tex_xy = np.round(tex_xy).astype(np.int32) + tex_value = texture[tex_xy[1], tex_xy[0], :] + + # bilinear + elif mapping_type == 'bilinear': + # next 4 pixels + ul = texture[int(np.floor(tex_xy[1])), int(np.floor(tex_xy[0])), :] + ur = texture[int(np.floor(tex_xy[1])), int(np.ceil(tex_xy[0])), :] + dl = texture[int(np.ceil(tex_xy[1])), int(np.floor(tex_xy[0])), :] + dr = texture[int(np.ceil(tex_xy[1])), int(np.ceil(tex_xy[0])), :] + + yd = tex_xy[1] - np.floor(tex_xy[1]) + xd = tex_xy[0] - np.floor(tex_xy[0]) + tex_value = ul*(1-xd)*(1-yd) + ur*xd*(1-yd) + dl*(1-xd)*yd + dr*xd*yd + + image[v, u, :] = tex_value + return image \ No newline at end of file diff --git a/src/utils/dependencies/insightface/thirdparty/face3d/mesh_numpy/transform.py b/src/utils/dependencies/insightface/thirdparty/face3d/mesh_numpy/transform.py new file mode 100644 index 0000000..ab56e37 --- /dev/null +++ b/src/utils/dependencies/insightface/thirdparty/face3d/mesh_numpy/transform.py @@ -0,0 +1,385 @@ +''' +Functions about transforming mesh(changing the position: modify vertices). +1. forward: transform(transform, camera, project). +2. backward: estimate transform matrix from correspondences. + +Preparation knowledge: +transform&camera model: +https://cs184.eecs.berkeley.edu/lecture/transforms-2 +Part I: camera geometry and single view geometry in MVGCV +''' + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import numpy as np +import math +from math import cos, sin + +def angle2matrix(angles): + ''' get rotation matrix from three rotation angles(degree). right-handed. + Args: + angles: [3,]. x, y, z angles + x: pitch. positive for looking down. + y: yaw. positive for looking left. + z: roll. positive for tilting head right. + Returns: + R: [3, 3]. rotation matrix. + ''' + x, y, z = np.deg2rad(angles[0]), np.deg2rad(angles[1]), np.deg2rad(angles[2]) + # x + Rx=np.array([[1, 0, 0], + [0, cos(x), -sin(x)], + [0, sin(x), cos(x)]]) + # y + Ry=np.array([[ cos(y), 0, sin(y)], + [ 0, 1, 0], + [-sin(y), 0, cos(y)]]) + # z + Rz=np.array([[cos(z), -sin(z), 0], + [sin(z), cos(z), 0], + [ 0, 0, 1]]) + + R=Rz.dot(Ry.dot(Rx)) + return R.astype(np.float32) + +def angle2matrix_3ddfa(angles): + ''' get rotation matrix from three rotation angles(radian). The same as in 3DDFA. + Args: + angles: [3,]. x, y, z angles + x: pitch. + y: yaw. + z: roll. + Returns: + R: 3x3. rotation matrix. + ''' + # x, y, z = np.deg2rad(angles[0]), np.deg2rad(angles[1]), np.deg2rad(angles[2]) + x, y, z = angles[0], angles[1], angles[2] + + # x + Rx=np.array([[1, 0, 0], + [0, cos(x), sin(x)], + [0, -sin(x), cos(x)]]) + # y + Ry=np.array([[ cos(y), 0, -sin(y)], + [ 0, 1, 0], + [sin(y), 0, cos(y)]]) + # z + Rz=np.array([[cos(z), sin(z), 0], + [-sin(z), cos(z), 0], + [ 0, 0, 1]]) + R = Rx.dot(Ry).dot(Rz) + return R.astype(np.float32) + + +## ------------------------------------------ 1. transform(transform, project, camera). +## ---------- 3d-3d transform. Transform obj in world space +def rotate(vertices, angles): + ''' rotate vertices. + X_new = R.dot(X). X: 3 x 1 + Args: + vertices: [nver, 3]. + rx, ry, rz: degree angles + rx: pitch. positive for looking down + ry: yaw. positive for looking left + rz: roll. positive for tilting head right + Returns: + rotated vertices: [nver, 3] + ''' + R = angle2matrix(angles) + rotated_vertices = vertices.dot(R.T) + + return rotated_vertices + +def similarity_transform(vertices, s, R, t3d): + ''' similarity transform. dof = 7. + 3D: s*R.dot(X) + t + Homo: M = [[sR, t],[0^T, 1]]. M.dot(X) + Args:(float32) + vertices: [nver, 3]. + s: [1,]. scale factor. + R: [3,3]. rotation matrix. + t3d: [3,]. 3d translation vector. + Returns: + transformed vertices: [nver, 3] + ''' + t3d = np.squeeze(np.array(t3d, dtype = np.float32)) + transformed_vertices = s * vertices.dot(R.T) + t3d[np.newaxis, :] + + return transformed_vertices + + +## -------------- Camera. from world space to camera space +# Ref: https://cs184.eecs.berkeley.edu/lecture/transforms-2 +def normalize(x): + epsilon = 1e-12 + norm = np.sqrt(np.sum(x**2, axis = 0)) + norm = np.maximum(norm, epsilon) + return x/norm + +def lookat_camera(vertices, eye, at = None, up = None): + """ 'look at' transformation: from world space to camera space + standard camera space: + camera located at the origin. + looking down negative z-axis. + vertical vector is y-axis. + Xcam = R(X - C) + Homo: [[R, -RC], [0, 1]] + Args: + vertices: [nver, 3] + eye: [3,] the XYZ world space position of the camera. + at: [3,] a position along the center of the camera's gaze. + up: [3,] up direction + Returns: + transformed_vertices: [nver, 3] + """ + if at is None: + at = np.array([0, 0, 0], np.float32) + if up is None: + up = np.array([0, 1, 0], np.float32) + + eye = np.array(eye).astype(np.float32) + at = np.array(at).astype(np.float32) + z_aixs = -normalize(at - eye) # look forward + x_aixs = normalize(np.cross(up, z_aixs)) # look right + y_axis = np.cross(z_aixs, x_aixs) # look up + + R = np.stack((x_aixs, y_axis, z_aixs))#, axis = 0) # 3 x 3 + transformed_vertices = vertices - eye # translation + transformed_vertices = transformed_vertices.dot(R.T) # rotation + return transformed_vertices + +## --------- 3d-2d project. from camera space to image plane +# generally, image plane only keeps x,y channels, here reserve z channel for calculating z-buffer. +def orthographic_project(vertices): + ''' scaled orthographic projection(just delete z) + assumes: variations in depth over the object is small relative to the mean distance from camera to object + x -> x*f/z, y -> x*f/z, z -> f. + for point i,j. zi~=zj. so just delete z + ** often used in face + Homo: P = [[1,0,0,0], [0,1,0,0], [0,0,1,0]] + Args: + vertices: [nver, 3] + Returns: + projected_vertices: [nver, 3] if isKeepZ=True. [nver, 2] if isKeepZ=False. + ''' + return vertices.copy() + +def perspective_project(vertices, fovy, aspect_ratio = 1., near = 0.1, far = 1000.): + ''' perspective projection. + Args: + vertices: [nver, 3] + fovy: vertical angular field of view. degree. + aspect_ratio : width / height of field of view + near : depth of near clipping plane + far : depth of far clipping plane + Returns: + projected_vertices: [nver, 3] + ''' + fovy = np.deg2rad(fovy) + top = near*np.tan(fovy) + bottom = -top + right = top*aspect_ratio + left = -right + + #-- homo + P = np.array([[near/right, 0, 0, 0], + [0, near/top, 0, 0], + [0, 0, -(far+near)/(far-near), -2*far*near/(far-near)], + [0, 0, -1, 0]]) + vertices_homo = np.hstack((vertices, np.ones((vertices.shape[0], 1)))) # [nver, 4] + projected_vertices = vertices_homo.dot(P.T) + projected_vertices = projected_vertices/projected_vertices[:,3:] + projected_vertices = projected_vertices[:,:3] + projected_vertices[:,2] = -projected_vertices[:,2] + + #-- non homo. only fovy + # projected_vertices = vertices.copy() + # projected_vertices[:,0] = -(near/right)*vertices[:,0]/vertices[:,2] + # projected_vertices[:,1] = -(near/top)*vertices[:,1]/vertices[:,2] + return projected_vertices + + +def to_image(vertices, h, w, is_perspective = False): + ''' change vertices to image coord system + 3d system: XYZ, center(0, 0, 0) + 2d image: x(u), y(v). center(w/2, h/2), flip y-axis. + Args: + vertices: [nver, 3] + h: height of the rendering + w : width of the rendering + Returns: + projected_vertices: [nver, 3] + ''' + image_vertices = vertices.copy() + if is_perspective: + # if perspective, the projected vertices are normalized to [-1, 1]. so change it to image size first. + image_vertices[:,0] = image_vertices[:,0]*w/2 + image_vertices[:,1] = image_vertices[:,1]*h/2 + # move to center of image + image_vertices[:,0] = image_vertices[:,0] + w/2 + image_vertices[:,1] = image_vertices[:,1] + h/2 + # flip vertices along y-axis. + image_vertices[:,1] = h - image_vertices[:,1] - 1 + return image_vertices + + +#### -------------------------------------------2. estimate transform matrix from correspondences. +def estimate_affine_matrix_3d23d(X, Y): + ''' Using least-squares solution + Args: + X: [n, 3]. 3d points(fixed) + Y: [n, 3]. corresponding 3d points(moving). Y = PX + Returns: + P_Affine: (3, 4). Affine camera matrix (the third row is [0, 0, 0, 1]). + ''' + X_homo = np.hstack((X, np.ones([X.shape[1],1]))) #n x 4 + P = np.linalg.lstsq(X_homo, Y)[0].T # Affine matrix. 3 x 4 + return P + +def estimate_affine_matrix_3d22d(X, x): + ''' Using Golden Standard Algorithm for estimating an affine camera + matrix P from world to image correspondences. + See Alg.7.2. in MVGCV + Code Ref: https://github.com/patrikhuber/eos/blob/master/include/eos/fitting/affine_camera_estimation.hpp + x_homo = X_homo.dot(P_Affine) + Args: + X: [n, 3]. corresponding 3d points(fixed) + x: [n, 2]. n>=4. 2d points(moving). x = PX + Returns: + P_Affine: [3, 4]. Affine camera matrix + ''' + X = X.T; x = x.T + assert(x.shape[1] == X.shape[1]) + n = x.shape[1] + assert(n >= 4) + + #--- 1. normalization + # 2d points + mean = np.mean(x, 1) # (2,) + x = x - np.tile(mean[:, np.newaxis], [1, n]) + average_norm = np.mean(np.sqrt(np.sum(x**2, 0))) + scale = np.sqrt(2) / average_norm + x = scale * x + + T = np.zeros((3,3), dtype = np.float32) + T[0, 0] = T[1, 1] = scale + T[:2, 2] = -mean*scale + T[2, 2] = 1 + + # 3d points + X_homo = np.vstack((X, np.ones((1, n)))) + mean = np.mean(X, 1) # (3,) + X = X - np.tile(mean[:, np.newaxis], [1, n]) + m = X_homo[:3,:] - X + average_norm = np.mean(np.sqrt(np.sum(X**2, 0))) + scale = np.sqrt(3) / average_norm + X = scale * X + + U = np.zeros((4,4), dtype = np.float32) + U[0, 0] = U[1, 1] = U[2, 2] = scale + U[:3, 3] = -mean*scale + U[3, 3] = 1 + + # --- 2. equations + A = np.zeros((n*2, 8), dtype = np.float32); + X_homo = np.vstack((X, np.ones((1, n)))).T + A[:n, :4] = X_homo + A[n:, 4:] = X_homo + b = np.reshape(x, [-1, 1]) + + # --- 3. solution + p_8 = np.linalg.pinv(A).dot(b) + P = np.zeros((3, 4), dtype = np.float32) + P[0, :] = p_8[:4, 0] + P[1, :] = p_8[4:, 0] + P[-1, -1] = 1 + + # --- 4. denormalization + P_Affine = np.linalg.inv(T).dot(P.dot(U)) + return P_Affine + +def P2sRt(P): + ''' decompositing camera matrix P + Args: + P: (3, 4). Affine Camera Matrix. + Returns: + s: scale factor. + R: (3, 3). rotation matrix. + t: (3,). translation. + ''' + t = P[:, 3] + R1 = P[0:1, :3] + R2 = P[1:2, :3] + s = (np.linalg.norm(R1) + np.linalg.norm(R2))/2.0 + r1 = R1/np.linalg.norm(R1) + r2 = R2/np.linalg.norm(R2) + r3 = np.cross(r1, r2) + + R = np.concatenate((r1, r2, r3), 0) + return s, R, t + +#Ref: https://www.learnopencv.com/rotation-matrix-to-euler-angles/ +def isRotationMatrix(R): + ''' checks if a matrix is a valid rotation matrix(whether orthogonal or not) + ''' + Rt = np.transpose(R) + shouldBeIdentity = np.dot(Rt, R) + I = np.identity(3, dtype = R.dtype) + n = np.linalg.norm(I - shouldBeIdentity) + return n < 1e-6 + +def matrix2angle(R): + ''' get three Euler angles from Rotation Matrix + Args: + R: (3,3). rotation matrix + Returns: + x: pitch + y: yaw + z: roll + ''' + assert(isRotationMatrix) + sy = math.sqrt(R[0,0] * R[0,0] + R[1,0] * R[1,0]) + + singular = sy < 1e-6 + + if not singular : + x = math.atan2(R[2,1] , R[2,2]) + y = math.atan2(-R[2,0], sy) + z = math.atan2(R[1,0], R[0,0]) + else : + x = math.atan2(-R[1,2], R[1,1]) + y = math.atan2(-R[2,0], sy) + z = 0 + + # rx, ry, rz = np.rad2deg(x), np.rad2deg(y), np.rad2deg(z) + rx, ry, rz = x*180/np.pi, y*180/np.pi, z*180/np.pi + return rx, ry, rz + +# def matrix2angle(R): +# ''' compute three Euler angles from a Rotation Matrix. Ref: http://www.gregslabaugh.net/publications/euler.pdf +# Args: +# R: (3,3). rotation matrix +# Returns: +# x: yaw +# y: pitch +# z: roll +# ''' +# # assert(isRotationMatrix(R)) + +# if R[2,0] !=1 or R[2,0] != -1: +# x = math.asin(R[2,0]) +# y = math.atan2(R[2,1]/cos(x), R[2,2]/cos(x)) +# z = math.atan2(R[1,0]/cos(x), R[0,0]/cos(x)) + +# else:# Gimbal lock +# z = 0 #can be anything +# if R[2,0] == -1: +# x = np.pi/2 +# y = z + math.atan2(R[0,1], R[0,2]) +# else: +# x = -np.pi/2 +# y = -z + math.atan2(-R[0,1], -R[0,2]) + +# return x, y, z \ No newline at end of file diff --git a/src/utils/dependencies/insightface/thirdparty/face3d/mesh_numpy/vis.py b/src/utils/dependencies/insightface/thirdparty/face3d/mesh_numpy/vis.py new file mode 100644 index 0000000..9db972f --- /dev/null +++ b/src/utils/dependencies/insightface/thirdparty/face3d/mesh_numpy/vis.py @@ -0,0 +1,24 @@ +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import numpy as np +import matplotlib.pyplot as plt +from skimage import measure +from mpl_toolkits.mplot3d import Axes3D + +def plot_mesh(vertices, triangles, subplot = [1,1,1], title = 'mesh', el = 90, az = -90, lwdt=.1, dist = 6, color = "grey"): + ''' + plot the mesh + Args: + vertices: [nver, 3] + triangles: [ntri, 3] + ''' + ax = plt.subplot(subplot[0], subplot[1], subplot[2], projection = '3d') + ax.plot_trisurf(vertices[:, 0], vertices[:, 1], vertices[:, 2], triangles = triangles, lw = lwdt, color = color, alpha = 1) + ax.axis("off") + ax.view_init(elev = el, azim = az) + ax.dist = dist + plt.title(title) + +### -------------- Todo: use vtk to visualize mesh? or visvis? or VisPy? diff --git a/src/utils/dependencies/insightface/thirdparty/face3d/morphable_model/__init__.py b/src/utils/dependencies/insightface/thirdparty/face3d/morphable_model/__init__.py new file mode 100644 index 0000000..19fc6a6 --- /dev/null +++ b/src/utils/dependencies/insightface/thirdparty/face3d/morphable_model/__init__.py @@ -0,0 +1,7 @@ +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +from .. import mesh +from .morphabel_model import MorphabelModel +from . import load \ No newline at end of file diff --git a/src/utils/dependencies/insightface/thirdparty/face3d/morphable_model/fit.py b/src/utils/dependencies/insightface/thirdparty/face3d/morphable_model/fit.py new file mode 100644 index 0000000..480532c --- /dev/null +++ b/src/utils/dependencies/insightface/thirdparty/face3d/morphable_model/fit.py @@ -0,0 +1,272 @@ +''' +Estimating parameters about vertices: shape para, exp para, pose para(s, R, t) +''' +import numpy as np +from .. import mesh + +''' TODO: a clear document. +Given: image_points, 3D Model, Camera Matrix(s, R, t2d) +Estimate: shape parameters, expression parameters + +Inference: + + projected_vertices = s*P*R(mu + shape + exp) + t2d --> image_points + s*P*R*shape + s*P*R(mu + exp) + t2d --> image_poitns + + # Define: + X = vertices + x_hat = projected_vertices + x = image_points + A = s*P*R + b = s*P*R(mu + exp) + t2d + ==> + x_hat = A*shape + b (2 x n) + + A*shape (2 x n) + shape = reshape(shapePC * sp) (3 x n) + shapePC*sp : (3n x 1) + + * flatten: + x_hat_flatten = A*shape + b_flatten (2n x 1) + A*shape (2n x 1) + --> A*shapePC (2n x 199) sp: 199 x 1 + + # Define: + pc_2d = A* reshape(shapePC) + pc_2d_flatten = flatten(pc_2d) (2n x 199) + + =====> + x_hat_flatten = pc_2d_flatten * sp + b_flatten ---> x_flatten (2n x 1) + + Goals: + (ignore flatten, pc_2d-->pc) + min E = || x_hat - x || + lambda*sum(sp/sigma)^2 + = || pc * sp + b - x || + lambda*sum(sp/sigma)^2 + + Solve: + d(E)/d(sp) = 0 + 2 * pc' * (pc * sp + b - x) + 2 * lambda * sp / (sigma' * sigma) = 0 + + Get: + (pc' * pc + lambda / (sigma'* sigma)) * sp = pc' * (x - b) + +''' + +def estimate_shape(x, shapeMU, shapePC, shapeEV, expression, s, R, t2d, lamb = 3000): + ''' + Args: + x: (2, n). image points (to be fitted) + shapeMU: (3n, 1) + shapePC: (3n, n_sp) + shapeEV: (n_sp, 1) + expression: (3, n) + s: scale + R: (3, 3). rotation matrix + t2d: (2,). 2d translation + lambda: regulation coefficient + + Returns: + shape_para: (n_sp, 1) shape parameters(coefficients) + ''' + x = x.copy() + assert(shapeMU.shape[0] == shapePC.shape[0]) + assert(shapeMU.shape[0] == x.shape[1]*3) + + dof = shapePC.shape[1] + + n = x.shape[1] + sigma = shapeEV + t2d = np.array(t2d) + P = np.array([[1, 0, 0], [0, 1, 0]], dtype = np.float32) + A = s*P.dot(R) + + # --- calc pc + pc_3d = np.resize(shapePC.T, [dof, n, 3]) # 199 x n x 3 + pc_3d = np.reshape(pc_3d, [dof*n, 3]) + pc_2d = pc_3d.dot(A.T.copy()) # 199 x n x 2 + + pc = np.reshape(pc_2d, [dof, -1]).T # 2n x 199 + + # --- calc b + # shapeMU + mu_3d = np.resize(shapeMU, [n, 3]).T # 3 x n + # expression + exp_3d = expression + # + b = A.dot(mu_3d + exp_3d) + np.tile(t2d[:, np.newaxis], [1, n]) # 2 x n + b = np.reshape(b.T, [-1, 1]) # 2n x 1 + + # --- solve + equation_left = np.dot(pc.T, pc) + lamb * np.diagflat(1/sigma**2) + x = np.reshape(x.T, [-1, 1]) + equation_right = np.dot(pc.T, x - b) + + shape_para = np.dot(np.linalg.inv(equation_left), equation_right) + + return shape_para + +def estimate_expression(x, shapeMU, expPC, expEV, shape, s, R, t2d, lamb = 2000): + ''' + Args: + x: (2, n). image points (to be fitted) + shapeMU: (3n, 1) + expPC: (3n, n_ep) + expEV: (n_ep, 1) + shape: (3, n) + s: scale + R: (3, 3). rotation matrix + t2d: (2,). 2d translation + lambda: regulation coefficient + + Returns: + exp_para: (n_ep, 1) shape parameters(coefficients) + ''' + x = x.copy() + assert(shapeMU.shape[0] == expPC.shape[0]) + assert(shapeMU.shape[0] == x.shape[1]*3) + + dof = expPC.shape[1] + + n = x.shape[1] + sigma = expEV + t2d = np.array(t2d) + P = np.array([[1, 0, 0], [0, 1, 0]], dtype = np.float32) + A = s*P.dot(R) + + # --- calc pc + pc_3d = np.resize(expPC.T, [dof, n, 3]) + pc_3d = np.reshape(pc_3d, [dof*n, 3]) + pc_2d = pc_3d.dot(A.T) + pc = np.reshape(pc_2d, [dof, -1]).T # 2n x 29 + + # --- calc b + # shapeMU + mu_3d = np.resize(shapeMU, [n, 3]).T # 3 x n + # expression + shape_3d = shape + # + b = A.dot(mu_3d + shape_3d) + np.tile(t2d[:, np.newaxis], [1, n]) # 2 x n + b = np.reshape(b.T, [-1, 1]) # 2n x 1 + + # --- solve + equation_left = np.dot(pc.T, pc) + lamb * np.diagflat(1/sigma**2) + x = np.reshape(x.T, [-1, 1]) + equation_right = np.dot(pc.T, x - b) + + exp_para = np.dot(np.linalg.inv(equation_left), equation_right) + + return exp_para + + +# ---------------- fit +def fit_points(x, X_ind, model, n_sp, n_ep, max_iter = 4): + ''' + Args: + x: (n, 2) image points + X_ind: (n,) corresponding Model vertex indices + model: 3DMM + max_iter: iteration + Returns: + sp: (n_sp, 1). shape parameters + ep: (n_ep, 1). exp parameters + s, R, t + ''' + x = x.copy().T + + #-- init + sp = np.zeros((n_sp, 1), dtype = np.float32) + ep = np.zeros((n_ep, 1), dtype = np.float32) + + #-------------------- estimate + X_ind_all = np.tile(X_ind[np.newaxis, :], [3, 1])*3 + X_ind_all[1, :] += 1 + X_ind_all[2, :] += 2 + valid_ind = X_ind_all.flatten('F') + + shapeMU = model['shapeMU'][valid_ind, :] + shapePC = model['shapePC'][valid_ind, :n_sp] + expPC = model['expPC'][valid_ind, :n_ep] + + for i in range(max_iter): + X = shapeMU + shapePC.dot(sp) + expPC.dot(ep) + X = np.reshape(X, [int(len(X)/3), 3]).T + + #----- estimate pose + P = mesh.transform.estimate_affine_matrix_3d22d(X.T, x.T) + s, R, t = mesh.transform.P2sRt(P) + rx, ry, rz = mesh.transform.matrix2angle(R) + #print('Iter:{}; estimated pose: s {}, rx {}, ry {}, rz {}, t1 {}, t2 {}'.format(i, s, rx, ry, rz, t[0], t[1])) + + #----- estimate shape + # expression + shape = shapePC.dot(sp) + shape = np.reshape(shape, [int(len(shape)/3), 3]).T + ep = estimate_expression(x, shapeMU, expPC, model['expEV'][:n_ep,:], shape, s, R, t[:2], lamb = 20) + + # shape + expression = expPC.dot(ep) + expression = np.reshape(expression, [int(len(expression)/3), 3]).T + if i == 0 : + sp = estimate_shape(x, shapeMU, shapePC, model['shapeEV'][:n_sp,:], expression, s, R, t[:2], lamb = 40) + + return sp, ep, s, R, t + + +# ---------------- fitting process +def fit_points_for_show(x, X_ind, model, n_sp, n_ep, max_iter = 4): + ''' + Args: + x: (n, 2) image points + X_ind: (n,) corresponding Model vertex indices + model: 3DMM + max_iter: iteration + Returns: + sp: (n_sp, 1). shape parameters + ep: (n_ep, 1). exp parameters + s, R, t + ''' + x = x.copy().T + + #-- init + sp = np.zeros((n_sp, 1), dtype = np.float32) + ep = np.zeros((n_ep, 1), dtype = np.float32) + + #-------------------- estimate + X_ind_all = np.tile(X_ind[np.newaxis, :], [3, 1])*3 + X_ind_all[1, :] += 1 + X_ind_all[2, :] += 2 + valid_ind = X_ind_all.flatten('F') + + shapeMU = model['shapeMU'][valid_ind, :] + shapePC = model['shapePC'][valid_ind, :n_sp] + expPC = model['expPC'][valid_ind, :n_ep] + + s = 4e-04 + R = mesh.transform.angle2matrix([0, 0, 0]) + t = [0, 0, 0] + lsp = []; lep = []; ls = []; lR = []; lt = [] + for i in range(max_iter): + X = shapeMU + shapePC.dot(sp) + expPC.dot(ep) + X = np.reshape(X, [int(len(X)/3), 3]).T + lsp.append(sp); lep.append(ep); ls.append(s), lR.append(R), lt.append(t) + + #----- estimate pose + P = mesh.transform.estimate_affine_matrix_3d22d(X.T, x.T) + s, R, t = mesh.transform.P2sRt(P) + lsp.append(sp); lep.append(ep); ls.append(s), lR.append(R), lt.append(t) + + #----- estimate shape + # expression + shape = shapePC.dot(sp) + shape = np.reshape(shape, [int(len(shape)/3), 3]).T + ep = estimate_expression(x, shapeMU, expPC, model['expEV'][:n_ep,:], shape, s, R, t[:2], lamb = 20) + lsp.append(sp); lep.append(ep); ls.append(s), lR.append(R), lt.append(t) + + # shape + expression = expPC.dot(ep) + expression = np.reshape(expression, [int(len(expression)/3), 3]).T + sp = estimate_shape(x, shapeMU, shapePC, model['shapeEV'][:n_sp,:], expression, s, R, t[:2], lamb = 40) + + # print('ls', ls) + # print('lR', lR) + return np.array(lsp), np.array(lep), np.array(ls), np.array(lR), np.array(lt) diff --git a/src/utils/dependencies/insightface/thirdparty/face3d/morphable_model/load.py b/src/utils/dependencies/insightface/thirdparty/face3d/morphable_model/load.py new file mode 100644 index 0000000..3ed4649 --- /dev/null +++ b/src/utils/dependencies/insightface/thirdparty/face3d/morphable_model/load.py @@ -0,0 +1,110 @@ +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import numpy as np +import scipy.io as sio + +### --------------------------------- load BFM data +def load_BFM(model_path): + ''' load BFM 3DMM model + Args: + model_path: path to BFM model. + Returns: + model: (nver = 53215, ntri = 105840). nver: number of vertices. ntri: number of triangles. + 'shapeMU': [3*nver, 1] + 'shapePC': [3*nver, 199] + 'shapeEV': [199, 1] + 'expMU': [3*nver, 1] + 'expPC': [3*nver, 29] + 'expEV': [29, 1] + 'texMU': [3*nver, 1] + 'texPC': [3*nver, 199] + 'texEV': [199, 1] + 'tri': [ntri, 3] (start from 1, should sub 1 in python and c++) + 'tri_lip': [114, 3] (start from 1, as a supplement to lip triangles) + 'kpt_ind': [68,] (start from 1) + PS: + You can change codes according to your own saved data. + Just make sure the model has corresponding attributes. + ''' + C = sio.loadmat(model_path) + model = C['model'] + model = model[0,0] + + # change dtype from double(np.float64) to np.float32, + # since big matrix process(espetially matrix dot) is too slow in python. + model['shapeMU'] = (model['shapeMU'] + model['expMU']).astype(np.float32) + model['shapePC'] = model['shapePC'].astype(np.float32) + model['shapeEV'] = model['shapeEV'].astype(np.float32) + model['expEV'] = model['expEV'].astype(np.float32) + model['expPC'] = model['expPC'].astype(np.float32) + + # matlab start with 1. change to 0 in python. + model['tri'] = model['tri'].T.copy(order = 'C').astype(np.int32) - 1 + model['tri_lip'] = model['tri_lip'].T.copy(order = 'C').astype(np.int32) - 1 + + # kpt ind + model['kpt_ind'] = (np.squeeze(model['kpt_ind']) - 1).astype(np.int32) + + return model + +def load_BFM_info(path = 'BFM_info.mat'): + ''' load 3DMM model extra information + Args: + path: path to BFM info. + Returns: + model_info: + 'symlist': 2 x 26720 + 'symlist_tri': 2 x 52937 + 'segbin': 4 x n (0: nose, 1: eye, 2: lip, 3: cheek) + 'segbin_tri': 4 x ntri + 'face_contour': 1 x 28 + 'face_contour_line': 1 x 512 + 'face_contour_front': 1 x 28 + 'face_contour_front_line': 1 x 512 + 'nose_hole': 1 x 142 + 'nose_hole_right': 1 x 71 + 'nose_hole_left': 1 x 71 + 'parallel': 17 x 1 cell + 'parallel_face_contour': 28 x 1 cell + 'uv_coords': n x 2 + ''' + C = sio.loadmat(path) + model_info = C['model_info'] + model_info = model_info[0,0] + return model_info + +def load_uv_coords(path = 'BFM_UV.mat'): + ''' load uv coords of BFM + Args: + path: path to data. + Returns: + uv_coords: [nver, 2]. range: 0-1 + ''' + C = sio.loadmat(path) + uv_coords = C['UV'].copy(order = 'C') + return uv_coords + +def load_pncc_code(path = 'pncc_code.mat'): + ''' load pncc code of BFM + PNCC code: Defined in 'Face Alignment Across Large Poses: A 3D Solution Xiangyu' + download at http://www.cbsr.ia.ac.cn/users/xiangyuzhu/projects/3DDFA/main.htm. + Args: + path: path to data. + Returns: + pncc_code: [nver, 3] + ''' + C = sio.loadmat(path) + pncc_code = C['vertex_code'].T + return pncc_code + +## +def get_organ_ind(model_info): + ''' get nose, eye, lip index + ''' + valid_bin = model_info['segbin'].astype(bool) + organ_ind = np.nonzero(valid_bin[0,:])[0] + for i in range(1, valid_bin.shape[0] - 1): + organ_ind = np.union1d(organ_ind, np.nonzero(valid_bin[i,:])[0]) + return organ_ind.astype(np.int32) diff --git a/src/utils/dependencies/insightface/thirdparty/face3d/morphable_model/morphabel_model.py b/src/utils/dependencies/insightface/thirdparty/face3d/morphable_model/morphabel_model.py new file mode 100644 index 0000000..eb02724 --- /dev/null +++ b/src/utils/dependencies/insightface/thirdparty/face3d/morphable_model/morphabel_model.py @@ -0,0 +1,143 @@ +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import numpy as np +import scipy.io as sio +from .. import mesh +from . import fit +from . import load + +class MorphabelModel(object): + """docstring for MorphabelModel + model: nver: number of vertices. ntri: number of triangles. *: must have. ~: can generate ones array for place holder. + 'shapeMU': [3*nver, 1]. * + 'shapePC': [3*nver, n_shape_para]. * + 'shapeEV': [n_shape_para, 1]. ~ + 'expMU': [3*nver, 1]. ~ + 'expPC': [3*nver, n_exp_para]. ~ + 'expEV': [n_exp_para, 1]. ~ + 'texMU': [3*nver, 1]. ~ + 'texPC': [3*nver, n_tex_para]. ~ + 'texEV': [n_tex_para, 1]. ~ + 'tri': [ntri, 3] (start from 1, should sub 1 in python and c++). * + 'tri_lip': [114, 3] (start from 1, as a supplement to lip triangles). ~ + 'kpt_ind': [68,] (start from 1). ~ + """ + def __init__(self, model_path, model_type = 'BFM'): + super( MorphabelModel, self).__init__() + if model_type=='BFM': + self.model = load.load_BFM(model_path) + else: + print('sorry, not support other 3DMM model now') + exit() + + # fixed attributes + self.nver = self.model['shapePC'].shape[0]/3 + self.ntri = self.model['tri'].shape[0] + self.n_shape_para = self.model['shapePC'].shape[1] + self.n_exp_para = self.model['expPC'].shape[1] + self.n_tex_para = self.model['texMU'].shape[1] + + self.kpt_ind = self.model['kpt_ind'] + self.triangles = self.model['tri'] + self.full_triangles = np.vstack((self.model['tri'], self.model['tri_lip'])) + + # ------------------------------------- shape: represented with mesh(vertices & triangles(fixed)) + def get_shape_para(self, type = 'random'): + if type == 'zero': + sp = np.random.zeros((self.n_shape_para, 1)) + elif type == 'random': + sp = np.random.rand(self.n_shape_para, 1)*1e04 + return sp + + def get_exp_para(self, type = 'random'): + if type == 'zero': + ep = np.zeros((self.n_exp_para, 1)) + elif type == 'random': + ep = -1.5 + 3*np.random.random([self.n_exp_para, 1]) + ep[6:, 0] = 0 + + return ep + + def generate_vertices(self, shape_para, exp_para): + ''' + Args: + shape_para: (n_shape_para, 1) + exp_para: (n_exp_para, 1) + Returns: + vertices: (nver, 3) + ''' + vertices = self.model['shapeMU'] + self.model['shapePC'].dot(shape_para) + self.model['expPC'].dot(exp_para) + vertices = np.reshape(vertices, [int(3), int(len(vertices)/3)], 'F').T + + return vertices + + # -------------------------------------- texture: here represented with rgb value(colors) in vertices. + def get_tex_para(self, type = 'random'): + if type == 'zero': + tp = np.zeros((self.n_tex_para, 1)) + elif type == 'random': + tp = np.random.rand(self.n_tex_para, 1) + return tp + + def generate_colors(self, tex_para): + ''' + Args: + tex_para: (n_tex_para, 1) + Returns: + colors: (nver, 3) + ''' + colors = self.model['texMU'] + self.model['texPC'].dot(tex_para*self.model['texEV']) + colors = np.reshape(colors, [int(3), int(len(colors)/3)], 'F').T/255. + + return colors + + + # ------------------------------------------- transformation + # ------------- transform + def rotate(self, vertices, angles): + ''' rotate face + Args: + vertices: [nver, 3] + angles: [3] x, y, z rotation angle(degree) + x: pitch. positive for looking down + y: yaw. positive for looking left + z: roll. positive for tilting head right + Returns: + vertices: rotated vertices + ''' + return mesh.transform.rotate(vertices, angles) + + def transform(self, vertices, s, angles, t3d): + R = mesh.transform.angle2matrix(angles) + return mesh.transform.similarity_transform(vertices, s, R, t3d) + + def transform_3ddfa(self, vertices, s, angles, t3d): # only used for processing 300W_LP data + R = mesh.transform.angle2matrix_3ddfa(angles) + return mesh.transform.similarity_transform(vertices, s, R, t3d) + + # --------------------------------------------------- fitting + def fit(self, x, X_ind, max_iter = 4, isShow = False): + ''' fit 3dmm & pose parameters + Args: + x: (n, 2) image points + X_ind: (n,) corresponding Model vertex indices + max_iter: iteration + isShow: whether to reserve middle results for show + Returns: + fitted_sp: (n_sp, 1). shape parameters + fitted_ep: (n_ep, 1). exp parameters + s, angles, t + ''' + if isShow: + fitted_sp, fitted_ep, s, R, t = fit.fit_points_for_show(x, X_ind, self.model, n_sp = self.n_shape_para, n_ep = self.n_exp_para, max_iter = max_iter) + angles = np.zeros((R.shape[0], 3)) + for i in range(R.shape[0]): + angles[i] = mesh.transform.matrix2angle(R[i]) + else: + fitted_sp, fitted_ep, s, R, t = fit.fit_points(x, X_ind, self.model, n_sp = self.n_shape_para, n_ep = self.n_exp_para, max_iter = max_iter) + angles = mesh.transform.matrix2angle(R) + return fitted_sp, fitted_ep, s, angles, t + + diff --git a/src/utils/dependencies/insightface/utils/__init__.py b/src/utils/dependencies/insightface/utils/__init__.py new file mode 100644 index 0000000..6960431 --- /dev/null +++ b/src/utils/dependencies/insightface/utils/__init__.py @@ -0,0 +1,6 @@ +from __future__ import absolute_import + +from .storage import download, ensure_available, download_onnx +from .filesystem import get_model_dir +from .filesystem import makedirs, try_import_dali +from .constant import * diff --git a/src/utils/dependencies/insightface/utils/constant.py b/src/utils/dependencies/insightface/utils/constant.py new file mode 100644 index 0000000..8860ff0 --- /dev/null +++ b/src/utils/dependencies/insightface/utils/constant.py @@ -0,0 +1,3 @@ + +DEFAULT_MP_NAME = 'buffalo_l' + diff --git a/src/utils/dependencies/insightface/utils/download.py b/src/utils/dependencies/insightface/utils/download.py new file mode 100644 index 0000000..5cda84d --- /dev/null +++ b/src/utils/dependencies/insightface/utils/download.py @@ -0,0 +1,95 @@ +""" +This code file mainly comes from https://github.com/dmlc/gluon-cv/blob/master/gluoncv/utils/download.py +""" +import os +import hashlib +import requests +from tqdm import tqdm + + +def check_sha1(filename, sha1_hash): + """Check whether the sha1 hash of the file content matches the expected hash. + Parameters + ---------- + filename : str + Path to the file. + sha1_hash : str + Expected sha1 hash in hexadecimal digits. + Returns + ------- + bool + Whether the file content matches the expected hash. + """ + sha1 = hashlib.sha1() + with open(filename, 'rb') as f: + while True: + data = f.read(1048576) + if not data: + break + sha1.update(data) + + sha1_file = sha1.hexdigest() + l = min(len(sha1_file), len(sha1_hash)) + return sha1.hexdigest()[0:l] == sha1_hash[0:l] + + +def download_file(url, path=None, overwrite=False, sha1_hash=None): + """Download an given URL + Parameters + ---------- + url : str + URL to download + path : str, optional + Destination path to store downloaded file. By default stores to the + current directory with same name as in url. + overwrite : bool, optional + Whether to overwrite destination file if already exists. + sha1_hash : str, optional + Expected sha1 hash in hexadecimal digits. Will ignore existing file when hash is specified + but doesn't match. + Returns + ------- + str + The file path of the downloaded file. + """ + if path is None: + fname = url.split('/')[-1] + else: + path = os.path.expanduser(path) + if os.path.isdir(path): + fname = os.path.join(path, url.split('/')[-1]) + else: + fname = path + + if overwrite or not os.path.exists(fname) or ( + sha1_hash and not check_sha1(fname, sha1_hash)): + dirname = os.path.dirname(os.path.abspath(os.path.expanduser(fname))) + if not os.path.exists(dirname): + os.makedirs(dirname) + + print('Downloading %s from %s...' % (fname, url)) + r = requests.get(url, stream=True) + if r.status_code != 200: + raise RuntimeError("Failed downloading url %s" % url) + total_length = r.headers.get('content-length') + with open(fname, 'wb') as f: + if total_length is None: # no content length header + for chunk in r.iter_content(chunk_size=1024): + if chunk: # filter out keep-alive new chunks + f.write(chunk) + else: + total_length = int(total_length) + for chunk in tqdm(r.iter_content(chunk_size=1024), + total=int(total_length / 1024. + 0.5), + unit='KB', + unit_scale=False, + dynamic_ncols=True): + f.write(chunk) + + if sha1_hash and not check_sha1(fname, sha1_hash): + raise UserWarning('File {} is downloaded but the content hash does not match. ' \ + 'The repo may be outdated or download may be incomplete. ' \ + 'If the "repo_url" is overridden, consider switching to ' \ + 'the default repo.'.format(fname)) + + return fname diff --git a/src/utils/dependencies/insightface/utils/face_align.py b/src/utils/dependencies/insightface/utils/face_align.py new file mode 100644 index 0000000..226628b --- /dev/null +++ b/src/utils/dependencies/insightface/utils/face_align.py @@ -0,0 +1,103 @@ +import cv2 +import numpy as np +from skimage import transform as trans + + +arcface_dst = np.array( + [[38.2946, 51.6963], [73.5318, 51.5014], [56.0252, 71.7366], + [41.5493, 92.3655], [70.7299, 92.2041]], + dtype=np.float32) + +def estimate_norm(lmk, image_size=112,mode='arcface'): + assert lmk.shape == (5, 2) + assert image_size%112==0 or image_size%128==0 + if image_size%112==0: + ratio = float(image_size)/112.0 + diff_x = 0 + else: + ratio = float(image_size)/128.0 + diff_x = 8.0*ratio + dst = arcface_dst * ratio + dst[:,0] += diff_x + tform = trans.SimilarityTransform() + tform.estimate(lmk, dst) + M = tform.params[0:2, :] + return M + +def norm_crop(img, landmark, image_size=112, mode='arcface'): + M = estimate_norm(landmark, image_size, mode) + warped = cv2.warpAffine(img, M, (image_size, image_size), borderValue=0.0) + return warped + +def norm_crop2(img, landmark, image_size=112, mode='arcface'): + M = estimate_norm(landmark, image_size, mode) + warped = cv2.warpAffine(img, M, (image_size, image_size), borderValue=0.0) + return warped, M + +def square_crop(im, S): + if im.shape[0] > im.shape[1]: + height = S + width = int(float(im.shape[1]) / im.shape[0] * S) + scale = float(S) / im.shape[0] + else: + width = S + height = int(float(im.shape[0]) / im.shape[1] * S) + scale = float(S) / im.shape[1] + resized_im = cv2.resize(im, (width, height)) + det_im = np.zeros((S, S, 3), dtype=np.uint8) + det_im[:resized_im.shape[0], :resized_im.shape[1], :] = resized_im + return det_im, scale + + +def transform(data, center, output_size, scale, rotation): + scale_ratio = scale + rot = float(rotation) * np.pi / 180.0 + #translation = (output_size/2-center[0]*scale_ratio, output_size/2-center[1]*scale_ratio) + t1 = trans.SimilarityTransform(scale=scale_ratio) + cx = center[0] * scale_ratio + cy = center[1] * scale_ratio + t2 = trans.SimilarityTransform(translation=(-1 * cx, -1 * cy)) + t3 = trans.SimilarityTransform(rotation=rot) + t4 = trans.SimilarityTransform(translation=(output_size / 2, + output_size / 2)) + t = t1 + t2 + t3 + t4 + M = t.params[0:2] + cropped = cv2.warpAffine(data, + M, (output_size, output_size), + borderValue=0.0) + return cropped, M + + +def trans_points2d(pts, M): + new_pts = np.zeros(shape=pts.shape, dtype=np.float32) + for i in range(pts.shape[0]): + pt = pts[i] + new_pt = np.array([pt[0], pt[1], 1.], dtype=np.float32) + new_pt = np.dot(M, new_pt) + #print('new_pt', new_pt.shape, new_pt) + new_pts[i] = new_pt[0:2] + + return new_pts + + +def trans_points3d(pts, M): + scale = np.sqrt(M[0][0] * M[0][0] + M[0][1] * M[0][1]) + #print(scale) + new_pts = np.zeros(shape=pts.shape, dtype=np.float32) + for i in range(pts.shape[0]): + pt = pts[i] + new_pt = np.array([pt[0], pt[1], 1.], dtype=np.float32) + new_pt = np.dot(M, new_pt) + #print('new_pt', new_pt.shape, new_pt) + new_pts[i][0:2] = new_pt[0:2] + new_pts[i][2] = pts[i][2] * scale + + return new_pts + + +def trans_points(pts, M): + if pts.shape[1] == 2: + return trans_points2d(pts, M) + else: + return trans_points3d(pts, M) + diff --git a/src/utils/dependencies/insightface/utils/filesystem.py b/src/utils/dependencies/insightface/utils/filesystem.py new file mode 100644 index 0000000..01e3851 --- /dev/null +++ b/src/utils/dependencies/insightface/utils/filesystem.py @@ -0,0 +1,157 @@ +""" +This code file mainly comes from https://github.com/dmlc/gluon-cv/blob/master/gluoncv/utils/filesystem.py +""" +import os +import os.path as osp +import errno + + +def get_model_dir(name, root='~/.insightface'): + root = os.path.expanduser(root) + model_dir = osp.join(root, 'models', name) + return model_dir + +def makedirs(path): + """Create directory recursively if not exists. + Similar to `makedir -p`, you can skip checking existence before this function. + + Parameters + ---------- + path : str + Path of the desired dir + """ + try: + os.makedirs(path) + except OSError as exc: + if exc.errno != errno.EEXIST: + raise + + +def try_import(package, message=None): + """Try import specified package, with custom message support. + + Parameters + ---------- + package : str + The name of the targeting package. + message : str, default is None + If not None, this function will raise customized error message when import error is found. + + + Returns + ------- + module if found, raise ImportError otherwise + + """ + try: + return __import__(package) + except ImportError as e: + if not message: + raise e + raise ImportError(message) + + +def try_import_cv2(): + """Try import cv2 at runtime. + + Returns + ------- + cv2 module if found. Raise ImportError otherwise + + """ + msg = "cv2 is required, you can install by package manager, e.g. 'apt-get', \ + or `pip install opencv-python --user` (note that this is unofficial PYPI package)." + + return try_import('cv2', msg) + + +def try_import_mmcv(): + """Try import mmcv at runtime. + + Returns + ------- + mmcv module if found. Raise ImportError otherwise + + """ + msg = "mmcv is required, you can install by first `pip install Cython --user` \ + and then `pip install mmcv --user` (note that this is unofficial PYPI package)." + + return try_import('mmcv', msg) + + +def try_import_rarfile(): + """Try import rarfile at runtime. + + Returns + ------- + rarfile module if found. Raise ImportError otherwise + + """ + msg = "rarfile is required, you can install by first `sudo apt-get install unrar` \ + and then `pip install rarfile --user` (note that this is unofficial PYPI package)." + + return try_import('rarfile', msg) + + +def import_try_install(package, extern_url=None): + """Try import the specified package. + If the package not installed, try use pip to install and import if success. + + Parameters + ---------- + package : str + The name of the package trying to import. + extern_url : str or None, optional + The external url if package is not hosted on PyPI. + For example, you can install a package using: + "pip install git+http://github.com/user/repo/tarball/master/egginfo=xxx". + In this case, you can pass the url to the extern_url. + + Returns + ------- + + The imported python module. + + """ + try: + return __import__(package) + except ImportError: + try: + from pip import main as pipmain + except ImportError: + from pip._internal import main as pipmain + + # trying to install package + url = package if extern_url is None else extern_url + pipmain(['install', '--user', + url]) # will raise SystemExit Error if fails + + # trying to load again + try: + return __import__(package) + except ImportError: + import sys + import site + user_site = site.getusersitepackages() + if user_site not in sys.path: + sys.path.append(user_site) + return __import__(package) + return __import__(package) + + +def try_import_dali(): + """Try import NVIDIA DALI at runtime. + """ + try: + dali = __import__('nvidia.dali', fromlist=['pipeline', 'ops', 'types']) + dali.Pipeline = dali.pipeline.Pipeline + except ImportError: + + class dali: + class Pipeline: + def __init__(self): + raise NotImplementedError( + "DALI not found, please check if you installed it correctly." + ) + + return dali diff --git a/src/utils/dependencies/insightface/utils/storage.py b/src/utils/dependencies/insightface/utils/storage.py new file mode 100644 index 0000000..5bf37e2 --- /dev/null +++ b/src/utils/dependencies/insightface/utils/storage.py @@ -0,0 +1,52 @@ + +import os +import os.path as osp +import zipfile +from .download import download_file + +BASE_REPO_URL = 'https://github.com/deepinsight/insightface/releases/download/v0.7' + +def download(sub_dir, name, force=False, root='~/.insightface'): + _root = os.path.expanduser(root) + dir_path = os.path.join(_root, sub_dir, name) + if osp.exists(dir_path) and not force: + return dir_path + print('download_path:', dir_path) + zip_file_path = os.path.join(_root, sub_dir, name + '.zip') + model_url = "%s/%s.zip"%(BASE_REPO_URL, name) + download_file(model_url, + path=zip_file_path, + overwrite=True) + if not os.path.exists(dir_path): + os.makedirs(dir_path) + with zipfile.ZipFile(zip_file_path) as zf: + zf.extractall(dir_path) + #os.remove(zip_file_path) + return dir_path + +def ensure_available(sub_dir, name, root='~/.insightface'): + return download(sub_dir, name, force=False, root=root) + +def download_onnx(sub_dir, model_file, force=False, root='~/.insightface', download_zip=False): + _root = os.path.expanduser(root) + model_root = osp.join(_root, sub_dir) + new_model_file = osp.join(model_root, model_file) + if osp.exists(new_model_file) and not force: + return new_model_file + if not osp.exists(model_root): + os.makedirs(model_root) + print('download_path:', new_model_file) + if not download_zip: + model_url = "%s/%s"%(BASE_REPO_URL, model_file) + download_file(model_url, + path=new_model_file, + overwrite=True) + else: + model_url = "%s/%s.zip"%(BASE_REPO_URL, model_file) + zip_file_path = new_model_file+".zip" + download_file(model_url, + path=zip_file_path, + overwrite=True) + with zipfile.ZipFile(zip_file_path) as zf: + zf.extractall(model_root) + return new_model_file diff --git a/src/utils/dependencies/insightface/utils/transform.py b/src/utils/dependencies/insightface/utils/transform.py new file mode 100644 index 0000000..06531d2 --- /dev/null +++ b/src/utils/dependencies/insightface/utils/transform.py @@ -0,0 +1,116 @@ +import cv2 +import math +import numpy as np +from skimage import transform as trans + + +def transform(data, center, output_size, scale, rotation): + scale_ratio = scale + rot = float(rotation) * np.pi / 180.0 + #translation = (output_size/2-center[0]*scale_ratio, output_size/2-center[1]*scale_ratio) + t1 = trans.SimilarityTransform(scale=scale_ratio) + cx = center[0] * scale_ratio + cy = center[1] * scale_ratio + t2 = trans.SimilarityTransform(translation=(-1 * cx, -1 * cy)) + t3 = trans.SimilarityTransform(rotation=rot) + t4 = trans.SimilarityTransform(translation=(output_size / 2, + output_size / 2)) + t = t1 + t2 + t3 + t4 + M = t.params[0:2] + cropped = cv2.warpAffine(data, + M, (output_size, output_size), + borderValue=0.0) + return cropped, M + + +def trans_points2d(pts, M): + new_pts = np.zeros(shape=pts.shape, dtype=np.float32) + for i in range(pts.shape[0]): + pt = pts[i] + new_pt = np.array([pt[0], pt[1], 1.], dtype=np.float32) + new_pt = np.dot(M, new_pt) + #print('new_pt', new_pt.shape, new_pt) + new_pts[i] = new_pt[0:2] + + return new_pts + + +def trans_points3d(pts, M): + scale = np.sqrt(M[0][0] * M[0][0] + M[0][1] * M[0][1]) + #print(scale) + new_pts = np.zeros(shape=pts.shape, dtype=np.float32) + for i in range(pts.shape[0]): + pt = pts[i] + new_pt = np.array([pt[0], pt[1], 1.], dtype=np.float32) + new_pt = np.dot(M, new_pt) + #print('new_pt', new_pt.shape, new_pt) + new_pts[i][0:2] = new_pt[0:2] + new_pts[i][2] = pts[i][2] * scale + + return new_pts + + +def trans_points(pts, M): + if pts.shape[1] == 2: + return trans_points2d(pts, M) + else: + return trans_points3d(pts, M) + +def estimate_affine_matrix_3d23d(X, Y): + ''' Using least-squares solution + Args: + X: [n, 3]. 3d points(fixed) + Y: [n, 3]. corresponding 3d points(moving). Y = PX + Returns: + P_Affine: (3, 4). Affine camera matrix (the third row is [0, 0, 0, 1]). + ''' + X_homo = np.hstack((X, np.ones([X.shape[0],1]))) #n x 4 + P = np.linalg.lstsq(X_homo, Y)[0].T # Affine matrix. 3 x 4 + return P + +def P2sRt(P): + ''' decompositing camera matrix P + Args: + P: (3, 4). Affine Camera Matrix. + Returns: + s: scale factor. + R: (3, 3). rotation matrix. + t: (3,). translation. + ''' + t = P[:, 3] + R1 = P[0:1, :3] + R2 = P[1:2, :3] + s = (np.linalg.norm(R1) + np.linalg.norm(R2))/2.0 + r1 = R1/np.linalg.norm(R1) + r2 = R2/np.linalg.norm(R2) + r3 = np.cross(r1, r2) + + R = np.concatenate((r1, r2, r3), 0) + return s, R, t + +def matrix2angle(R): + ''' get three Euler angles from Rotation Matrix + Args: + R: (3,3). rotation matrix + Returns: + x: pitch + y: yaw + z: roll + ''' + sy = math.sqrt(R[0,0] * R[0,0] + R[1,0] * R[1,0]) + + singular = sy < 1e-6 + + if not singular : + x = math.atan2(R[2,1] , R[2,2]) + y = math.atan2(-R[2,0], sy) + z = math.atan2(R[1,0], R[0,0]) + else : + x = math.atan2(-R[1,2], R[1,1]) + y = math.atan2(-R[2,0], sy) + z = 0 + + # rx, ry, rz = np.rad2deg(x), np.rad2deg(y), np.rad2deg(z) + rx, ry, rz = x*180/np.pi, y*180/np.pi, z*180/np.pi + return rx, ry, rz + diff --git a/src/utils/face_analysis_diy.py b/src/utils/face_analysis_diy.py new file mode 100644 index 0000000..456be5e --- /dev/null +++ b/src/utils/face_analysis_diy.py @@ -0,0 +1,79 @@ +# coding: utf-8 + +""" +face detectoin and alignment using InsightFace +""" + +import numpy as np +from .rprint import rlog as log +from .dependencies.insightface.app import FaceAnalysis +from .dependencies.insightface.app.common import Face +from .timer import Timer + + +def sort_by_direction(faces, direction: str = 'large-small', face_center=None): + if len(faces) <= 0: + return faces + + if direction == 'left-right': + return sorted(faces, key=lambda face: face['bbox'][0]) + if direction == 'right-left': + return sorted(faces, key=lambda face: face['bbox'][0], reverse=True) + if direction == 'top-bottom': + return sorted(faces, key=lambda face: face['bbox'][1]) + if direction == 'bottom-top': + return sorted(faces, key=lambda face: face['bbox'][1], reverse=True) + if direction == 'small-large': + return sorted(faces, key=lambda face: (face['bbox'][2] - face['bbox'][0]) * (face['bbox'][3] - face['bbox'][1])) + if direction == 'large-small': + return sorted(faces, key=lambda face: (face['bbox'][2] - face['bbox'][0]) * (face['bbox'][3] - face['bbox'][1]), reverse=True) + if direction == 'distance-from-retarget-face': + return sorted(faces, key=lambda face: (((face['bbox'][2]+face['bbox'][0])/2-face_center[0])**2+((face['bbox'][3]+face['bbox'][1])/2-face_center[1])**2)**0.5) + return faces + + +class FaceAnalysisDIY(FaceAnalysis): + def __init__(self, name='buffalo_l', root='~/.insightface', allowed_modules=None, **kwargs): + super().__init__(name=name, root=root, allowed_modules=allowed_modules, **kwargs) + + self.timer = Timer() + + def get(self, img_bgr, **kwargs): + max_num = kwargs.get('max_num', 0) # the number of the detected faces, 0 means no limit + flag_do_landmark_2d_106 = kwargs.get('flag_do_landmark_2d_106', True) # whether to do 106-point detection + direction = kwargs.get('direction', 'large-small') # sorting direction + face_center = None + + bboxes, kpss = self.det_model.detect(img_bgr, max_num=max_num, metric='default') + if bboxes.shape[0] == 0: + return [] + ret = [] + for i in range(bboxes.shape[0]): + bbox = bboxes[i, 0:4] + det_score = bboxes[i, 4] + kps = None + if kpss is not None: + kps = kpss[i] + face = Face(bbox=bbox, kps=kps, det_score=det_score) + for taskname, model in self.models.items(): + if taskname == 'detection': + continue + + if (not flag_do_landmark_2d_106) and taskname == 'landmark_2d_106': + continue + + # print(f'taskname: {taskname}') + model.get(img_bgr, face) + ret.append(face) + + ret = sort_by_direction(ret, direction, face_center) + return ret + + def warmup(self): + self.timer.tic() + + img_bgr = np.zeros((512, 512, 3), dtype=np.uint8) + self.get(img_bgr) + + elapse = self.timer.toc() + log(f'FaceAnalysisDIY warmup time: {elapse:.3f}s') diff --git a/src/utils/helper.py b/src/utils/helper.py new file mode 100644 index 0000000..267f97f --- /dev/null +++ b/src/utils/helper.py @@ -0,0 +1,175 @@ +# coding: utf-8 + +""" +utility functions and classes to handle feature extraction and model loading +""" + +import os +import os.path as osp +import cv2 +import torch +from rich.console import Console +from collections import OrderedDict + +from src.modules.spade_generator import SPADEDecoder +from src.modules.warping_network import WarpingNetwork +from src.modules.motion_extractor import MotionExtractor +from src.modules.appearance_feature_extractor import AppearanceFeatureExtractor +from src.modules.stitching_retargeting_network import StitchingRetargetingNetwork +from .rprint import rlog as log + + +def suffix(filename): + """a.jpg -> jpg""" + pos = filename.rfind(".") + if pos == -1: + return "" + return filename[pos + 1:] + + +def prefix(filename): + """a.jpg -> a""" + pos = filename.rfind(".") + if pos == -1: + return filename + return filename[:pos] + + +def basename(filename): + """a/b/c.jpg -> c""" + return prefix(osp.basename(filename)) + + +def is_video(file_path): + if file_path.lower().endswith((".mp4", ".mov", ".avi", ".webm")) or osp.isdir(file_path): + return True + return False + +def is_template(file_path): + if file_path.endswith(".pkl"): + return True + return False + + +def mkdir(d, log=False): + # return self-assined `d`, for one line code + if not osp.exists(d): + os.makedirs(d, exist_ok=True) + if log: + print(f"Make dir: {d}") + return d + + +def squeeze_tensor_to_numpy(tensor): + out = tensor.data.squeeze(0).cpu().numpy() + return out + + +def dct2cuda(dct: dict, device_id: int): + for key in dct: + dct[key] = torch.tensor(dct[key]).cuda(device_id) + return dct + + +def concat_feat(kp_source: torch.Tensor, kp_driving: torch.Tensor) -> torch.Tensor: + """ + kp_source: (bs, k, 3) + kp_driving: (bs, k, 3) + Return: (bs, 2k*3) + """ + bs_src = kp_source.shape[0] + bs_dri = kp_driving.shape[0] + assert bs_src == bs_dri, 'batch size must be equal' + + feat = torch.cat([kp_source.view(bs_src, -1), kp_driving.view(bs_dri, -1)], dim=1) + return feat + + +def remove_ddp_dumplicate_key(state_dict): + state_dict_new = OrderedDict() + for key in state_dict.keys(): + state_dict_new[key.replace('module.', '')] = state_dict[key] + return state_dict_new + + +def load_model(ckpt_path, model_config, device, model_type): + model_params = model_config['model_params'][f'{model_type}_params'] + + if model_type == 'appearance_feature_extractor': + model = AppearanceFeatureExtractor(**model_params).cuda(device) + elif model_type == 'motion_extractor': + model = MotionExtractor(**model_params).cuda(device) + elif model_type == 'warping_module': + model = WarpingNetwork(**model_params).cuda(device) + elif model_type == 'spade_generator': + model = SPADEDecoder(**model_params).cuda(device) + elif model_type == 'stitching_retargeting_module': + # Special handling for stitching and retargeting module + config = model_config['model_params']['stitching_retargeting_module_params'] + checkpoint = torch.load(ckpt_path, map_location=lambda storage, loc: storage) + + stitcher = StitchingRetargetingNetwork(**config.get('stitching')) + stitcher.load_state_dict(remove_ddp_dumplicate_key(checkpoint['retarget_shoulder'])) + stitcher = stitcher.cuda(device) + stitcher.eval() + + retargetor_lip = StitchingRetargetingNetwork(**config.get('lip')) + retargetor_lip.load_state_dict(remove_ddp_dumplicate_key(checkpoint['retarget_mouth'])) + retargetor_lip = retargetor_lip.cuda(device) + retargetor_lip.eval() + + retargetor_eye = StitchingRetargetingNetwork(**config.get('eye')) + retargetor_eye.load_state_dict(remove_ddp_dumplicate_key(checkpoint['retarget_eye'])) + retargetor_eye = retargetor_eye.cuda(device) + retargetor_eye.eval() + + return { + 'stitching': stitcher, + 'lip': retargetor_lip, + 'eye': retargetor_eye + } + else: + raise ValueError(f"Unknown model type: {model_type}") + + model.load_state_dict(torch.load(ckpt_path, map_location=lambda storage, loc: storage)) + model.eval() + return model + + +# get coefficients of Eqn. 7 +def calculate_transformation(config, s_kp_info, t_0_kp_info, t_i_kp_info, R_s, R_t_0, R_t_i): + if config.relative: + new_rotation = (R_t_i @ R_t_0.permute(0, 2, 1)) @ R_s + new_expression = s_kp_info['exp'] + (t_i_kp_info['exp'] - t_0_kp_info['exp']) + else: + new_rotation = R_t_i + new_expression = t_i_kp_info['exp'] + new_translation = s_kp_info['t'] + (t_i_kp_info['t'] - t_0_kp_info['t']) + new_translation[..., 2].fill_(0) # Keep the z-axis unchanged + new_scale = s_kp_info['scale'] * (t_i_kp_info['scale'] / t_0_kp_info['scale']) + return new_rotation, new_expression, new_translation, new_scale + +def load_description(fp): + with open(fp, 'r', encoding='utf-8') as f: + content = f.read() + return content + + +def resize_to_limit(img, max_dim=1280, n=2): + h, w = img.shape[:2] + if max_dim > 0 and max(h, w) > max_dim: + if h > w: + new_h = max_dim + new_w = int(w * (max_dim / h)) + else: + new_w = max_dim + new_h = int(h * (max_dim / w)) + img = cv2.resize(img, (new_w, new_h)) + n = max(n, 1) + new_h = img.shape[0] - (img.shape[0] % n) + new_w = img.shape[1] - (img.shape[1] % n) + if new_h == 0 or new_w == 0: + return img + if new_h != img.shape[0] or new_w != img.shape[1]: + img = img[:new_h, :new_w] + return img diff --git a/src/utils/io.py b/src/utils/io.py new file mode 100644 index 0000000..f930c48 --- /dev/null +++ b/src/utils/io.py @@ -0,0 +1,97 @@ +# coding: utf-8 + +import os +from glob import glob +import os.path as osp +import imageio +import numpy as np +import cv2; cv2.setNumThreads(0); cv2.ocl.setUseOpenCL(False) + + +def load_image_rgb(image_path: str): + if not osp.exists(image_path): + raise FileNotFoundError(f"Image not found: {image_path}") + img = cv2.imread(image_path, cv2.IMREAD_COLOR) + return cv2.cvtColor(img, cv2.COLOR_BGR2RGB) + + +def load_driving_info(driving_info): + driving_video_ori = [] + + def load_images_from_directory(directory): + image_paths = sorted(glob(osp.join(directory, '*.png')) + glob(osp.join(directory, '*.jpg'))) + return [load_image_rgb(im_path) for im_path in image_paths] + + def load_images_from_video(file_path): + reader = imageio.get_reader(file_path) + return [image for idx, image in enumerate(reader)] + + if osp.isdir(driving_info): + driving_video_ori = load_images_from_directory(driving_info) + elif osp.isfile(driving_info): + driving_video_ori = load_images_from_video(driving_info) + + return driving_video_ori + + +def contiguous(obj): + if not obj.flags.c_contiguous: + obj = obj.copy(order="C") + return obj + + +def _resize_to_limit(img: np.ndarray, max_dim=1920, n=2): + """ + ajust the size of the image so that the maximum dimension does not exceed max_dim, and the width and the height of the image are multiples of n. + :param img: the image to be processed. + :param max_dim: the maximum dimension constraint. + :param n: the number that needs to be multiples of. + :return: the adjusted image. + """ + h, w = img.shape[:2] + + # ajust the size of the image according to the maximum dimension + if max_dim > 0 and max(h, w) > max_dim: + if h > w: + new_h = max_dim + new_w = int(w * (max_dim / h)) + else: + new_w = max_dim + new_h = int(h * (max_dim / w)) + img = cv2.resize(img, (new_w, new_h)) + + # ensure that the image dimensions are multiples of n + n = max(n, 1) + new_h = img.shape[0] - (img.shape[0] % n) + new_w = img.shape[1] - (img.shape[1] % n) + + if new_h == 0 or new_w == 0: + # when the width or height is less than n, no need to process + return img + + if new_h != img.shape[0] or new_w != img.shape[1]: + img = img[:new_h, :new_w] + + return img + + +def load_img_online(obj, mode="bgr", **kwargs): + max_dim = kwargs.get("max_dim", 1920) + n = kwargs.get("n", 2) + if isinstance(obj, str): + if mode.lower() == "gray": + img = cv2.imread(obj, cv2.IMREAD_GRAYSCALE) + else: + img = cv2.imread(obj, cv2.IMREAD_COLOR) + else: + img = obj + + # Resize image to satisfy constraints + img = _resize_to_limit(img, max_dim=max_dim, n=n) + + if mode.lower() == "bgr": + return contiguous(img) + elif mode.lower() == "rgb": + return contiguous(img[..., ::-1]) + else: + raise Exception(f"Unknown mode {mode}") diff --git a/src/utils/landmark_runner.py b/src/utils/landmark_runner.py new file mode 100644 index 0000000..7b0dcbe --- /dev/null +++ b/src/utils/landmark_runner.py @@ -0,0 +1,89 @@ +# coding: utf-8 + +import os.path as osp +import cv2; cv2.setNumThreads(0); cv2.ocl.setUseOpenCL(False) +import torch +import numpy as np +import onnxruntime +from .timer import Timer +from .rprint import rlog +from .crop import crop_image, _transform_pts + + +def make_abs_path(fn): + return osp.join(osp.dirname(osp.realpath(__file__)), fn) + + +def to_ndarray(obj): + if isinstance(obj, torch.Tensor): + return obj.cpu().numpy() + elif isinstance(obj, np.ndarray): + return obj + else: + return np.array(obj) + + +class LandmarkRunner(object): + """landmark runner""" + def __init__(self, **kwargs): + ckpt_path = kwargs.get('ckpt_path') + onnx_provider = kwargs.get('onnx_provider', 'cuda') # ้ป˜่ฎค็”จcuda + device_id = kwargs.get('device_id', 0) + self.dsize = kwargs.get('dsize', 224) + self.timer = Timer() + + if onnx_provider.lower() == 'cuda': + self.session = onnxruntime.InferenceSession( + ckpt_path, providers=[ + ('CUDAExecutionProvider', {'device_id': device_id}) + ] + ) + else: + opts = onnxruntime.SessionOptions() + opts.intra_op_num_threads = 4 # ้ป˜่ฎค็บฟ็จ‹ๆ•ฐไธบ 4 + self.session = onnxruntime.InferenceSession( + ckpt_path, providers=['CPUExecutionProvider'], + sess_options=opts + ) + + def _run(self, inp): + out = self.session.run(None, {'input': inp}) + return out + + def run(self, img_rgb: np.ndarray, lmk=None): + if lmk is not None: + crop_dct = crop_image(img_rgb, lmk, dsize=self.dsize, scale=1.5, vy_ratio=-0.1) + img_crop_rgb = crop_dct['img_crop'] + else: + img_crop_rgb = cv2.resize(img_rgb, (self.dsize, self.dsize)) + scale = max(img_rgb.shape[:2]) / self.dsize + crop_dct = { + 'M_c2o': np.array([ + [scale, 0., 0.], + [0., scale, 0.], + [0., 0., 1.], + ], dtype=np.float32), + } + + inp = (img_crop_rgb.astype(np.float32) / 255.).transpose(2, 0, 1)[None, ...] # HxWx3 (BGR) -> 1x3xHxW (RGB!) + + out_lst = self._run(inp) + out_pts = out_lst[2] + + pts = to_ndarray(out_pts[0]).reshape(-1, 2) * self.dsize # scale to 0-224 + pts = _transform_pts(pts, M=crop_dct['M_c2o']) + + return { + 'pts': pts, # 2d landmarks 203 points + } + + def warmup(self): + # ๆž„้€ dummy image่ฟ›่กŒwarmup + self.timer.tic() + + dummy_image = np.zeros((1, 3, self.dsize, self.dsize), dtype=np.float32) + + _ = self._run(dummy_image) + + elapse = self.timer.toc() + rlog(f'LandmarkRunner warmup time: {elapse:.3f}s') diff --git a/src/utils/resources/.gitattributes b/src/utils/resources/.gitattributes new file mode 100644 index 0000000..e9c5856 --- /dev/null +++ b/src/utils/resources/.gitattributes @@ -0,0 +1 @@ +mask_template.png filter=lfs diff=lfs merge=lfs -text diff --git a/src/utils/resources/mask_template.png b/src/utils/resources/mask_template.png new file mode 100644 index 0000000..d352221 --- /dev/null +++ b/src/utils/resources/mask_template.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4c53e64a07ae3056af2b38548ae5b6cceb04d5c3e6514c7a8d2c3aff9da1ee76 +size 3470 diff --git a/src/utils/retargeting_utils.py b/src/utils/retargeting_utils.py new file mode 100644 index 0000000..2028590 --- /dev/null +++ b/src/utils/retargeting_utils.py @@ -0,0 +1,76 @@ + +""" +Functions to compute distance ratios between specific pairs of facial landmarks +""" + +import numpy as np +import torch + + +def calculate_distance_ratio(lmk: np.ndarray, idx1: int, idx2: int, idx3: int, idx4: int, eps: float = 1e-6) -> np.ndarray: + """ + Calculate the ratio of the distance between two pairs of landmarks. + + Parameters: + lmk (np.ndarray): Landmarks array of shape (B, N, 2). + idx1, idx2, idx3, idx4 (int): Indices of the landmarks. + eps (float): Small value to avoid division by zero. + + Returns: + np.ndarray: Calculated distance ratio. + """ + return (np.linalg.norm(lmk[:, idx1] - lmk[:, idx2], axis=1, keepdims=True) / + (np.linalg.norm(lmk[:, idx3] - lmk[:, idx4], axis=1, keepdims=True) + eps)) + + +def calc_eye_close_ratio(lmk: np.ndarray, target_eye_ratio: np.ndarray = None) -> np.ndarray: + """ + Calculate the eye-close ratio for left and right eyes. + + Parameters: + lmk (np.ndarray): Landmarks array of shape (B, N, 2). + target_eye_ratio (np.ndarray, optional): Additional target eye ratio array to include. + + Returns: + np.ndarray: Concatenated eye-close ratios. + """ + lefteye_close_ratio = calculate_distance_ratio(lmk, 6, 18, 0, 12) + righteye_close_ratio = calculate_distance_ratio(lmk, 30, 42, 24, 36) + if target_eye_ratio is not None: + return np.concatenate([lefteye_close_ratio, righteye_close_ratio, target_eye_ratio], axis=1) + else: + return np.concatenate([lefteye_close_ratio, righteye_close_ratio], axis=1) + + +def calc_lip_close_ratio(lmk: np.ndarray) -> np.ndarray: + """ + Calculate the lip-close ratio. + + Parameters: + lmk (np.ndarray): Landmarks array of shape (B, N, 2). + + Returns: + np.ndarray: Calculated lip-close ratio. + """ + return calculate_distance_ratio(lmk, 90, 102, 48, 66) + + +def compute_eye_delta(frame_idx, input_eye_ratios, source_landmarks, portrait_wrapper, kp_source): + input_eye_ratio = input_eye_ratios[frame_idx][0][0] + eye_close_ratio = calc_eye_close_ratio(source_landmarks[None]) + eye_close_ratio_tensor = torch.from_numpy(eye_close_ratio).float().cuda(portrait_wrapper.device_id) + input_eye_ratio_tensor = torch.Tensor([input_eye_ratio]).reshape(1, 1).cuda(portrait_wrapper.device_id) + combined_eye_ratio_tensor = torch.cat([eye_close_ratio_tensor, input_eye_ratio_tensor], dim=1) + # print(combined_eye_ratio_tensor.mean()) + eye_delta = portrait_wrapper.retarget_eye(kp_source, combined_eye_ratio_tensor) + return eye_delta + + +def compute_lip_delta(frame_idx, input_lip_ratios, source_landmarks, portrait_wrapper, kp_source): + input_lip_ratio = input_lip_ratios[frame_idx][0] + lip_close_ratio = calc_lip_close_ratio(source_landmarks[None]) + lip_close_ratio_tensor = torch.from_numpy(lip_close_ratio).float().cuda(portrait_wrapper.device_id) + input_lip_ratio_tensor = torch.Tensor([input_lip_ratio]).cuda(portrait_wrapper.device_id) + combined_lip_ratio_tensor = torch.cat([lip_close_ratio_tensor, input_lip_ratio_tensor], dim=1) + lip_delta = portrait_wrapper.retarget_lip(kp_source, combined_lip_ratio_tensor) + return lip_delta diff --git a/src/utils/rprint.py b/src/utils/rprint.py new file mode 100644 index 0000000..c43a42f --- /dev/null +++ b/src/utils/rprint.py @@ -0,0 +1,16 @@ +# coding: utf-8 + +""" +custom print and log functions +""" + +__all__ = ['rprint', 'rlog'] + +try: + from rich.console import Console + console = Console() + rprint = console.print + rlog = console.log +except: + rprint = print + rlog = print diff --git a/src/utils/timer.py b/src/utils/timer.py new file mode 100644 index 0000000..3570fa4 --- /dev/null +++ b/src/utils/timer.py @@ -0,0 +1,29 @@ +# coding: utf-8 + +""" +tools to measure elapsed time +""" + +import time + +class Timer(object): + """A simple timer.""" + + def __init__(self): + self.total_time = 0. + self.calls = 0 + self.start_time = 0. + self.diff = 0. + + def tic(self): + # using time.time instead of time.clock because time time.clock + # does not normalize for multithreading + self.start_time = time.time() + + def toc(self, average=True): + self.diff = time.time() - self.start_time + return self.diff + + def clear(self): + self.start_time = 0. + self.diff = 0. diff --git a/src/utils/video.py b/src/utils/video.py new file mode 100644 index 0000000..720e082 --- /dev/null +++ b/src/utils/video.py @@ -0,0 +1,139 @@ +# coding: utf-8 + +""" +functions for processing video +""" + +import os.path as osp +import numpy as np +import subprocess +import imageio +import cv2 + +from rich.progress import track +from .helper import prefix +from .rprint import rprint as print + + +def exec_cmd(cmd): + subprocess.run(cmd, shell=True, check=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + + +def images2video(images, wfp, **kwargs): + fps = kwargs.get('fps', 30) + video_format = kwargs.get('format', 'mp4') # default is mp4 format + codec = kwargs.get('codec', 'libx264') # default is libx264 encoding + quality = kwargs.get('quality') # video quality + pixelformat = kwargs.get('pixelformat', 'yuv420p') # video pixel format + image_mode = kwargs.get('image_mode', 'rgb') + macro_block_size = kwargs.get('macro_block_size', 2) + ffmpeg_params = ['-crf', str(kwargs.get('crf', 18))] + + writer = imageio.get_writer( + wfp, fps=fps, format=video_format, + codec=codec, quality=quality, ffmpeg_params=ffmpeg_params, pixelformat=pixelformat, macro_block_size=macro_block_size + ) + + n = len(images) + for i in track(range(n), description='writing', transient=True): + if image_mode.lower() == 'bgr': + writer.append_data(images[i][..., ::-1]) + else: + writer.append_data(images[i]) + + writer.close() + + # print(f':smiley: Dump to {wfp}\n', style="bold green") + print(f'Dump to {wfp}\n') + + +def video2gif(video_fp, fps=30, size=256): + if osp.exists(video_fp): + d = osp.split(video_fp)[0] + fn = prefix(osp.basename(video_fp)) + palette_wfp = osp.join(d, 'palette.png') + gif_wfp = osp.join(d, f'{fn}.gif') + # generate the palette + cmd = f'ffmpeg -i {video_fp} -vf "fps={fps},scale={size}:-1:flags=lanczos,palettegen" {palette_wfp} -y' + exec_cmd(cmd) + # use the palette to generate the gif + cmd = f'ffmpeg -i {video_fp} -i {palette_wfp} -filter_complex "fps={fps},scale={size}:-1:flags=lanczos[x];[x][1:v]paletteuse" {gif_wfp} -y' + exec_cmd(cmd) + else: + print(f'video_fp: {video_fp} not exists!') + + +def merge_audio_video(video_fp, audio_fp, wfp): + if osp.exists(video_fp) and osp.exists(audio_fp): + cmd = f'ffmpeg -i {video_fp} -i {audio_fp} -c:v copy -c:a aac {wfp} -y' + exec_cmd(cmd) + print(f'merge {video_fp} and {audio_fp} to {wfp}') + else: + print(f'video_fp: {video_fp} or audio_fp: {audio_fp} not exists!') + + +def blend(img: np.ndarray, mask: np.ndarray, background_color=(255, 255, 255)): + mask_float = mask.astype(np.float32) / 255. + background_color = np.array(background_color).reshape([1, 1, 3]) + bg = np.ones_like(img) * background_color + img = np.clip(mask_float * img + (1 - mask_float) * bg, 0, 255).astype(np.uint8) + return img + + +def concat_frames(I_p_lst, driving_rgb_lst, img_rgb): + # TODO: add more concat style, e.g., left-down corner driving + out_lst = [] + for idx, _ in track(enumerate(I_p_lst), total=len(I_p_lst), description='Concatenating result...'): + source_image_drived = I_p_lst[idx] + image_drive = driving_rgb_lst[idx] + + # resize images to match source_image_drived shape + h, w, _ = source_image_drived.shape + image_drive_resized = cv2.resize(image_drive, (w, h)) + img_rgb_resized = cv2.resize(img_rgb, (w, h)) + + # concatenate images horizontally + frame = np.concatenate((image_drive_resized, img_rgb_resized, source_image_drived), axis=1) + out_lst.append(frame) + return out_lst + + +class VideoWriter: + def __init__(self, **kwargs): + self.fps = kwargs.get('fps', 30) + self.wfp = kwargs.get('wfp', 'video.mp4') + self.video_format = kwargs.get('format', 'mp4') + self.codec = kwargs.get('codec', 'libx264') + self.quality = kwargs.get('quality') + self.pixelformat = kwargs.get('pixelformat', 'yuv420p') + self.image_mode = kwargs.get('image_mode', 'rgb') + self.ffmpeg_params = kwargs.get('ffmpeg_params') + + self.writer = imageio.get_writer( + self.wfp, fps=self.fps, format=self.video_format, + codec=self.codec, quality=self.quality, + ffmpeg_params=self.ffmpeg_params, pixelformat=self.pixelformat + ) + + def write(self, image): + if self.image_mode.lower() == 'bgr': + self.writer.append_data(image[..., ::-1]) + else: + self.writer.append_data(image) + + def close(self): + if self.writer is not None: + self.writer.close() + + +def change_video_fps(input_file, output_file, fps=20, codec='libx264', crf=5): + cmd = f"ffmpeg -i {input_file} -c:v {codec} -crf {crf} -r {fps} {output_file} -y" + exec_cmd(cmd) + + +def get_fps(filepath): + import ffmpeg + probe = ffmpeg.probe(filepath) + video_stream = next((stream for stream in probe['streams'] if stream['codec_type'] == 'video'), None) + fps = eval(video_stream['avg_frame_rate']) + return fps diff --git a/video2template.py b/video2template.py new file mode 100644 index 0000000..c187396 --- /dev/null +++ b/video2template.py @@ -0,0 +1,37 @@ +# coding: utf-8 + +""" +[WIP] Pipeline for video template preparation +""" + +import tyro +from src.config.crop_config import CropConfig +from src.config.inference_config import InferenceConfig +from src.config.argument_config import ArgumentConfig +from src.template_maker import TemplateMaker + + +def partial_fields(target_class, kwargs): + return target_class(**{k: v for k, v in kwargs.items() if hasattr(target_class, k)}) + + +def main(): + # set tyro theme + tyro.extras.set_accent_color("bright_cyan") + args = tyro.cli(ArgumentConfig) + + # specify configs for inference + inference_cfg = partial_fields(InferenceConfig, args.__dict__) # use attribute of args to initial InferenceConfig + crop_cfg = partial_fields(CropConfig, args.__dict__) # use attribute of args to initial CropConfig + + video_template_maker = TemplateMaker( + inference_cfg=inference_cfg, + crop_cfg=crop_cfg + ) + + # run + video_template_maker.make_motion_template(args.driving_video_path, args.template_output_dir) + + +if __name__ == '__main__': + main()