port from perforce
This commit is contained in:
107
meshToolsV5/TestApp/ObjExporter.cpp
Normal file
107
meshToolsV5/TestApp/ObjExporter.cpp
Normal file
@@ -0,0 +1,107 @@
|
||||
|
||||
#if _DEBUG
|
||||
|
||||
#include "ObjExporter.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
|
||||
void ObjExporter::Export(mt::Mesh* mesh, const std::string& filePath)
|
||||
{
|
||||
ObjExporter exporter(mesh);
|
||||
exporter.Export(filePath);
|
||||
}
|
||||
|
||||
|
||||
ObjExporter::ObjExporter(mt::Mesh* mesh)
|
||||
: mesh{mesh}
|
||||
{
|
||||
}
|
||||
|
||||
void ObjExporter::Export(const std::string& filePath)
|
||||
{
|
||||
std::ostringstream builder;
|
||||
std::ostringstream mtlBuilder;
|
||||
builder << "mtllib " + replace(filePath, ".obj", ".mtl") << std::endl;
|
||||
WritePositions(builder);
|
||||
WriteNormals(builder);
|
||||
WriteUVs(builder);
|
||||
WriteFaceGroups(builder, mtlBuilder);
|
||||
|
||||
std::ofstream objFile(filePath);
|
||||
objFile << builder.str();
|
||||
objFile.close();
|
||||
|
||||
std::ofstream mtlFile(replace(filePath, ".obj", ".mtl"));
|
||||
mtlFile << mtlBuilder.str();
|
||||
mtlFile.close();
|
||||
}
|
||||
|
||||
|
||||
void ObjExporter::WriteFaceGroups(std::ostringstream& builder, std::ostringstream& mtlBuilder)
|
||||
{
|
||||
auto groups = mesh->GetSubMeshs();
|
||||
for(const auto& group : groups)
|
||||
{
|
||||
auto materialId = group->Key;
|
||||
|
||||
builder << "usemtl " << materialId << std::endl;
|
||||
builder << "g " << materialId << std::endl;
|
||||
|
||||
WriteFaces(builder, group->Value);
|
||||
|
||||
mtlBuilder << "newmtl " << materialId << std::endl;
|
||||
mtlBuilder << "Ka 0.0 0.0 0.0" << std::endl;
|
||||
mtlBuilder << "Kd 1.0 1.0 1.0" << std::endl;
|
||||
mtlBuilder << "Ks 1.0 1.0 1.0" << std::endl;
|
||||
mtlBuilder << "Ns 16.0" << std::endl;
|
||||
mtlBuilder << "illum 0" << std::endl;
|
||||
|
||||
mtlBuilder << "map_Kd " << materialId << ".png" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ObjExporter::WriteFaces(std::ostringstream& builder, const mt::FaceList& faces)
|
||||
{
|
||||
for (auto face : faces)
|
||||
{
|
||||
auto indices = face->GetIndices(true);
|
||||
|
||||
builder << "f";
|
||||
for (int i = 0; i < indices.Count(); ++i)
|
||||
{
|
||||
builder << " ";
|
||||
auto index = indices[i] + 1;
|
||||
builder << index << "/" << index << "/" << index;
|
||||
}
|
||||
builder << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void ObjExporter::WritePositions(std::ostringstream& builder)
|
||||
{
|
||||
for (const auto& v : mesh->GetVertices())
|
||||
{
|
||||
builder << "v " << v->Position.x << " " << v->Position.y << " " << v->Position.z << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void ObjExporter::WriteNormals(std::ostringstream& builder)
|
||||
{
|
||||
for (const auto& v : mesh->GetVertices())
|
||||
{
|
||||
auto normal = v->GetNormal();
|
||||
builder << "vn " << normal.x << " " << normal.y << " " << normal.z << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void ObjExporter::WriteUVs(std::ostringstream& builder)
|
||||
{
|
||||
for (const auto& v : mesh->GetVertices())
|
||||
{
|
||||
builder << "vt " << v->UV[0] << " " << v->UV[1] << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
44
meshToolsV5/TestApp/ObjExporter.h
Normal file
44
meshToolsV5/TestApp/ObjExporter.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
#if _DEBUG
|
||||
|
||||
#include "../src/Lib/mt/mt.h"
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
class Mesh;
|
||||
|
||||
class ObjExporter
|
||||
{
|
||||
public:
|
||||
static void Export(mt::Mesh* mesh, const std::string& filePath);
|
||||
|
||||
ObjExporter(mt::Mesh* mesh);
|
||||
void Export(const std::string& filePath);
|
||||
void WriteFaceGroups(std::ostringstream& builder, std::ostringstream& mtlBuilder);
|
||||
void WriteFaces(std::ostringstream& builder, const mt::FaceList& faces);
|
||||
void WritePositions(std::ostringstream& builder);
|
||||
void WriteNormals(std::ostringstream& builder);
|
||||
void WriteUVs(std::ostringstream& builder);
|
||||
|
||||
private:
|
||||
std::string replace(const std::string &input, const std::string &search, const std::string &replace)
|
||||
{
|
||||
auto s = input;
|
||||
for (size_t pos = 0;; pos += replace.length())
|
||||
{
|
||||
// Locate the substring to replace
|
||||
pos = s.find(search, pos);
|
||||
if (pos == std::string::npos) break;
|
||||
// Replace by erasing and inserting
|
||||
s.erase(pos, search.length());
|
||||
s.insert(pos, replace);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
private:
|
||||
mt::Mesh* mesh;
|
||||
};
|
||||
|
||||
#endif
|
||||
40
meshToolsV5/TestApp/ReadMe.txt
Normal file
40
meshToolsV5/TestApp/ReadMe.txt
Normal file
@@ -0,0 +1,40 @@
|
||||
========================================================================
|
||||
CONSOLE APPLICATION : TestApp Project Overview
|
||||
========================================================================
|
||||
|
||||
AppWizard has created this TestApp application for you.
|
||||
|
||||
This file contains a summary of what you will find in each of the files that
|
||||
make up your TestApp application.
|
||||
|
||||
|
||||
TestApp.vcxproj
|
||||
This is the main project file for VC++ projects generated using an Application Wizard.
|
||||
It contains information about the version of Visual C++ that generated the file, and
|
||||
information about the platforms, configurations, and project features selected with the
|
||||
Application Wizard.
|
||||
|
||||
TestApp.vcxproj.filters
|
||||
This is the filters file for VC++ projects generated using an Application Wizard.
|
||||
It contains information about the association between the files in your project
|
||||
and the filters. This association is used in the IDE to show grouping of files with
|
||||
similar extensions under a specific node (for e.g. ".cpp" files are associated with the
|
||||
"Source Files" filter).
|
||||
|
||||
TestApp.cpp
|
||||
This is the main application source file.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
Other standard files:
|
||||
|
||||
StdAfx.h, StdAfx.cpp
|
||||
These files are used to build a precompiled header (PCH) file
|
||||
named TestApp.pch and a precompiled types file named StdAfx.obj.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
Other notes:
|
||||
|
||||
AppWizard uses "TODO:" comments to indicate parts of the source code you
|
||||
should add to or customize.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
161
meshToolsV5/TestApp/TestApp.cpp
Normal file
161
meshToolsV5/TestApp/TestApp.cpp
Normal file
@@ -0,0 +1,161 @@
|
||||
// TestApp.cpp : Defines the entry point for the console application.
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "../src/Lib/mt/mt.h"
|
||||
#include "ObjExporter.h"
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
auto mesh = mt::CreateSphere(2);
|
||||
|
||||
const int FFD_X = 2;
|
||||
const int FFD_Y = 5;
|
||||
const int FFD_Z = 5;
|
||||
|
||||
auto ffd = new mt::FFD(mesh->GetFaces(), FFD_X, FFD_Y, FFD_Z, mt::FFD::FFDControlPointMode::Surface);
|
||||
|
||||
// Bring the skull shape in form for the top view [DONE]
|
||||
auto selection = ffd->SelectPoints(0, FFD_X, 0, FFD_Y, 0, FFD_Z); // Select all FFD Points
|
||||
for (const auto& v : selection)
|
||||
{
|
||||
v->x *= 1 + (0.3f * (v->z + 0.5f));
|
||||
v->z *= 1.5f;
|
||||
}
|
||||
|
||||
// Shape the back view [DONE]
|
||||
selection = ffd->SelectPoints(0, FFD_X, 0, 0, 0, FFD_Z); // Select all bottom Points
|
||||
for (const auto& v : selection)
|
||||
{
|
||||
v->x *= 1.75f;
|
||||
}
|
||||
|
||||
// Shape the side view (Cheek) [DONE]
|
||||
selection = ffd->SelectPoints(0, FFD_X, 0, 2, 2, 2);
|
||||
for (const auto& v : selection)
|
||||
{
|
||||
v->y = v->y * 0.5f + 0.5f;
|
||||
}
|
||||
|
||||
// Shape the side view (Nose) [Done]
|
||||
selection = ffd->SelectPoints(1, 1, 0, 2, 0, 0);
|
||||
//selection.Add(&ffd->ControlPoints[1][0][1]);
|
||||
for (const auto& v : selection)
|
||||
{
|
||||
v->y -= 0.75f;
|
||||
}
|
||||
|
||||
// Generell vertical upscale
|
||||
selection = ffd->SelectPoints(0, FFD_X, 0, FFD_Y, 0, FFD_Z);
|
||||
for (const auto& v : selection)
|
||||
{
|
||||
v->y *= 1.25f;
|
||||
}
|
||||
|
||||
// Fix the back part of the head which is really high above [Done]
|
||||
selection = ffd->SelectPoints(0, FFD_X, 5, 5, FFD_Z, FFD_Z);
|
||||
for (const auto& v : selection)
|
||||
{
|
||||
v->y += 0.4f;
|
||||
v->z += 0.4f;
|
||||
}
|
||||
|
||||
// Descale the length of the head [Done]
|
||||
selection = ffd->SelectPoints(0, FFD_X, 0, FFD_Y, 0, 2);
|
||||
for (const auto& v : selection)
|
||||
{
|
||||
v->z *= 0.9f;
|
||||
}
|
||||
|
||||
//ffd->DrawFFDGrid(mesh, 0.025f, &selection);
|
||||
//ffd->DumpFFDGridPositions();
|
||||
ffd->Apply();
|
||||
|
||||
// Despike the chin [Done]
|
||||
auto chinVertex = mesh->GetVertices()[38];
|
||||
// chinVertex->Position.y += 0.1f;
|
||||
|
||||
// Dechamfer chin
|
||||
int chinIndices[] = { 51, 53, 55 }; // 3
|
||||
auto chinVertices = mesh->GetVertices().GetSubset(chinIndices, 3);
|
||||
/*auto chinVertices = mt::GetVerticesOnPositivePlane(mesh->GetVertices(), mt::Plane(mt::vec3::back, mt::vec3::zero));
|
||||
chinVertices = mt::GetVerticesOnPositivePlane(chinVertices, mt::Plane(mt::vec3::forward, mt::vec3::back * 0.25f));
|
||||
chinVertices = mt::GetVerticesOnPositivePlane(chinVertices, mt::Plane(mt::vec3::down, mt::vec3::down * 0.2f));
|
||||
mt::DumpIndicies(chinVertices, mesh->GetVertices());
|
||||
mt::DisplayVertices(chinVertices, 0.1f, mesh);*/
|
||||
|
||||
for (const auto& v : chinVertices)
|
||||
v->Position.z -= 0.05f;
|
||||
|
||||
auto faceSelection = mt::GetFacesOnPositivePlane(mesh->GetFaces(), { mt::vec3::down, mt::vec3::zero });
|
||||
faceSelection = mt::GetFacesOnPositivePlane(faceSelection, { mt::vec3::forward, mt::vec3::back * 0.25f });
|
||||
//faceSelection = mt::GetFacesOnPositivePlane(faceSelection, { mt::vec3::back, mt::vec3::forward * 0.25f });
|
||||
|
||||
ffd = new mt::FFD(faceSelection, 1, 1, 1, mt::FFD::FFDControlPointMode::Surface);
|
||||
selection = ffd->SelectPoints(0, 1, 0, 0, 0, 0);
|
||||
for (const auto& v : selection)
|
||||
{
|
||||
v->x *= 0.5f;
|
||||
}
|
||||
|
||||
//ffd->DrawFFDGrid(mesh, 0.025f, &selection);
|
||||
//ffd->DumpFFDGridPositions();
|
||||
ffd->Apply();
|
||||
|
||||
faceSelection = mt::GetFacesOnPositivePlane(mesh->GetFaces(), { mt::vec3::left, mt::vec3::zero });
|
||||
mt::Delete(faceSelection);
|
||||
//faceSelection.Clear();
|
||||
//faceSelection.Add(mesh->GetFaces()[2]);
|
||||
//faceSelection.Add(mesh->GetFaces()[6]);
|
||||
//mt::Split(faceSelection, {mt::vec3::up, mt::vec3::zero});
|
||||
|
||||
// Dat eye socket
|
||||
mt::vec3 eyeCenter = { 0.22f, -0.05f, -0.5f };
|
||||
auto eyeBall = mt::CreateSphere(1, eyeCenter, 0.35f);
|
||||
mt::Scale(eyeBall->GetVertices(), { 1, 0.7f, 2.0f });
|
||||
mt::Rotate(eyeBall->GetVertices(), eyeCenter, mt::vec3::forward, -0.3f);
|
||||
|
||||
// De noze
|
||||
mt::vec3 nostrilCenter = { 0.2f, -0.25f, -0.5f };
|
||||
auto nostril = mt::CreateSphere(1, nostrilCenter, 0.45f);
|
||||
ffd = new mt::FFD(nostril->GetFaces(), 1, 1, 1, mt::FFD::FFDControlPointMode::Surface);
|
||||
selection = ffd->SelectPoints(0, 1, 1, 1, 0, 1);
|
||||
for (const auto& v : selection)
|
||||
{
|
||||
v->x *= 0.8f;
|
||||
}
|
||||
|
||||
selection = ffd->SelectPoints(0, 1, 0, 1, 0, 1);
|
||||
for (const auto& v : selection)
|
||||
{
|
||||
v->x = v->x * 0.5f - 0.1f;
|
||||
v->y *= 0.65f;
|
||||
}
|
||||
|
||||
selection = ffd->SelectPoints(1, 1, 0, 0, 0, 1);
|
||||
for (const auto& v : selection)
|
||||
{
|
||||
v->y -= 0.05f;
|
||||
}
|
||||
|
||||
ffd->Apply();
|
||||
|
||||
for (const auto& v : nostril->GetVertices())
|
||||
v->Position.x = v->Position.x < 0.004f ? 0.004f : v->Position.x;
|
||||
|
||||
mt::CloneToMesh(nostril->GetFaces(), eyeBall);
|
||||
mesh = mt::CsgSubtract(mesh->GetFaces(), eyeBall->GetFaces());
|
||||
|
||||
auto vertices = mesh->GetVertices();
|
||||
mt::Weld(vertices);
|
||||
faceSelection = mt::Clone(mesh->GetFaces());
|
||||
|
||||
mt::Mirror(faceSelection, { mt::vec3::right, mt::vec3::zero });
|
||||
|
||||
//mt::Subdivide(mesh->GetFaces(), true);
|
||||
|
||||
ObjExporter::Export(mesh, "mesh.obj");
|
||||
return 0;
|
||||
}
|
||||
|
||||
163
meshToolsV5/TestApp/TestApp.vcxproj
Normal file
163
meshToolsV5/TestApp/TestApp.vcxproj
Normal file
@@ -0,0 +1,163 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{0E9C6FB6-B6ED-407B-A868-3157BC58EC02}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>TestApp</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(IncludePath)</IncludePath>
|
||||
<LibraryPath>D:\Repositories\blu-flame.org\meshToolsV5\lib\Debug;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>Lib.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="ReadMe.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ObjExporter.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ObjExporter.cpp" />
|
||||
<ClCompile Include="stdafx.cpp" />
|
||||
<ClCompile Include="TestApp.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
42
meshToolsV5/TestApp/TestApp.vcxproj.filters
Normal file
42
meshToolsV5/TestApp/TestApp.vcxproj.filters
Normal file
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="ReadMe.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="targetver.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ObjExporter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TestApp.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ObjExporter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
6
meshToolsV5/TestApp/TestApp.vcxproj.user
Normal file
6
meshToolsV5/TestApp/TestApp.vcxproj.user
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ShowAllFiles>true</ShowAllFiles>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
8
meshToolsV5/TestApp/stdafx.cpp
Normal file
8
meshToolsV5/TestApp/stdafx.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// TestApp.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: reference any additional headers you need in STDAFX.H
|
||||
// and not in this file
|
||||
15
meshToolsV5/TestApp/stdafx.h
Normal file
15
meshToolsV5/TestApp/stdafx.h
Normal file
@@ -0,0 +1,15 @@
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "targetver.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
|
||||
|
||||
|
||||
// TODO: reference additional headers your program requires here
|
||||
8
meshToolsV5/TestApp/targetver.h
Normal file
8
meshToolsV5/TestApp/targetver.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
// Including SDKDDKVer.h defines the highest available Windows platform.
|
||||
|
||||
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
|
||||
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
|
||||
|
||||
#include <SDKDDKVer.h>
|
||||
59
meshToolsV5/meshToolsV5.sln
Normal file
59
meshToolsV5/meshToolsV5.sln
Normal file
@@ -0,0 +1,59 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29920.165
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Editor", "src\Editor\Editor.csproj", "{8AF5E6D2-4E9C-4D08-9189-1FBD6F1334AD}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{FDEBD01E-0317-4400-9208-58D7DD7CEE44} = {FDEBD01E-0317-4400-9208-58D7DD7CEE44}
|
||||
{EB7F77A5-EBA2-4EF4-BDD2-02E961B0E256} = {EB7F77A5-EBA2-4EF4-BDD2-02E961B0E256}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Lib", "src\Lib\Lib.vcxproj", "{FDEBD01E-0317-4400-9208-58D7DD7CEE44}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{EB7F77A5-EBA2-4EF4-BDD2-02E961B0E256} = {EB7F77A5-EBA2-4EF4-BDD2-02E961B0E256}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Interop", "src\Interop\Interop.vcxproj", "{306104A5-EEEE-4789-847A-07869D715550}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{FDEBD01E-0317-4400-9208-58D7DD7CEE44} = {FDEBD01E-0317-4400-9208-58D7DD7CEE44}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Codegen", "src\Codegen\Codegen.csproj", "{EB7F77A5-EBA2-4EF4-BDD2-02E961B0E256}"
|
||||
EndProject
|
||||
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Editor.Operators", "src\Editor.Operators\Editor.Operators.shproj", "{01F4EA18-A795-416A-AE63-7680E87C0931}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SharedMSBuildProjectFiles) = preSolution
|
||||
src\Editor.Operators\Editor.Operators.projitems*{01f4ea18-a795-416a-ae63-7680e87c0931}*SharedItemsImports = 13
|
||||
src\Editor.Operators\Editor.Operators.projitems*{8af5e6d2-4e9c-4d08-9189-1fbd6f1334ad}*SharedItemsImports = 4
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{8AF5E6D2-4E9C-4D08-9189-1FBD6F1334AD}.Debug|Win32.ActiveCfg = Debug|x86
|
||||
{8AF5E6D2-4E9C-4D08-9189-1FBD6F1334AD}.Debug|Win32.Build.0 = Debug|x86
|
||||
{8AF5E6D2-4E9C-4D08-9189-1FBD6F1334AD}.Release|Win32.ActiveCfg = Release|x86
|
||||
{8AF5E6D2-4E9C-4D08-9189-1FBD6F1334AD}.Release|Win32.Build.0 = Release|x86
|
||||
{FDEBD01E-0317-4400-9208-58D7DD7CEE44}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{FDEBD01E-0317-4400-9208-58D7DD7CEE44}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{FDEBD01E-0317-4400-9208-58D7DD7CEE44}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{FDEBD01E-0317-4400-9208-58D7DD7CEE44}.Release|Win32.Build.0 = Release|Win32
|
||||
{306104A5-EEEE-4789-847A-07869D715550}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{306104A5-EEEE-4789-847A-07869D715550}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{306104A5-EEEE-4789-847A-07869D715550}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{306104A5-EEEE-4789-847A-07869D715550}.Release|Win32.Build.0 = Release|Win32
|
||||
{EB7F77A5-EBA2-4EF4-BDD2-02E961B0E256}.Debug|Win32.ActiveCfg = Debug|x86
|
||||
{EB7F77A5-EBA2-4EF4-BDD2-02E961B0E256}.Debug|Win32.Build.0 = Debug|x86
|
||||
{EB7F77A5-EBA2-4EF4-BDD2-02E961B0E256}.Release|Win32.ActiveCfg = Release|x86
|
||||
{EB7F77A5-EBA2-4EF4-BDD2-02E961B0E256}.Release|Win32.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {46C9A196-4DC8-4282-885E-B2258D00D4CC}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
6
meshToolsV5/src/Codegen/App.config
Normal file
6
meshToolsV5/src/Codegen/App.config
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
|
||||
</startup>
|
||||
</configuration>
|
||||
63
meshToolsV5/src/Codegen/Codegen.csproj
Normal file
63
meshToolsV5/src/Codegen/Codegen.csproj
Normal file
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{EB7F77A5-EBA2-4EF4-BDD2-02E961B0E256}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Codegen</RootNamespace>
|
||||
<AssemblyName>Codegen</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>..\..\bin\Debug\</OutputPath>
|
||||
<BaseIntermediateOutputPath>..\..\obj\Debug\Codegen\</BaseIntermediateOutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>..\..\bin\Release\</OutputPath>
|
||||
<BaseIntermediateOutputPath>..\..\obj\Release\Codegen\</BaseIntermediateOutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
504
meshToolsV5/src/Codegen/Program.cs
Normal file
504
meshToolsV5/src/Codegen/Program.cs
Normal file
@@ -0,0 +1,504 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Codegen
|
||||
{
|
||||
class Program
|
||||
{
|
||||
class OpParam
|
||||
{
|
||||
public OpParam(string sTypeName, string sParamName, string sDefaultValue)
|
||||
{
|
||||
TypeName = sTypeName;
|
||||
ParamName = sParamName;
|
||||
DefaultValue = sDefaultValue;
|
||||
}
|
||||
|
||||
public string Min;
|
||||
public string Max;
|
||||
public string Step;
|
||||
public string Description;
|
||||
public string DisplayName;
|
||||
public string DefaultValue;
|
||||
public string ParamName;
|
||||
public string TypeName;
|
||||
public string CleanType;
|
||||
public bool NeedsIndex;
|
||||
public bool IsConst;
|
||||
public bool IsPtr;
|
||||
}
|
||||
|
||||
class OpLines
|
||||
{
|
||||
public List<string> MetaData;
|
||||
public string Definition;
|
||||
public string Name;
|
||||
public Dictionary<string, OpParam> Parameters;
|
||||
public string ToolTip;
|
||||
public int Index;
|
||||
|
||||
public virtual void WriteOp(StreamWriter _opWriter)
|
||||
{
|
||||
_opWriter.WriteLine("\t\t\tcase " + Index + ":");
|
||||
_opWriter.WriteLine("\t\t\t\t{");
|
||||
|
||||
var paramList = new List<string>();
|
||||
foreach (var kvp in Parameters)
|
||||
{
|
||||
var sName = kvp.Key;
|
||||
var param = kvp.Value;
|
||||
|
||||
paramList.Add(sName);
|
||||
|
||||
if (param.NeedsIndex)
|
||||
{
|
||||
_opWriter.WriteLine("\t\t\t\t\tauto " + sName + "Index = *((unsigned short*)data); data += sizeof(unsigned short);");
|
||||
string sPtr = !param.IsPtr ? "*" : "";
|
||||
if (param.IsConst)
|
||||
{
|
||||
_opWriter.WriteLine("\t\t\t\t\t" + param.TypeName + " " + sName + " = " + sPtr + "(" + param.CleanType + "*)r[" + sName + "Index];");
|
||||
}
|
||||
else
|
||||
{
|
||||
_opWriter.WriteLine("\t\t\t\t\t" + param.TypeName + " " + sName + " = " + sPtr + "(" + param.CleanType + "*)(r[" + sName + "Index] = new " + param.CleanType + "());");
|
||||
}
|
||||
}
|
||||
else if (param.TypeName == "bool")
|
||||
{
|
||||
_opWriter.WriteLine("\t\t\t\t\tbool " + sName + " = *((unsigned char*)data) == 1; data += sizeof(unsigned char);");
|
||||
}
|
||||
else
|
||||
{
|
||||
_opWriter.WriteLine("\t\t\t\t\t" + param.TypeName + " " + sName + " = *((" + param.CleanType + "*)data); data += sizeof(" + param.CleanType + ");");
|
||||
}
|
||||
}
|
||||
_opWriter.WriteLine("\t\t\t\t\top::" + Name + "(" + string.Join(", ", paramList) + ");");
|
||||
_opWriter.WriteLine("\t\t\t\t}");
|
||||
_opWriter.WriteLine("\t\t\t\tbreak;");
|
||||
}
|
||||
|
||||
public virtual void ParseMetaData()
|
||||
{
|
||||
var defTokens = Definition.Split(' ', '(');
|
||||
Name = defTokens[1];
|
||||
|
||||
var start = Definition.IndexOf('(');
|
||||
var end = Definition.IndexOf(')');
|
||||
var args = Definition.Substring(start + 1, end - start - 1).Split(',').Select(a => a.Trim());
|
||||
Parameters = new Dictionary<string, OpParam>();
|
||||
foreach (var arg in args)
|
||||
{
|
||||
var argTokens = arg.Split(' ');
|
||||
int i = 0;
|
||||
string sTypeName = "";
|
||||
string sCleanType = "";
|
||||
bool bConst = false;
|
||||
if (argTokens[i] == "const")
|
||||
{
|
||||
sTypeName = "const ";
|
||||
bConst = true;
|
||||
++i;
|
||||
}
|
||||
sCleanType = argTokens[i++];
|
||||
sTypeName += sCleanType;
|
||||
sCleanType = sCleanType.Replace("&", "").Replace("*", "");
|
||||
bool bNeedsIndex = sCleanType == "OpMesh" || (sTypeName.Contains("*") || sTypeName.Contains("&"));
|
||||
bool bIsPtr = sTypeName.Contains("*");
|
||||
var sParamName = argTokens[i++];
|
||||
|
||||
string sDefaultValue = "";
|
||||
if (argTokens.Length > i && argTokens[i++] == "=")
|
||||
sDefaultValue = argTokens[i];
|
||||
|
||||
Parameters[sParamName] = new OpParam(sTypeName, sParamName, sDefaultValue) { NeedsIndex = bNeedsIndex, CleanType = sCleanType, IsConst = bConst, IsPtr = bIsPtr };
|
||||
}
|
||||
|
||||
foreach (var data in MetaData)
|
||||
{
|
||||
start = data.IndexOf('[');
|
||||
end = data.IndexOf(']');
|
||||
if (start == -1)
|
||||
continue;
|
||||
|
||||
var mdName = data.Substring(start + 1, end - start - 1);
|
||||
if (mdName == "toolTip")
|
||||
{
|
||||
ToolTip = data.Substring(end + 1).Trim();
|
||||
}
|
||||
else if (Parameters.ContainsKey(mdName))
|
||||
{
|
||||
var opParam = Parameters[mdName];
|
||||
var props = data.Substring(end + 1).Trim();
|
||||
while (true)
|
||||
{
|
||||
start = props.IndexOf('"');
|
||||
if (start == -1)
|
||||
break;
|
||||
|
||||
end = props.Substring(start + 1).IndexOf('"') + start + 2;
|
||||
var property = props.Substring(0, end);
|
||||
var propTokens = property.Split('=');
|
||||
var propName = propTokens[0];
|
||||
var propValue = propTokens[1].Substring(1, propTokens[1].Length - 2);
|
||||
switch (propTokens[0])
|
||||
{
|
||||
case "DisplayName": opParam.DisplayName = propValue; break;
|
||||
case "Min": opParam.Min = propValue; break;
|
||||
case "Max": opParam.Max = propValue; break;
|
||||
case "Step": opParam.Step = propValue; break;
|
||||
case "Description": opParam.Description = propValue; break;
|
||||
}
|
||||
props = props.Substring(end).Trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class OpLoop : OpLines
|
||||
{
|
||||
public override void ParseMetaData()
|
||||
{
|
||||
Name = "Loop";
|
||||
ToolTip = "Simple operator for iterating integer values";
|
||||
Parameters = new Dictionary<string, OpParam>();
|
||||
Parameters["From"] = new OpParam("ushort", "From", "0") { DisplayName = "From", Description = "Initial value for the iteration integer", CleanType = "ushort" };
|
||||
Parameters["To"] = new OpParam("ushort", "To", "0") { DisplayName = "To", Description = "Upper bound (exclusive) for the iteration integer", CleanType = "ushort" };
|
||||
Parameters["GroupId"] = new OpParam("ushort", "GroupId", "0") { DisplayName = "Group ID", Description = "Group to execute during every iteration", CleanType = "ushort" };
|
||||
Parameters["LoopVarIndex"] = new OpParam("ushort", "LoopVarIndex", "0") { DisplayName = "Loop variable ID", Description = "Index where to store the loop integer", CleanType = "ushort" };
|
||||
}
|
||||
|
||||
public override void WriteOp(StreamWriter _opWriter)
|
||||
{
|
||||
_opWriter.WriteLine("\t\t\tcase " + Index + ": // Loop");
|
||||
_opWriter.WriteLine("\t\t\t\t{");
|
||||
_opWriter.WriteLine("\t\t\t\t\tauto iFrom = *((unsigned short*)data); data += sizeof(unsigned short); ");
|
||||
_opWriter.WriteLine("\t\t\t\t\tauto iTo = *((unsigned short*)data); data += sizeof(unsigned short); ");
|
||||
_opWriter.WriteLine("\t\t\t\t\tauto iGroupId = *((unsigned short*)data); data += sizeof(unsigned short); ");
|
||||
_opWriter.WriteLine("\t\t\t\t\tauto iLoopVarIndex = *((unsigned short*)data); data += sizeof(unsigned short); ");
|
||||
_opWriter.WriteLine("\t\t\t\t\tauto loopVar = new int[1]; r[iLoopVarIndex] = new int(); ");
|
||||
_opWriter.WriteLine("\t\t\t\t\tfor (*loopVar = iFrom; *loopVar < iTo; (*loopVar)++)");
|
||||
_opWriter.WriteLine("\t\t\t\t\t{");
|
||||
_opWriter.WriteLine("\t\t\t\t\t\tauto groupData = (unsigned char*)r[iGroupId]; ");
|
||||
_opWriter.WriteLine("\t\t\t\t\t\tauto iOpCount = *((unsigned short*)groupData); groupData += sizeof(unsigned short); ");
|
||||
_opWriter.WriteLine("\t\t\t\t\t\tfor (auto i = 0u; i < iOpCount; ++i) ");
|
||||
_opWriter.WriteLine("\t\t\t\t\t\t{");
|
||||
_opWriter.WriteLine("\t\t\t\t\t\t\tmt::ParseOp(r, &groupData); ");
|
||||
_opWriter.WriteLine("\t\t\t\t\t\t}");
|
||||
_opWriter.WriteLine("\t\t\t\t\t}");
|
||||
_opWriter.WriteLine("\t\t\t\t\tdelete [] loopVar;");
|
||||
_opWriter.WriteLine("\t\t\t\t}");
|
||||
_opWriter.WriteLine("\t\t\t\tbreak;");
|
||||
}
|
||||
}
|
||||
|
||||
class OpGroup : OpLines
|
||||
{
|
||||
public override void ParseMetaData()
|
||||
{
|
||||
Name = "Group";
|
||||
ToolTip = "Simple operator for grouping operators";
|
||||
Parameters = new Dictionary<string, OpParam>();
|
||||
Parameters["GroupId"] = new OpParam("ushort", "GroupId", "0") { DisplayName = "Group ID", Description = "Index of this group", CleanType = "ushort" };
|
||||
}
|
||||
|
||||
public override void WriteOp(StreamWriter _opWriter)
|
||||
{
|
||||
_opWriter.WriteLine("\t\t\tcase " + Index + ": // Grouping");
|
||||
_opWriter.WriteLine("\t\t\t\t{");
|
||||
_opWriter.WriteLine("\t\t\t\t\tauto iGroupId = *((unsigned short*)data); data += sizeof(unsigned short);");
|
||||
_opWriter.WriteLine("\t\t\t\t\tauto groupData = (unsigned char*)r[iGroupId];");
|
||||
_opWriter.WriteLine("\t\t\t\t\tauto iOpCount = *((unsigned short*)groupData); groupData += sizeof(unsigned short);");
|
||||
_opWriter.WriteLine("\t\t\t\t\tfor (auto i = 0u; i < iOpCount; ++i)");
|
||||
_opWriter.WriteLine("\t\t\t\t\t{");
|
||||
_opWriter.WriteLine("\t\t\t\t\t\tmt::ParseOp(r, &groupData);");
|
||||
_opWriter.WriteLine("\t\t\t\t\t}");
|
||||
_opWriter.WriteLine("\t\t\t\t}");
|
||||
_opWriter.WriteLine("\t\t\t\tbreak;");
|
||||
}
|
||||
}
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
var sDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
var iIndex = sDir.IndexOf("meshToolsV5");
|
||||
sDir = sDir.Substring(0, iIndex + 11);
|
||||
|
||||
var sInputFile = Path.Combine(sDir, "src\\Lib\\mt\\operators\\operators.h");
|
||||
var sOpsFile = Path.Combine(sDir, "src\\Lib\\mt\\parser\\ops.h");
|
||||
var sEditDir = Path.Combine(sDir, "src\\Editor.Operators");
|
||||
var sOpsProjectFile = Path.Combine(sEditDir, "Editor.Operators.projitems");
|
||||
|
||||
var lines = File.ReadAllLines(sInputFile);
|
||||
int i = 0;
|
||||
while (!lines[i++].Trim().StartsWith("namespace op"));
|
||||
while (lines[i++].Trim() != "{");
|
||||
|
||||
int index = 0;
|
||||
var ops = new List<OpLines>();
|
||||
|
||||
var groupOp = new OpGroup() { Index = index++ };
|
||||
groupOp.ParseMetaData();
|
||||
ops.Add(groupOp);
|
||||
|
||||
var loopOp = new OpLoop() { Index = index++ };
|
||||
loopOp.ParseMetaData();
|
||||
ops.Add(loopOp);
|
||||
|
||||
while (i < lines.Length) // All ops
|
||||
{
|
||||
if (lines[i].Trim() == "}")
|
||||
break;
|
||||
|
||||
var op = new OpLines() { MetaData = new List<string>() };
|
||||
while (i < lines.Length) // One op
|
||||
{
|
||||
var head = lines[i++].Trim();
|
||||
if (head.StartsWith("//"))
|
||||
{
|
||||
op.MetaData.Add(head.Substring(2));
|
||||
}
|
||||
else if (head.StartsWith("void"))
|
||||
{
|
||||
op.Definition = head;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(op.Definition))
|
||||
{
|
||||
op.ParseMetaData();
|
||||
op.Index = index++;
|
||||
ops.Add(op);
|
||||
}
|
||||
}
|
||||
|
||||
using (var opStream = new FileStream(sOpsFile, FileMode.Create))
|
||||
{
|
||||
using (var opWriter = new StreamWriter(opStream))
|
||||
{
|
||||
opWriter.WriteLine("// Autogenerated file");
|
||||
opWriter.WriteLine("#pragma once\n");
|
||||
opWriter.WriteLine("namespace mt");
|
||||
opWriter.WriteLine("{");
|
||||
opWriter.WriteLine("\tvoid ParseOp(void** r, unsigned char** dataPtr)");
|
||||
opWriter.WriteLine("\t{");
|
||||
opWriter.WriteLine("\t\tauto data = *dataPtr;\n");
|
||||
opWriter.WriteLine("\t\tauto opId = *((unsigned short*)data); data += sizeof(unsigned short);");
|
||||
opWriter.WriteLine("\t\tswitch (opId)");
|
||||
opWriter.WriteLine("\t\t{");
|
||||
|
||||
foreach (var op in ops)
|
||||
{
|
||||
op.WriteOp(opWriter);
|
||||
WriteOpClass(sEditDir, op);
|
||||
}
|
||||
|
||||
opWriter.WriteLine("\t\t}\n");
|
||||
opWriter.WriteLine("\t\t*dataPtr = data; ");
|
||||
opWriter.WriteLine("\t}");
|
||||
opWriter.WriteLine("}\n");
|
||||
}
|
||||
}
|
||||
|
||||
var sTempFile = Path.GetTempFileName();
|
||||
using (var stream = new FileStream(sTempFile, FileMode.Create))
|
||||
{
|
||||
using (var writer = new StreamWriter(stream))
|
||||
{
|
||||
writer.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
|
||||
writer.WriteLine("<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">");
|
||||
writer.WriteLine(" <PropertyGroup>");
|
||||
writer.WriteLine(" <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>");
|
||||
writer.WriteLine(" <SharedGUID>01f4ea18-a795-416a-ae63-7680e87c0931</SharedGUID>");
|
||||
writer.WriteLine(" </PropertyGroup>");
|
||||
writer.WriteLine(" <PropertyGroup Label=\"Configuration\">");
|
||||
writer.WriteLine(" <Import_RootNamespace>Editor.Operators</Import_RootNamespace>");
|
||||
writer.WriteLine(" </PropertyGroup>");
|
||||
writer.WriteLine(" <ItemGroup>");
|
||||
foreach (var op in ops)
|
||||
{
|
||||
writer.WriteLine(" <Compile Include=\"$(MSBuildThisFileDirectory)" + op.Name + ".cs\" />");
|
||||
}
|
||||
writer.WriteLine(" </ItemGroup>");
|
||||
writer.WriteLine("</Project>");
|
||||
}
|
||||
}
|
||||
|
||||
if (File.ReadAllText(sTempFile) != File.ReadAllText(sOpsProjectFile))
|
||||
{
|
||||
File.Copy(sTempFile, sOpsProjectFile, true);
|
||||
}
|
||||
|
||||
File.Delete(sTempFile);
|
||||
}
|
||||
|
||||
private static void WriteOpClass(string sEditDir, OpLines op)
|
||||
{
|
||||
var sPath = Path.Combine(sEditDir, op.Name + ".cs");
|
||||
using (var stream = new FileStream(sPath, FileMode.Create))
|
||||
{
|
||||
using (var writer = new StreamWriter(stream))
|
||||
{
|
||||
writer.WriteLine("using System.ComponentModel;");
|
||||
writer.WriteLine("using System.IO;");
|
||||
writer.WriteLine("using Editor.Attributes;\n");
|
||||
writer.WriteLine("namespace Editor.Operators");
|
||||
writer.WriteLine("{");
|
||||
writer.WriteLine("\tpublic class " + op.Name + " : OperatorBase");
|
||||
writer.WriteLine("\t{");
|
||||
writer.WriteLine("\t\tpublic override ushort OpId { get { return " + op.Index + "; } }\n");
|
||||
|
||||
var parameters = new List<Tuple<string, string>>();
|
||||
foreach (var kvp in op.Parameters)
|
||||
{
|
||||
var sName = CultureInfo.InvariantCulture.TextInfo.ToTitleCase(kvp.Key);
|
||||
var param = kvp.Value;
|
||||
|
||||
var sType = param.CleanType;
|
||||
if (param.NeedsIndex)
|
||||
{
|
||||
writer.WriteLine("\t\t[IndexedType(\"" + sType + "\")]");
|
||||
sName += "Index";
|
||||
sType = "ushort";
|
||||
}
|
||||
|
||||
parameters.Add(Tuple.Create(sName, sType));
|
||||
|
||||
if (!string.IsNullOrEmpty(param.DefaultValue))
|
||||
{
|
||||
if (!param.CleanType.StartsWith("vec"))
|
||||
{
|
||||
writer.WriteLine("\t\t[DefaultValue(" + param.DefaultValue + ")]");
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(param.Description))
|
||||
{
|
||||
writer.WriteLine("\t\t[Description(\"" + param.Description + "\")]");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(param.DisplayName))
|
||||
{
|
||||
writer.WriteLine("\t\t[DisplayName(\"" + param.DisplayName + "\")]");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(param.Max))
|
||||
{
|
||||
writer.WriteLine("\t\t[Max(\"" + param.Max + "\")]");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(param.Min))
|
||||
{
|
||||
writer.WriteLine("\t\t[Min(\"" + param.Min + "\")]");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(param.Step))
|
||||
{
|
||||
writer.WriteLine("\t\t[Step(\"" + param.Step + "\")]");
|
||||
}
|
||||
|
||||
writer.WriteLine("\t\tpublic " + sType + " " + sName);
|
||||
writer.WriteLine("\t\t{");
|
||||
writer.WriteLine("\t\t\tget");
|
||||
writer.WriteLine("\t\t\t{");
|
||||
writer.WriteLine("\t\t\t\treturn m_" + sName + ";");
|
||||
writer.WriteLine("\t\t\t}");
|
||||
writer.WriteLine("\t\t\tset");
|
||||
writer.WriteLine("\t\t\t{");
|
||||
writer.WriteLine("\t\t\t\tm_" + sName + " = value;");
|
||||
writer.WriteLine("\t\t\t\tRaisePropertyChanged();");
|
||||
writer.WriteLine("\t\t\t}");
|
||||
writer.WriteLine("\t\t}");
|
||||
writer.WriteLine("\t\tprivate " + sType + " m_" + sName + ";\n");
|
||||
}
|
||||
|
||||
writer.WriteLine("\t\tpublic " + op.Name + "()");
|
||||
writer.WriteLine("\t\t{");
|
||||
foreach (var param in op.Parameters)
|
||||
{
|
||||
var defaultValue = param.Value.DefaultValue;
|
||||
if (string.IsNullOrEmpty(defaultValue))
|
||||
continue;
|
||||
|
||||
var sName = CultureInfo.InvariantCulture.TextInfo.ToTitleCase(param.Key);
|
||||
|
||||
// TODO
|
||||
if (param.Value.CleanType == "vec2")
|
||||
{
|
||||
//writer.WriteLine("\t\t\tm_" + sName + ".x = " + defaultValue + ";");
|
||||
//writer.WriteLine("\t\t\tm_" + sName + ".y = " + defaultValue + ";");
|
||||
}
|
||||
else if (param.Value.CleanType == "vec3")
|
||||
{
|
||||
//writer.WriteLine("\t\t\tm_" + sName + ".x = " + defaultValue + ";");
|
||||
//writer.WriteLine("\t\t\tm_" + sName + ".y = " + defaultValue + ";");
|
||||
//writer.WriteLine("\t\t\tm_" + sName + ".z = " + defaultValue + ";");
|
||||
}
|
||||
else if (param.Value.CleanType == "vec4")
|
||||
{
|
||||
//writer.WriteLine("\t\t\tm_" + sName + ".x = " + defaultValue + ";");
|
||||
//writer.WriteLine("\t\t\tm_" + sName + ".y = " + defaultValue + ";");
|
||||
//writer.WriteLine("\t\t\tm_" + sName + ".z = " + defaultValue + ";");
|
||||
//writer.WriteLine("\t\t\tm_" + sName + ".w = " + defaultValue + ";");
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteLine("\t\t\tm_" + sName + " = " + defaultValue + ";");
|
||||
}
|
||||
}
|
||||
writer.WriteLine("\t\t}\n");
|
||||
writer.WriteLine("\t\tpublic override byte[] Serialize()");
|
||||
writer.WriteLine("\t\t{");
|
||||
writer.WriteLine("\t\t\tusing (var stream = new MemoryStream())");
|
||||
writer.WriteLine("\t\t\t{");
|
||||
writer.WriteLine("\t\t\t\tusing (var writer = new BinaryWriter(stream))");
|
||||
writer.WriteLine("\t\t\t\t{");
|
||||
writer.WriteLine("\t\t\t\t\twriter.Write(OpId);");
|
||||
|
||||
foreach (var param in parameters)
|
||||
{
|
||||
if (param.Item2 == "vec2")
|
||||
{
|
||||
writer.WriteLine("\t\t\t\t\twriter.Write(m_" + param.Item1 + ".x);");
|
||||
writer.WriteLine("\t\t\t\t\twriter.Write(m_" + param.Item1 + ".y);");
|
||||
}
|
||||
else if (param.Item2 == "vec3")
|
||||
{
|
||||
writer.WriteLine("\t\t\t\t\twriter.Write(m_" + param.Item1 + ".x);");
|
||||
writer.WriteLine("\t\t\t\t\twriter.Write(m_" + param.Item1 + ".y);");
|
||||
writer.WriteLine("\t\t\t\t\twriter.Write(m_" + param.Item1 + ".z);");
|
||||
}
|
||||
else if (param.Item2 == "vec4")
|
||||
{
|
||||
writer.WriteLine("\t\t\t\t\twriter.Write(m_" + param.Item1 + ".x);");
|
||||
writer.WriteLine("\t\t\t\t\twriter.Write(m_" + param.Item1 + ".y);");
|
||||
writer.WriteLine("\t\t\t\t\twriter.Write(m_" + param.Item1 + ".z);");
|
||||
writer.WriteLine("\t\t\t\t\twriter.Write(m_" + param.Item1 + ".w);");
|
||||
}
|
||||
else if (param.Item2 == "bool")
|
||||
{
|
||||
writer.WriteLine("\t\t\t\t\twriter.Write(m_" + param.Item1 + " ? (byte)1 : (byte)0);");
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteLine("\t\t\t\t\twriter.Write(m_" + param.Item1 + ");");
|
||||
}
|
||||
}
|
||||
|
||||
writer.WriteLine("\t\t\t\t\treturn stream.ToArray();");
|
||||
writer.WriteLine("\t\t\t\t}");
|
||||
writer.WriteLine("\t\t\t}");
|
||||
writer.WriteLine("\t\t}");
|
||||
writer.WriteLine("\t}");
|
||||
writer.WriteLine("}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
36
meshToolsV5/src/Codegen/Properties/AssemblyInfo.cs
Normal file
36
meshToolsV5/src/Codegen/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Codegen")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Codegen")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("eb7f77a5-eba2-4ef4-bdd2-02e961b0e256")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
19
meshToolsV5/src/Editor.Operators/Editor.Operators.projitems
Normal file
19
meshToolsV5/src/Editor.Operators/Editor.Operators.projitems
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||
<SharedGUID>01f4ea18-a795-416a-ae63-7680e87c0931</SharedGUID>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration">
|
||||
<Import_RootNamespace>Editor.Operators</Import_RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Group.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Loop.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)CreateCube.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Subdivide.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Delete.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)SelectAllFaces.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)SelectFacesByDirection.cs" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
13
meshToolsV5/src/Editor.Operators/Editor.Operators.shproj
Normal file
13
meshToolsV5/src/Editor.Operators/Editor.Operators.shproj
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>01f4ea18-a795-416a-ae63-7680e87c0931</ProjectGuid>
|
||||
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
|
||||
<PropertyGroup />
|
||||
<Import Project="Editor.Operators.projitems" Label="Shared" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
|
||||
</Project>
|
||||
43
meshToolsV5/src/Editor.Operators/Foo.cs
Normal file
43
meshToolsV5/src/Editor.Operators/Foo.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using Editor.Attributes;
|
||||
|
||||
namespace Editor.Operators
|
||||
{
|
||||
public class Foo : OperatorBase
|
||||
{
|
||||
public override ushort OpId { get { return 5; } }
|
||||
|
||||
[IndexedType("OpMesh")]
|
||||
public ushort OutputIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_OutputIndex;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_OutputIndex = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
private ushort m_OutputIndex;
|
||||
|
||||
public Foo()
|
||||
{
|
||||
}
|
||||
|
||||
public override byte[] Serialize()
|
||||
{
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
using (var writer = new BinaryWriter(stream))
|
||||
{
|
||||
writer.Write(OpId);
|
||||
writer.Write(m_OutputIndex);
|
||||
return stream.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
57
meshToolsV5/src/Editor.Operators/Load.cs
Normal file
57
meshToolsV5/src/Editor.Operators/Load.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using Editor.Attributes;
|
||||
|
||||
namespace Editor.Operators
|
||||
{
|
||||
public class Load : OperatorBase
|
||||
{
|
||||
public override ushort OpId { get { return 6; } }
|
||||
|
||||
public int &Output
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_&Output;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_&Output = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
private int m_&Output;
|
||||
|
||||
public int Intput
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Intput;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_Intput = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
private int m_Intput;
|
||||
|
||||
public Load()
|
||||
{
|
||||
}
|
||||
|
||||
public override byte[] Serialize()
|
||||
{
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
using (var writer = new BinaryWriter(stream))
|
||||
{
|
||||
writer.Write(OpId);
|
||||
writer.Write(m_&Output);
|
||||
writer.Write(m_Intput);
|
||||
return stream.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
57
meshToolsV5/src/Editor.Operators/Store.cs
Normal file
57
meshToolsV5/src/Editor.Operators/Store.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using Editor.Attributes;
|
||||
|
||||
namespace Editor.Operators
|
||||
{
|
||||
public class Store : OperatorBase
|
||||
{
|
||||
public override ushort OpId { get { return 5; } }
|
||||
|
||||
public int Output
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Output;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_Output = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
private int m_Output;
|
||||
|
||||
public int Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_Value = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
private int m_Value;
|
||||
|
||||
public Store()
|
||||
{
|
||||
}
|
||||
|
||||
public override byte[] Serialize()
|
||||
{
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
using (var writer = new BinaryWriter(stream))
|
||||
{
|
||||
writer.Write(OpId);
|
||||
writer.Write(m_Output);
|
||||
writer.Write(m_Value);
|
||||
return stream.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
59
meshToolsV5/src/Editor.Operators/Test.cs
Normal file
59
meshToolsV5/src/Editor.Operators/Test.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using Editor.Attributes;
|
||||
|
||||
namespace Editor.Operators
|
||||
{
|
||||
public class Test : OperatorBase
|
||||
{
|
||||
public override ushort OpId { get { return 7; } }
|
||||
|
||||
[IndexedType("int")]
|
||||
public ushort OutputIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_OutputIndex;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_OutputIndex = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
private ushort m_OutputIndex;
|
||||
|
||||
[IndexedType("int")]
|
||||
public ushort ValueIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_ValueIndex;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_ValueIndex = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
private ushort m_ValueIndex;
|
||||
|
||||
public Test()
|
||||
{
|
||||
}
|
||||
|
||||
public override byte[] Serialize()
|
||||
{
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
using (var writer = new BinaryWriter(stream))
|
||||
{
|
||||
writer.Write(OpId);
|
||||
writer.Write(m_OutputIndex);
|
||||
writer.Write(m_ValueIndex);
|
||||
return stream.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
6
meshToolsV5/src/Editor/App.config
Normal file
6
meshToolsV5/src/Editor/App.config
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/>
|
||||
</startup>
|
||||
</configuration>
|
||||
8
meshToolsV5/src/Editor/App.xaml
Normal file
8
meshToolsV5/src/Editor/App.xaml
Normal file
@@ -0,0 +1,8 @@
|
||||
<Application x:Class="Editor.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
StartupUri="MainWindow.xaml">
|
||||
<Application.Resources>
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
17
meshToolsV5/src/Editor/App.xaml.cs
Normal file
17
meshToolsV5/src/Editor/App.xaml.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for App.xaml
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
}
|
||||
}
|
||||
18
meshToolsV5/src/Editor/Attributes/IndexedType.cs
Normal file
18
meshToolsV5/src/Editor/Attributes/IndexedType.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Editor.Attributes
|
||||
{
|
||||
public class IndexedTypeAttribute : Attribute
|
||||
{
|
||||
public IndexedTypeAttribute(string _sTypeName)
|
||||
{
|
||||
TypeName = _sTypeName;
|
||||
}
|
||||
|
||||
public string TypeName { get; private set; }
|
||||
}
|
||||
}
|
||||
18
meshToolsV5/src/Editor/Attributes/Max.cs
Normal file
18
meshToolsV5/src/Editor/Attributes/Max.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Editor.Attributes
|
||||
{
|
||||
public class MaxAttribute : Attribute
|
||||
{
|
||||
public MaxAttribute(string _sValue)
|
||||
{
|
||||
Value = int.Parse(_sValue);
|
||||
}
|
||||
|
||||
public int Value { get; private set; }
|
||||
}
|
||||
}
|
||||
18
meshToolsV5/src/Editor/Attributes/Min.cs
Normal file
18
meshToolsV5/src/Editor/Attributes/Min.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Editor.Attributes
|
||||
{
|
||||
public class MinAttribute : Attribute
|
||||
{
|
||||
public MinAttribute(string _sValue)
|
||||
{
|
||||
Value = int.Parse(_sValue);
|
||||
}
|
||||
|
||||
public int Value { get; private set; }
|
||||
}
|
||||
}
|
||||
18
meshToolsV5/src/Editor/Attributes/Step.cs
Normal file
18
meshToolsV5/src/Editor/Attributes/Step.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Editor.Attributes
|
||||
{
|
||||
public class StepAttribute : Attribute
|
||||
{
|
||||
public StepAttribute(string _sValue)
|
||||
{
|
||||
Value = float.Parse(_sValue);
|
||||
}
|
||||
|
||||
public float Value { get; private set; }
|
||||
}
|
||||
}
|
||||
40
meshToolsV5/src/Editor/Document.cs
Normal file
40
meshToolsV5/src/Editor/Document.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Editor
|
||||
{
|
||||
public class Document
|
||||
{
|
||||
public ushort RegisterCount { get; set; }
|
||||
|
||||
public ObservableCollection<OperatorGroup> Groups { get; private set; } = new ObservableCollection<OperatorGroup>();
|
||||
|
||||
public ushort ResultIndex { get; set; }
|
||||
|
||||
public byte[] Serialize()
|
||||
{
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
using (var writer = new BinaryWriter(stream))
|
||||
{
|
||||
writer.Write((ushort)RegisterCount);
|
||||
writer.Write((ushort)Groups.Count);
|
||||
|
||||
foreach (var group in Groups)
|
||||
{
|
||||
writer.Write(group.Serialize());
|
||||
}
|
||||
|
||||
writer.Write((ushort)ResultIndex);
|
||||
|
||||
return stream.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
130
meshToolsV5/src/Editor/Editor.csproj
Normal file
130
meshToolsV5/src/Editor/Editor.csproj
Normal file
@@ -0,0 +1,130 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<Import Project="..\Editor.Operators\Editor.Operators.projitems" Label="Shared" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{8AF5E6D2-4E9C-4D08-9189-1FBD6F1334AD}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Editor</RootNamespace>
|
||||
<AssemblyName>Editor</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>..\..\bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<BaseIntermediateOutputPath>..\..\obj\Debug\Editor\</BaseIntermediateOutputPath>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<BaseIntermediateOutputPath>..\..\obj\Release\Editor\</BaseIntermediateOutputPath>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Xaml">
|
||||
<RequiredTargetFramework>4.0</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="WindowsBase" />
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
<Reference Include="WindowsFormsIntegration" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Include="App.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
<Page Include="MainWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Compile Include="App.xaml.cs">
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Attributes\IndexedType.cs" />
|
||||
<Compile Include="Attributes\Max.cs" />
|
||||
<Compile Include="Attributes\Min.cs" />
|
||||
<Compile Include="Attributes\Step.cs" />
|
||||
<Compile Include="Document.cs" />
|
||||
<Compile Include="MainWindow.xaml.cs">
|
||||
<DependentUpon>MainWindow.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Math.cs" />
|
||||
<Compile Include="OperatorBase.cs" />
|
||||
<Compile Include="OperatorGroup.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<AppDesigner Include="Properties\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Interop\Interop.vcxproj">
|
||||
<Project>{306104a5-eeee-4789-847a-07869d715550}</Project>
|
||||
<Name>Interop</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>
|
||||
</PreBuildEvent>
|
||||
</PropertyGroup>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
9
meshToolsV5/src/Editor/Editor.csproj.user
Normal file
9
meshToolsV5/src/Editor/Editor.csproj.user
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<EnableUnmanagedDebugging>true</EnableUnmanagedDebugging>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ProjectView>ProjectFiles</ProjectView>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
21
meshToolsV5/src/Editor/MainWindow.xaml
Normal file
21
meshToolsV5/src/Editor/MainWindow.xaml
Normal file
@@ -0,0 +1,21 @@
|
||||
<Window x:Class="Editor.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
|
||||
Title="MainWindow" Height="350" Width="525" PreviewKeyDown="Window_PreviewKeyDown">
|
||||
<Grid x:Name="LayoutRoot">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<ToolBar>
|
||||
<ToggleButton x:Name="btnWireframe" Width="22" Height="22" Checked="btnWireframe_Checked" Unchecked="btnWireframe_Checked">W</ToggleButton>
|
||||
<ToggleButton x:Name="btnBackFaceCulling" Width="22" Height="22" Checked="btnBackFaceCulling_Checked" Unchecked="btnBackFaceCulling_Checked">B</ToggleButton>
|
||||
</ToolBar>
|
||||
<WindowsFormsHost HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="1">
|
||||
<wf:Panel x:Name="winForms" SizeChanged="winForms_LayoutUpdated" MouseDown="winForms_MouseDown" MouseMove="winForms_MouseMove" MouseUp="winForms_MouseUp" />
|
||||
</WindowsFormsHost>
|
||||
<Button Grid.Row="2" x:Name="btnCapture" Click="btnCapture_Click">Capture</Button>
|
||||
</Grid>
|
||||
</Window>
|
||||
114
meshToolsV5/src/Editor/MainWindow.xaml.cs
Normal file
114
meshToolsV5/src/Editor/MainWindow.xaml.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
using Editor.Operators;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for MainWindow.xaml
|
||||
/// </summary>
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
CompositionTarget.Rendering += CompositionTarget_Rendering;
|
||||
}
|
||||
|
||||
void CompositionTarget_Rendering(object sender, EventArgs e)
|
||||
{
|
||||
if (m_bInitialized)
|
||||
{
|
||||
Interop.Viewer.Instance.Render();
|
||||
}
|
||||
}
|
||||
|
||||
private void btnCapture_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Interop.Viewer.Instance.CaptureFrame();
|
||||
}
|
||||
|
||||
private void winForms_LayoutUpdated(object sender, EventArgs e)
|
||||
{
|
||||
var iWidth = (int)winForms.Width;
|
||||
var iHeight = (int)winForms.Height;
|
||||
|
||||
if (m_bInitialized)
|
||||
{
|
||||
Interop.Viewer.Instance.Resize(iWidth, iHeight);
|
||||
}
|
||||
else if (iWidth != 0 && iHeight != 0)
|
||||
{
|
||||
Interop.Viewer.Instance.Init(winForms.Handle, iWidth, iHeight);
|
||||
|
||||
var doc = new Document();
|
||||
doc.RegisterCount = 2;
|
||||
doc.ResultIndex = 1;
|
||||
var group = new OperatorGroup();
|
||||
doc.Groups.Add(group);
|
||||
group.Operators.Add(new CreateCube() { OutputIndex = 0 });
|
||||
//group.Operators.Add(new SelectAllFaces() { OutputIndex = 1, InputIndex = 0 });
|
||||
//group.Operators.Add(new SelectFacesByDirection() { OutputIndex = 0, InputIndex = 1, Direction = new vec3() { y = 1 } });
|
||||
//group.Operators.Add(new Subdivide() { OutputIndex = 1, InputIndex = 0 });
|
||||
//group.Operators.Add(new SelectAllFaces() { OutputIndex = 0, InputIndex = 1 });
|
||||
//group.Operators.Add(new SelectFacesByDirection() { OutputIndex = 1, InputIndex = 0, Direction = new vec3() { x = 1 }, Threshold = 0.5f });
|
||||
|
||||
Interop.Viewer.Instance.LoadDocument(doc.Serialize());
|
||||
|
||||
m_bInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void winForms_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
|
||||
{
|
||||
Interop.Viewer.Instance.MouseDown(e.Button == System.Windows.Forms.MouseButtons.Left, e.X, e.Y);
|
||||
}
|
||||
|
||||
private void winForms_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
|
||||
{
|
||||
Interop.Viewer.Instance.MouseMove(e.X, e.Y);
|
||||
}
|
||||
|
||||
private void winForms_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
|
||||
{
|
||||
Interop.Viewer.Instance.MouseUp(e.X, e.Y);
|
||||
}
|
||||
|
||||
private bool m_bInitialized = false;
|
||||
|
||||
private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.Key == Key.A)
|
||||
{
|
||||
Interop.Viewer.Instance.FrameAll();
|
||||
}
|
||||
else if (e.Key == Key.F)
|
||||
{
|
||||
Interop.Viewer.Instance.FrameSelection();
|
||||
}
|
||||
}
|
||||
|
||||
private void btnWireframe_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Interop.Viewer.Instance.Wireframe = btnWireframe.IsChecked ?? false;
|
||||
}
|
||||
|
||||
private void btnBackFaceCulling_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Interop.Viewer.Instance.BackFaceCulling = btnBackFaceCulling.IsChecked ?? false;
|
||||
}
|
||||
}
|
||||
}
|
||||
15
meshToolsV5/src/Editor/Math.cs
Normal file
15
meshToolsV5/src/Editor/Math.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Editor
|
||||
{
|
||||
public struct vec3
|
||||
{
|
||||
public float x;
|
||||
public float y;
|
||||
public float z;
|
||||
}
|
||||
}
|
||||
53
meshToolsV5/src/Editor/OperatorBase.cs
Normal file
53
meshToolsV5/src/Editor/OperatorBase.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Editor
|
||||
{
|
||||
public abstract class OperatorBase : INotifyPropertyChanged
|
||||
{
|
||||
public double Left
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Left;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_Left = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public double Top
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Top;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_Top = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract ushort OpId { get; }
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public void RaisePropertyChanged([CallerMemberName] string _sPropertyName = "")
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(_sPropertyName));
|
||||
}
|
||||
|
||||
public abstract byte[] Serialize();
|
||||
|
||||
private double m_Left;
|
||||
private double m_Top;
|
||||
}
|
||||
}
|
||||
33
meshToolsV5/src/Editor/OperatorGroup.cs
Normal file
33
meshToolsV5/src/Editor/OperatorGroup.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Editor
|
||||
{
|
||||
public class OperatorGroup
|
||||
{
|
||||
public ObservableCollection<OperatorBase> Operators { get; private set; } = new ObservableCollection<OperatorBase>();
|
||||
|
||||
public byte[] Serialize()
|
||||
{
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
using (var writer = new BinaryWriter(stream))
|
||||
{
|
||||
writer.Write((ushort)Operators.Count);
|
||||
foreach (var op in Operators)
|
||||
{
|
||||
var opBytes = op.Serialize();
|
||||
stream.Write(opBytes, 0, opBytes.Length);
|
||||
}
|
||||
|
||||
return stream.GetBuffer();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
55
meshToolsV5/src/Editor/Properties/AssemblyInfo.cs
Normal file
55
meshToolsV5/src/Editor/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using System.Reflection;
|
||||
using System.Resources;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Editor")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Editor")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
//In order to begin building localizable applications, set
|
||||
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
|
||||
//inside a <PropertyGroup>. For example, if you are using US english
|
||||
//in your source files, set the <UICulture> to en-US. Then uncomment
|
||||
//the NeutralResourceLanguage attribute below. Update the "en-US" in
|
||||
//the line below to match the UICulture setting in the project file.
|
||||
|
||||
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
|
||||
|
||||
|
||||
[assembly: ThemeInfo(
|
||||
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||
//(used if a resource is not found in the page,
|
||||
// or application resource dictionaries)
|
||||
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||
//(used if a resource is not found in the page,
|
||||
// app, or any theme specific resource dictionaries)
|
||||
)]
|
||||
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
63
meshToolsV5/src/Editor/Properties/Resources.Designer.cs
generated
Normal file
63
meshToolsV5/src/Editor/Properties/Resources.Designer.cs
generated
Normal file
@@ -0,0 +1,63 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Editor.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Editor.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
117
meshToolsV5/src/Editor/Properties/Resources.resx
Normal file
117
meshToolsV5/src/Editor/Properties/Resources.resx
Normal file
@@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
26
meshToolsV5/src/Editor/Properties/Settings.Designer.cs
generated
Normal file
26
meshToolsV5/src/Editor/Properties/Settings.Designer.cs
generated
Normal file
@@ -0,0 +1,26 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Editor.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
7
meshToolsV5/src/Editor/Properties/Settings.settings
Normal file
7
meshToolsV5/src/Editor/Properties/Settings.settings
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
87
meshToolsV5/src/Interop/ArcBall.cpp
Normal file
87
meshToolsV5/src/Interop/ArcBall.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#include "Stdafx.hpp"
|
||||
#include "ArcBall.hpp"
|
||||
|
||||
|
||||
ArcBall::ArcBall()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
|
||||
void ArcBall::Reset()
|
||||
{
|
||||
m_Down = mt::Quaternion::identity;
|
||||
m_Now = mt::Quaternion::identity;
|
||||
m_bDrag = false;
|
||||
m_fRadius = 1.0f;
|
||||
}
|
||||
|
||||
|
||||
void ArcBall::SetWindow(float _fWidth, float _fHeight, float _fRadius)
|
||||
{
|
||||
m_fWidth = _fWidth;
|
||||
m_fHeight = _fHeight;
|
||||
m_fRadius = _fRadius;
|
||||
}
|
||||
|
||||
|
||||
void ArcBall::OnBegin(float _fX, float _fY)
|
||||
{
|
||||
// Only enter the drag state if the click falls inside the click rectangle.
|
||||
if (_fX >= 0 &&
|
||||
_fX < m_fWidth &&
|
||||
_fY >= 0 &&
|
||||
_fY < m_fHeight)
|
||||
{
|
||||
m_bDrag = true;
|
||||
m_Down = m_Now;
|
||||
m_DownPoint = ScreenToVector(_fX, _fY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ArcBall::OnMove(float _fX, float _fY)
|
||||
{
|
||||
if (m_bDrag)
|
||||
{
|
||||
m_CurrentPoint = ScreenToVector(_fX, _fY);
|
||||
m_Now = mt::Quaternion::FromTo(m_DownPoint, m_CurrentPoint) * m_Down;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ArcBall::OnEnd()
|
||||
{
|
||||
m_bDrag = false;
|
||||
}
|
||||
|
||||
|
||||
mt::Matrix ArcBall::GetRotationMatrix()
|
||||
{
|
||||
return mt::Matrix::FromQuaternion(m_Now);
|
||||
}
|
||||
|
||||
|
||||
mt::vec3 ArcBall::ScreenToVector(float _fX, float _fY)
|
||||
{
|
||||
// Scale to screen
|
||||
float x = -(_fX - m_fWidth / 2.0f) / (m_fRadius * m_fWidth / 2.0f);
|
||||
float y = (_fY - m_fHeight / 2.0f) / (m_fRadius * m_fHeight / 2.0f);
|
||||
float z = 0.0f;
|
||||
|
||||
float fMag = x * x + y * y;
|
||||
if (fMag > 1.0f)
|
||||
{
|
||||
float fScale = 1.0f / sqrtf(fMag);
|
||||
x *= fScale;
|
||||
y *= fScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
z = sqrtf(1.0f - fMag);
|
||||
}
|
||||
|
||||
// Return vector
|
||||
return mt::vec3(x, y, z);
|
||||
}
|
||||
|
||||
32
meshToolsV5/src/Interop/ArcBall.hpp
Normal file
32
meshToolsV5/src/Interop/ArcBall.hpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
class ArcBall
|
||||
{
|
||||
public:
|
||||
void Reset();
|
||||
void SetWindow(float _fWidth, float _fHeight, float _fRadius = 1.0f);
|
||||
void OnBegin(float _fX, float _fY);
|
||||
void OnMove(float _fX, float _fY);
|
||||
void OnEnd();
|
||||
|
||||
mt::Matrix GetRotationMatrix();
|
||||
|
||||
public:
|
||||
ArcBall();
|
||||
|
||||
private:
|
||||
mt::vec3 ScreenToVector(float _fX, float _fY);
|
||||
|
||||
private:
|
||||
float m_fWidth; // arc ball's window width
|
||||
float m_fHeight; // arc ball's window height
|
||||
float m_fRadius; // arc ball's radius in screen coords
|
||||
|
||||
mt::Quaternion m_Down; // Quaternion before button down
|
||||
mt::Quaternion m_Now; // Composite quaternion for current drag
|
||||
bool m_bDrag; // Whether user is dragging arc ball
|
||||
|
||||
mt::vec3 m_DownPoint; // starting point of rotation arc
|
||||
mt::vec3 m_CurrentPoint; // current point of rotation arc
|
||||
};
|
||||
38
meshToolsV5/src/Interop/AssemblyInfo.cpp
Normal file
38
meshToolsV5/src/Interop/AssemblyInfo.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#include "Stdafx.hpp"
|
||||
|
||||
using namespace System;
|
||||
using namespace System::Reflection;
|
||||
using namespace System::Runtime::CompilerServices;
|
||||
using namespace System::Runtime::InteropServices;
|
||||
using namespace System::Security::Permissions;
|
||||
|
||||
//
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
//
|
||||
[assembly:AssemblyTitleAttribute(L"Interop")];
|
||||
[assembly:AssemblyDescriptionAttribute(L"")];
|
||||
[assembly:AssemblyConfigurationAttribute(L"")];
|
||||
[assembly:AssemblyCompanyAttribute(L"")];
|
||||
[assembly:AssemblyProductAttribute(L"Interop")];
|
||||
[assembly:AssemblyCopyrightAttribute(L"Copyright (c) 2016")];
|
||||
[assembly:AssemblyTrademarkAttribute(L"")];
|
||||
[assembly:AssemblyCultureAttribute(L"")];
|
||||
|
||||
//
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the value or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
|
||||
[assembly:AssemblyVersionAttribute("1.0.*")];
|
||||
|
||||
[assembly:ComVisible(false)];
|
||||
|
||||
[assembly:CLSCompliantAttribute(true)];
|
||||
131
meshToolsV5/src/Interop/Interop.vcxproj
Normal file
131
meshToolsV5/src/Interop/Interop.vcxproj
Normal file
@@ -0,0 +1,131 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{306104A5-EEEE-4789-847A-07869D715550}</ProjectGuid>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<Keyword>ManagedCProj</Keyword>
|
||||
<RootNamespace>Interop</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(SolutionDir)bin\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)obj\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<IncludePath>$(SolutionDir)src\Lib;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(SolutionDir)lib\$(Configuration)\;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)obj\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<IncludePath>$(SolutionDir)src\Lib;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(SolutionDir)lib\$(Configuration)\;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>stdafx.hpp</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>Lib.lib;d3d11.lib;DXGI.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>stdafx.hpp</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>Lib.lib;d3d11.lib;DXGI.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ArcBall.hpp" />
|
||||
<ClInclude Include="Viewer.hpp" />
|
||||
<ClInclude Include="Stdafx.hpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ArcBall.cpp" />
|
||||
<ClCompile Include="AssemblyInfo.cpp" />
|
||||
<ClCompile Include="Viewer.cpp" />
|
||||
<ClCompile Include="Stdafx.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Lib\Lib.vcxproj">
|
||||
<Project>{fdebd01e-0317-4400-9208-58d7dd7cee44}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<FxCompile Include="MeshVertexShader.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Vertex</ShaderType>
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Vertex</ShaderType>
|
||||
</FxCompile>
|
||||
<FxCompile Include="MeshPixelShader.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Pixel</ShaderType>
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
|
||||
</FxCompile>
|
||||
<FxCompile Include="SelectionPixelShader.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Pixel</ShaderType>
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
|
||||
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">5.0</ShaderModel>
|
||||
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">5.0</ShaderModel>
|
||||
</FxCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="List.natvis">
|
||||
<SubType>Designer</SubType>
|
||||
</Natvis>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
50
meshToolsV5/src/Interop/Interop.vcxproj.filters
Normal file
50
meshToolsV5/src/Interop/Interop.vcxproj.filters
Normal file
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ArcBall.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Viewer.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Stdafx.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="AssemblyInfo.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Stdafx.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Viewer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ArcBall.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<FxCompile Include="MeshPixelShader.hlsl" />
|
||||
<FxCompile Include="MeshVertexShader.hlsl" />
|
||||
<FxCompile Include="SelectionPixelShader.hlsl" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="List.natvis" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
6
meshToolsV5/src/Interop/Interop.vcxproj.user
Normal file
6
meshToolsV5/src/Interop/Interop.vcxproj.user
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ShowAllFiles>true</ShowAllFiles>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
15
meshToolsV5/src/Interop/List.natvis
Normal file
15
meshToolsV5/src/Interop/List.natvis
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
||||
<Type Name="List<*>">
|
||||
<DisplayString Condition="count == 0">empty</DisplayString>
|
||||
<DisplayString>{{ size={count} }}</DisplayString>
|
||||
<Expand>
|
||||
<ArrayItems>
|
||||
<Size>count</Size>
|
||||
<ValuePointer>data</ValuePointer>
|
||||
</ArrayItems>
|
||||
<Item Name="[size]" ExcludeView="simple">count</Item>
|
||||
<Item Name="[capacity]" ExcludeView="simple">capacity</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
</AutoVisualizer>
|
||||
5
meshToolsV5/src/Interop/MeshPixelShader.hlsl
Normal file
5
meshToolsV5/src/Interop/MeshPixelShader.hlsl
Normal file
@@ -0,0 +1,5 @@
|
||||
float4 main(in float4 result : SV_POSITION, in float3 normal : NORMAL, in float4 uv : TEXCOORD) : SV_TARGET
|
||||
{
|
||||
float l = dot(normal, normalize(float3(1, 0.5, 0.25))) * 0.5 + 0.5;
|
||||
return float4(l, l, l, 1.0f);
|
||||
}
|
||||
35
meshToolsV5/src/Interop/MeshVertexShader.hlsl
Normal file
35
meshToolsV5/src/Interop/MeshVertexShader.hlsl
Normal file
@@ -0,0 +1,35 @@
|
||||
cbuffer cb0 : register (b0)
|
||||
{
|
||||
float aspectRatio;
|
||||
float distanceToCenter;
|
||||
float dummy2;
|
||||
float dummy3;
|
||||
float4x4 modelRotation;
|
||||
float4 pivot;
|
||||
}
|
||||
|
||||
float4x4 getProjMatrix()
|
||||
{
|
||||
float yScale = 2.4142135623730950488016887242097;//cot(fovY/2)
|
||||
float xScale = yScale / aspectRatio;
|
||||
float n = 0.1f;
|
||||
float f = 100.0f;
|
||||
float4x4 proj =
|
||||
{
|
||||
xScale, 0, 0, 0,
|
||||
0, yScale, 0, 0,
|
||||
0, 0, f/(f-n), 1,
|
||||
0, 0, -n*f/(f-n), 0
|
||||
};
|
||||
return proj;
|
||||
}
|
||||
|
||||
void main(in float3 pos : POSITION, out float4 result : SV_POSITION, inout float3 normal : NORMAL, inout float4 uv : TEXCOORD)
|
||||
{
|
||||
float4 v = float4(pos, 1);
|
||||
v.xyz -= pivot.xyz;
|
||||
v = mul(v, modelRotation);
|
||||
v.z += distanceToCenter;
|
||||
v = mul(v, getProjMatrix());
|
||||
result = v;
|
||||
}
|
||||
6
meshToolsV5/src/Interop/SelectionPixelShader.hlsl
Normal file
6
meshToolsV5/src/Interop/SelectionPixelShader.hlsl
Normal file
@@ -0,0 +1,6 @@
|
||||
float4 main(in float4 result : SV_POSITION, in float3 normal : NORMAL, in float4 uv : TEXCOORD) : SV_TARGET
|
||||
{
|
||||
int2 wuv = result.xy;
|
||||
float l = (wuv.x ^ wuv.y) % 4;
|
||||
return float4(0.25, 0.5, 0.75, l * 0.5f);
|
||||
}
|
||||
5
meshToolsV5/src/Interop/Stdafx.cpp
Normal file
5
meshToolsV5/src/Interop/Stdafx.cpp
Normal file
@@ -0,0 +1,5 @@
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// Interop.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.hpp"
|
||||
8
meshToolsV5/src/Interop/Stdafx.hpp
Normal file
8
meshToolsV5/src/Interop/Stdafx.hpp
Normal file
@@ -0,0 +1,8 @@
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently,
|
||||
// but are changed infrequently
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mt\mt.h>
|
||||
#include "ArcBall.hpp"
|
||||
642
meshToolsV5/src/Interop/Viewer.cpp
Normal file
642
meshToolsV5/src/Interop/Viewer.cpp
Normal file
@@ -0,0 +1,642 @@
|
||||
#include "Stdafx.hpp"
|
||||
#include "Viewer.hpp"
|
||||
#include "../Lib/mt/operators/OpDocument.h"
|
||||
|
||||
#include <DXGItype.h>
|
||||
#include <dxgi1_2.h>
|
||||
#include <dxgi1_3.h>
|
||||
#include <DXProgrammableCapture.h>
|
||||
|
||||
using namespace System::Linq;
|
||||
|
||||
static D3D11_RASTERIZER_DESC rsSolidCullBackDesc =
|
||||
{
|
||||
D3D11_FILL_SOLID,
|
||||
D3D11_CULL_BACK,
|
||||
FALSE,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
TRUE,
|
||||
FALSE,
|
||||
FALSE,
|
||||
FALSE
|
||||
};
|
||||
|
||||
static D3D11_RASTERIZER_DESC rsWireframeCullBackDesc =
|
||||
{
|
||||
D3D11_FILL_WIREFRAME,
|
||||
D3D11_CULL_BACK,
|
||||
FALSE,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
TRUE,
|
||||
FALSE,
|
||||
FALSE,
|
||||
FALSE
|
||||
};
|
||||
|
||||
static D3D11_RASTERIZER_DESC rsSolidCullNoneDesc =
|
||||
{
|
||||
D3D11_FILL_SOLID,
|
||||
D3D11_CULL_NONE,
|
||||
FALSE,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
TRUE,
|
||||
FALSE,
|
||||
FALSE,
|
||||
FALSE
|
||||
};
|
||||
|
||||
static D3D11_RASTERIZER_DESC rsWireframeCullNoneDesc =
|
||||
{
|
||||
D3D11_FILL_WIREFRAME,
|
||||
D3D11_CULL_NONE,
|
||||
FALSE,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
TRUE,
|
||||
FALSE,
|
||||
FALSE,
|
||||
FALSE
|
||||
};
|
||||
|
||||
static D3D11_DEPTH_STENCIL_DESC depthStencilDesc =
|
||||
{
|
||||
TRUE,
|
||||
D3D11_DEPTH_WRITE_MASK_ALL,
|
||||
D3D11_COMPARISON_LESS_EQUAL,
|
||||
FALSE,
|
||||
D3D11_DEFAULT_STENCIL_READ_MASK,
|
||||
D3D11_DEFAULT_STENCIL_WRITE_MASK,
|
||||
{
|
||||
D3D11_STENCIL_OP_KEEP,
|
||||
D3D11_STENCIL_OP_KEEP,
|
||||
D3D11_STENCIL_OP_KEEP,
|
||||
D3D11_COMPARISON_ALWAYS
|
||||
},
|
||||
{
|
||||
D3D11_STENCIL_OP_KEEP,
|
||||
D3D11_STENCIL_OP_KEEP,
|
||||
D3D11_STENCIL_OP_KEEP,
|
||||
D3D11_COMPARISON_ALWAYS
|
||||
}
|
||||
};
|
||||
|
||||
static D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc =
|
||||
{
|
||||
DXGI_FORMAT_D32_FLOAT,
|
||||
D3D11_DSV_DIMENSION_TEXTURE2DMS,
|
||||
0
|
||||
};
|
||||
|
||||
static D3D11_RENDER_TARGET_VIEW_DESC backBufferRTVdesc =
|
||||
{
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
D3D11_RTV_DIMENSION_TEXTURE2DMS,
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static D3D11_BLEND_DESC alphaBlendDesc =
|
||||
{
|
||||
FALSE,
|
||||
FALSE,
|
||||
{
|
||||
TRUE,
|
||||
D3D11_BLEND_SRC_ALPHA,
|
||||
D3D11_BLEND_INV_SRC_ALPHA,
|
||||
D3D11_BLEND_OP_ADD,
|
||||
D3D11_BLEND_ZERO,
|
||||
D3D11_BLEND_ZERO,
|
||||
D3D11_BLEND_OP_ADD,
|
||||
0x0F
|
||||
}
|
||||
};
|
||||
|
||||
static D3D11_VIEWPORT viewPort =
|
||||
{
|
||||
0, 0, 0, 0, 0, 1
|
||||
};
|
||||
|
||||
static D3D_FEATURE_LEVEL featureLevel[] = { D3D_FEATURE_LEVEL_11_0 };
|
||||
|
||||
static D3D11_INPUT_ELEMENT_DESC inputElementDescs[] =
|
||||
{
|
||||
{
|
||||
"POSITION", 0,
|
||||
DXGI_FORMAT_R32G32B32_FLOAT,
|
||||
0,
|
||||
0, //AlignedByteOffset;
|
||||
D3D11_INPUT_PER_VERTEX_DATA,
|
||||
0
|
||||
},
|
||||
{
|
||||
"NORMAL", 0,
|
||||
DXGI_FORMAT_R32G32B32_FLOAT,
|
||||
0,
|
||||
12, //AlignedByteOffset;
|
||||
D3D11_INPUT_PER_VERTEX_DATA,
|
||||
0
|
||||
},
|
||||
{
|
||||
"TEXCOORD", 0,
|
||||
DXGI_FORMAT_R32G32B32A32_FLOAT,
|
||||
0,
|
||||
24, //AlignedByteOffset;
|
||||
D3D11_INPUT_PER_VERTEX_DATA,
|
||||
0
|
||||
}
|
||||
};
|
||||
|
||||
static DXGI_SWAP_CHAIN_DESC swapChainDesc =
|
||||
{
|
||||
{
|
||||
0,
|
||||
0,
|
||||
{ 60, 1 },
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED,
|
||||
DXGI_MODE_SCALING_UNSPECIFIED
|
||||
},
|
||||
{
|
||||
8,
|
||||
(UINT)-1
|
||||
},
|
||||
DXGI_USAGE_BACK_BUFFER | DXGI_USAGE_RENDER_TARGET_OUTPUT,
|
||||
1,
|
||||
0,
|
||||
TRUE,
|
||||
DXGI_SWAP_EFFECT_DISCARD,
|
||||
0
|
||||
};
|
||||
|
||||
static D3D11_BUFFER_DESC constantBufferDesc =
|
||||
{
|
||||
(
|
||||
4 + // float aspectRatio + 3 dummies
|
||||
(4 * 4) + // float4 modelRotation
|
||||
4 // pivot
|
||||
) * sizeof(float),
|
||||
D3D11_USAGE_DYNAMIC,
|
||||
D3D11_BIND_CONSTANT_BUFFER,
|
||||
D3D11_CPU_ACCESS_WRITE,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define D3D_DEVICE_FLAGS D3D11_CREATE_DEVICE_DEBUG
|
||||
#else
|
||||
#define D3D_DEVICE_FLAGS 0
|
||||
#endif
|
||||
|
||||
#pragma bss_seg(".bss")
|
||||
ID3D11Device* device = nullptr;
|
||||
ID3D11DeviceContext* context = nullptr;
|
||||
IDXGISwapChain* swapChain = nullptr;
|
||||
|
||||
ID3D11Texture2D* backBufferTexture = nullptr;
|
||||
ID3D11Texture2D* depthStencilBuffer = nullptr;
|
||||
|
||||
ID3D11InputLayout* inputLayout = nullptr;
|
||||
ID3D11BlendState* alphaBlendState = nullptr;
|
||||
ID3D11RenderTargetView* backBufferRTV = nullptr;
|
||||
ID3D11RasterizerState* rsSolidCullBack = nullptr;
|
||||
ID3D11RasterizerState* rsWireframeCullBack = nullptr;
|
||||
ID3D11RasterizerState* rsSolidCullNone = nullptr;
|
||||
ID3D11RasterizerState* rsWireframeCullNone = nullptr;
|
||||
ID3D11DepthStencilState* depthStencilState = nullptr;
|
||||
ID3D11DepthStencilView* depthStencilView = nullptr;
|
||||
ID3D11VertexShader* vertexShader = nullptr;
|
||||
ID3D11PixelShader* pixelShader = nullptr;
|
||||
ID3D11PixelShader* selPixelShader = nullptr;
|
||||
ID3D11Buffer* vertexBuffer = nullptr;
|
||||
ID3D11Buffer* indexBuffer = nullptr;
|
||||
ID3D11Buffer* selIndexBuffer = nullptr;
|
||||
ID3D11Buffer* constantBuffer = nullptr;
|
||||
unsigned int indexCount = 0;
|
||||
unsigned int selIndexCount = 0;
|
||||
bool drawWireframe = false;
|
||||
bool backFaceCulling = false;
|
||||
|
||||
#pragma code_seg(".code")
|
||||
|
||||
IntPtr Interop::Viewer::DevicePtr::get()
|
||||
{
|
||||
return IntPtr::IntPtr(device);
|
||||
}
|
||||
|
||||
|
||||
bool Interop::Viewer::Wireframe::get()
|
||||
{
|
||||
return drawWireframe;
|
||||
}
|
||||
|
||||
|
||||
void Interop::Viewer::Wireframe::set(bool value)
|
||||
{
|
||||
drawWireframe = value;
|
||||
}
|
||||
|
||||
|
||||
bool Interop::Viewer::BackFaceCulling::get()
|
||||
{
|
||||
return backFaceCulling;
|
||||
}
|
||||
|
||||
|
||||
void Interop::Viewer::BackFaceCulling::set(bool value)
|
||||
{
|
||||
backFaceCulling = value;
|
||||
}
|
||||
|
||||
|
||||
Interop::Viewer::Viewer()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Interop::Viewer::Init(IntPtr _hWnd, int _iWidth, int _iHeight)
|
||||
{
|
||||
m_ArcBall = new ArcBall();
|
||||
|
||||
swapChainDesc.OutputWindow = (HWND)_hWnd.ToPointer();
|
||||
swapChainDesc.BufferDesc.Width = _iWidth;
|
||||
swapChainDesc.BufferDesc.Height = _iHeight;
|
||||
D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D_DEVICE_FLAGS, featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &swapChain, &device, NULL, &context);
|
||||
swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&backBufferTexture);
|
||||
device->CreateRenderTargetView(backBufferTexture, &backBufferRTVdesc, &backBufferRTV);
|
||||
|
||||
device->CreateBlendState(&alphaBlendDesc, &alphaBlendState);
|
||||
device->CreateDepthStencilState(&depthStencilDesc, &depthStencilState);
|
||||
device->CreateRasterizerState(&rsSolidCullBackDesc, &rsSolidCullBack);
|
||||
device->CreateRasterizerState(&rsWireframeCullBackDesc, &rsWireframeCullBack);
|
||||
device->CreateRasterizerState(&rsSolidCullNoneDesc, &rsSolidCullNone);
|
||||
device->CreateRasterizerState(&rsWireframeCullNoneDesc, &rsWireframeCullNone);
|
||||
|
||||
auto vsCode = System::IO::File::ReadAllBytes("MeshVertexShader.cso");
|
||||
pin_ptr<unsigned char> pVsCode = &vsCode[0];
|
||||
device->CreateVertexShader(pVsCode, vsCode->Length, NULL, &vertexShader);
|
||||
device->CreateInputLayout(inputElementDescs, 3, pVsCode, vsCode->Length, &inputLayout);
|
||||
|
||||
auto psCode = System::IO::File::ReadAllBytes("MeshPixelShader.cso");
|
||||
pin_ptr<unsigned char> pPsCode = &psCode[0];
|
||||
device->CreatePixelShader(pPsCode, psCode->Length, NULL, &pixelShader);
|
||||
|
||||
psCode = System::IO::File::ReadAllBytes("SelectionPixelShader.cso");
|
||||
pPsCode = &psCode[0];
|
||||
device->CreatePixelShader(pPsCode, psCode->Length, NULL, &selPixelShader);
|
||||
|
||||
device->CreateBuffer(&constantBufferDesc, NULL, &constantBuffer);
|
||||
|
||||
CreateTextures(_iWidth, _iHeight);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void CreateVertexBuffer(ID3D11Buffer** _vertexBuffer, const List<T>& _data)
|
||||
{
|
||||
D3D11_BUFFER_DESC vertexBufferDesc =
|
||||
{
|
||||
sizeof(T) * _data.Count(),
|
||||
D3D11_USAGE_DEFAULT,
|
||||
D3D11_BIND_VERTEX_BUFFER,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
static D3D11_SUBRESOURCE_DATA vertexData =
|
||||
{
|
||||
&_data[0],
|
||||
sizeof(T),
|
||||
vertexBufferDesc.ByteWidth
|
||||
};
|
||||
|
||||
device->CreateBuffer(&vertexBufferDesc, &vertexData, _vertexBuffer);
|
||||
}
|
||||
|
||||
|
||||
void CreateIndexBuffer(ID3D11Buffer** _indexBuffer, const List<unsigned int>& _data)
|
||||
{
|
||||
D3D11_BUFFER_DESC indexBufferDesc =
|
||||
{
|
||||
sizeof(unsigned int) * _data.Count(),
|
||||
D3D11_USAGE_DEFAULT,
|
||||
D3D11_BIND_INDEX_BUFFER,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
D3D11_SUBRESOURCE_DATA indexData =
|
||||
{
|
||||
&_data[0],
|
||||
sizeof(unsigned int),
|
||||
indexBufferDesc.ByteWidth
|
||||
};
|
||||
|
||||
device->CreateBuffer(&indexBufferDesc, &indexData, _indexBuffer);
|
||||
}
|
||||
|
||||
|
||||
void Interop::Viewer::LoadDocument(array<System::Byte>^ _data)
|
||||
{
|
||||
auto parser = new mt::Parser();
|
||||
pin_ptr<unsigned char> pData = &_data[0];
|
||||
auto doc = parser->ParseDocument(pData);
|
||||
LoadOpMesh(doc->GetMesh(1));
|
||||
}
|
||||
|
||||
|
||||
void Interop::Viewer::LoadOpMesh(mt::OpMesh* _mesh)
|
||||
{
|
||||
m_Mesh = _mesh;
|
||||
auto vertices = m_Mesh->GetMesh()->GetRawVertices();
|
||||
auto indicies = m_Mesh->GetMesh()->GetIndices(false);
|
||||
::CreateVertexBuffer(&vertexBuffer, vertices);
|
||||
::CreateIndexBuffer(&indexBuffer, indicies);
|
||||
indexCount = indicies.Count();
|
||||
|
||||
auto selIndicies = m_Mesh->GetSelectedFaceIndices();
|
||||
selIndexCount = selIndicies.Count();
|
||||
if (selIndexCount)
|
||||
{
|
||||
::CreateIndexBuffer(&selIndexBuffer, selIndicies);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Interop::Viewer::CreateTextures(int _iWidth, int _iHeight)
|
||||
{
|
||||
viewPort.Width = (float)_iWidth;
|
||||
viewPort.Height = (float)_iHeight;
|
||||
|
||||
D3D11_TEXTURE2D_DESC depthStencilBufferDesc =
|
||||
{
|
||||
(UINT)_iWidth,
|
||||
(UINT)_iHeight,
|
||||
1u,
|
||||
1u,
|
||||
DXGI_FORMAT_R32_TYPELESS,
|
||||
{
|
||||
8,
|
||||
(UINT)-1
|
||||
},
|
||||
D3D11_USAGE_DEFAULT,
|
||||
D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
device->CreateTexture2D(&depthStencilBufferDesc, NULL, &depthStencilBuffer);
|
||||
device->CreateDepthStencilView(depthStencilBuffer, &depthStencilViewDesc, &depthStencilView);
|
||||
m_ArcBall->SetWindow((float)_iWidth, (float)_iHeight);
|
||||
UpdateConstantBuffer();
|
||||
}
|
||||
|
||||
|
||||
void Interop::Viewer::UpdateConstantBuffer()
|
||||
{
|
||||
mt::Matrix mat;
|
||||
if (m_ArcBall != NULL)
|
||||
mat = m_ArcBall->GetRotationMatrix();
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE mapped;
|
||||
context->Map(constantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
|
||||
float* data = (float*)mapped.pData;
|
||||
int i = 0;
|
||||
|
||||
data[i++] = (float)viewPort.Width / (float)viewPort.Height; // aspectRatio;
|
||||
data[i++] = m_fDistanceToCenter; // distanceToCenter
|
||||
data[i++] = 0; // unused
|
||||
data[i++] = 0; // unused
|
||||
|
||||
data[i++] = mat.M11; // rotation matrix
|
||||
data[i++] = mat.M21;
|
||||
data[i++] = mat.M31;
|
||||
data[i++] = mat.M41;
|
||||
|
||||
data[i++] = mat.M12;
|
||||
data[i++] = mat.M22;
|
||||
data[i++] = mat.M32;
|
||||
data[i++] = mat.M42;
|
||||
|
||||
data[i++] = mat.M13;
|
||||
data[i++] = mat.M23;
|
||||
data[i++] = mat.M33;
|
||||
data[i++] = mat.M43;
|
||||
|
||||
data[i++] = mat.M14;
|
||||
data[i++] = mat.M24;
|
||||
data[i++] = mat.M34;
|
||||
data[i++] = mat.M44;
|
||||
|
||||
data[i++] = m_fPivotX;
|
||||
data[i++] = m_fPivotY;
|
||||
data[i++] = m_fPivotZ;
|
||||
data[i++] = 1; // pivot.w
|
||||
|
||||
context->Unmap(constantBuffer, 0);
|
||||
}
|
||||
|
||||
|
||||
void Interop::Viewer::DisposeTextures()
|
||||
{
|
||||
depthStencilBuffer->Release();
|
||||
depthStencilView->Release();
|
||||
}
|
||||
|
||||
|
||||
void Interop::Viewer::Resize(int _iWidth, int _iHeight)
|
||||
{
|
||||
if (swapChain == nullptr)
|
||||
return;
|
||||
|
||||
DisposeTextures();
|
||||
backBufferTexture->Release();
|
||||
backBufferRTV->Release();
|
||||
|
||||
swapChain->ResizeBuffers(1, _iWidth, _iHeight, DXGI_FORMAT_B8G8R8A8_UNORM, 0);
|
||||
|
||||
swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&backBufferTexture);
|
||||
device->CreateRenderTargetView(backBufferTexture, &backBufferRTVdesc, &backBufferRTV);
|
||||
CreateTextures(_iWidth, _iHeight);
|
||||
}
|
||||
|
||||
|
||||
void Interop::Viewer::CaptureFrame()
|
||||
{
|
||||
m_bCaptureFrame = true;
|
||||
}
|
||||
|
||||
|
||||
void Interop::Viewer::MouseDown(bool _bLeftButton, int _iX, int _iY)
|
||||
{
|
||||
m_bDragging = true;
|
||||
if (_bLeftButton)
|
||||
{
|
||||
m_bLeftDrag = true;
|
||||
m_ArcBall->OnBegin((float)_iX, (float)_iY);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_iLastDragX = _iX;
|
||||
m_iLastDragY = _iY;
|
||||
m_bLeftDrag = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Interop::Viewer::Frame(const List<mt::RawVertex>& _vertices)
|
||||
{
|
||||
mt::vec3 vmin = mt::vec3(FLT_MAX, FLT_MAX, FLT_MAX);
|
||||
mt::vec3 vmax = mt::vec3(-FLT_MAX, -FLT_MAX, -FLT_MAX);
|
||||
for (auto vertex : _vertices)
|
||||
{
|
||||
vmin = mt::vec3::Min(vmin, vertex.Position);
|
||||
vmax = mt::vec3::Max(vmax, vertex.Position);
|
||||
}
|
||||
auto center = (vmin + vmax) / 2;
|
||||
|
||||
float fMaxDistance = 0.0f;
|
||||
for (auto vertex : _vertices)
|
||||
{
|
||||
fMaxDistance = max(fMaxDistance, mt::vec3::Distance(center, vertex.Position));
|
||||
}
|
||||
|
||||
m_fDistanceToCenter = fMaxDistance * 2.0f;
|
||||
m_fPivotX = center.x;
|
||||
m_fPivotY = center.y;
|
||||
m_fPivotZ = center.z;
|
||||
|
||||
UpdateConstantBuffer();
|
||||
}
|
||||
|
||||
|
||||
void Interop::Viewer::FrameSelection()
|
||||
{
|
||||
auto vertices = m_Mesh->GetSelectedFaceVertices();
|
||||
Frame(vertices);
|
||||
}
|
||||
|
||||
|
||||
void Interop::Viewer::FrameAll()
|
||||
{
|
||||
auto vertices = m_Mesh->GetMesh()->GetRawVertices();
|
||||
Frame(vertices);
|
||||
}
|
||||
|
||||
|
||||
void Interop::Viewer::MouseMove(int _iX, int _iY)
|
||||
{
|
||||
if (!m_bDragging)
|
||||
return;
|
||||
|
||||
if (m_bLeftDrag)
|
||||
{
|
||||
m_ArcBall->OnMove((float)_iX, (float)_iY);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto iDeltaX = _iX - m_iLastDragX;
|
||||
auto iDeltaY = m_iLastDragY - _iY;
|
||||
float fDeltaX = (float)iDeltaX / viewPort.Width;
|
||||
float fDeltaY = (float)iDeltaY / viewPort.Height;
|
||||
float mag = fDeltaX + fDeltaY;
|
||||
if (mag > 0)
|
||||
{
|
||||
m_fDistanceToCenter /= 1.0f + mag;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fDistanceToCenter *= 1.0f - mag;
|
||||
}
|
||||
m_iLastDragX = _iX;
|
||||
m_iLastDragY = _iY;
|
||||
}
|
||||
|
||||
UpdateConstantBuffer();
|
||||
}
|
||||
|
||||
|
||||
void Interop::Viewer::MouseUp(int _iX, int _iY)
|
||||
{
|
||||
m_bDragging = false;
|
||||
if (m_bLeftDrag)
|
||||
{
|
||||
m_ArcBall->OnEnd();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Interop::Viewer::Render()
|
||||
{
|
||||
IDXGraphicsAnalysis* pGraphicsAnalysis = nullptr;
|
||||
if (m_bCaptureFrame)
|
||||
{
|
||||
HRESULT getAnalysis = DXGIGetDebugInterface1(0, __uuidof(pGraphicsAnalysis), reinterpret_cast<void**>(&pGraphicsAnalysis));
|
||||
if (FAILED(getAnalysis))
|
||||
{
|
||||
pGraphicsAnalysis = nullptr;
|
||||
}
|
||||
|
||||
if (pGraphicsAnalysis != nullptr)
|
||||
{
|
||||
pGraphicsAnalysis->BeginCapture();
|
||||
m_bCaptureFrame = false;
|
||||
}
|
||||
}
|
||||
|
||||
static char zero[] = { 0, 0, 0, 0 };
|
||||
static float color[] = { 0, 0, 1, 1 };
|
||||
UINT stride = sizeof(mt::RawVertex);
|
||||
UINT offset = 0;
|
||||
|
||||
context->ClearRenderTargetView(backBufferRTV, color);
|
||||
context->ClearDepthStencilView(depthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);
|
||||
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
context->IASetInputLayout(inputLayout);
|
||||
context->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R32_UINT, 0);
|
||||
context->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
|
||||
context->VSSetConstantBuffers(0, 1, &constantBuffer);
|
||||
context->VSSetShader(vertexShader, NULL, 0);
|
||||
context->PSSetShader(pixelShader, NULL, 0);
|
||||
|
||||
context->RSSetViewports(1, &viewPort);
|
||||
if (backFaceCulling)
|
||||
{
|
||||
context->RSSetState(drawWireframe ? rsWireframeCullBack : rsSolidCullBack);
|
||||
}
|
||||
else
|
||||
{
|
||||
context->RSSetState(drawWireframe ? rsWireframeCullNone : rsSolidCullNone);
|
||||
}
|
||||
|
||||
context->OMSetBlendState(alphaBlendState, NULL, -1);
|
||||
context->OMSetDepthStencilState(depthStencilState, 0);
|
||||
context->OMSetRenderTargets(1, &backBufferRTV, depthStencilView);
|
||||
context->DrawIndexed(indexCount, 0, 0);
|
||||
|
||||
context->RSSetState(backFaceCulling ? rsSolidCullBack : rsSolidCullNone);
|
||||
context->IASetIndexBuffer(selIndexBuffer, DXGI_FORMAT_R32_UINT, 0);
|
||||
context->PSSetShader(selPixelShader, NULL, 0);
|
||||
context->DrawIndexed(selIndexCount, 0, 0);
|
||||
|
||||
context->IASetIndexBuffer(NULL, DXGI_FORMAT_R32_UINT, 0);
|
||||
context->IASetVertexBuffers(0, 1, (ID3D11Buffer* const*)zero, (const UINT*)zero, (const UINT*)zero);
|
||||
context->OMSetRenderTargets(1, (ID3D11RenderTargetView* const*)zero, NULL);
|
||||
|
||||
if (pGraphicsAnalysis != nullptr)
|
||||
{
|
||||
pGraphicsAnalysis->EndCapture();
|
||||
pGraphicsAnalysis->Release();
|
||||
pGraphicsAnalysis = nullptr;
|
||||
}
|
||||
|
||||
swapChain->Present(1, 0);
|
||||
}
|
||||
81
meshToolsV5/src/Interop/Viewer.hpp
Normal file
81
meshToolsV5/src/Interop/Viewer.hpp
Normal file
@@ -0,0 +1,81 @@
|
||||
// Interop.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <d3d11.h>
|
||||
using namespace System;
|
||||
|
||||
namespace Interop
|
||||
{
|
||||
public ref class Viewer
|
||||
{
|
||||
public:
|
||||
|
||||
static property Viewer^ Instance
|
||||
{
|
||||
public:
|
||||
Viewer^ get()
|
||||
{
|
||||
if (s_Instance == nullptr)
|
||||
{
|
||||
s_Instance = gcnew Viewer();
|
||||
}
|
||||
|
||||
return s_Instance;
|
||||
}
|
||||
}
|
||||
|
||||
property IntPtr DevicePtr
|
||||
{
|
||||
public:
|
||||
IntPtr get();
|
||||
}
|
||||
|
||||
property bool Wireframe
|
||||
{
|
||||
public:
|
||||
bool get();
|
||||
void set(bool _value);
|
||||
}
|
||||
|
||||
property bool BackFaceCulling
|
||||
{
|
||||
public:
|
||||
bool get();
|
||||
void set(bool _value);
|
||||
}
|
||||
|
||||
void Init(IntPtr _hWnd, int _iWidth, int _iHeight);
|
||||
void Resize(int _iWidth, int _iHeight);
|
||||
void MouseDown(bool _bLeftButton, int _iX, int _iY);
|
||||
void MouseMove(int _iX, int _iY);
|
||||
void MouseUp(int _iX, int _iY);
|
||||
void FrameSelection();
|
||||
void FrameAll();
|
||||
void Render();
|
||||
void LoadDocument(array<System::Byte>^ _data);
|
||||
void LoadOpMesh(mt::OpMesh* _mesh);
|
||||
void CaptureFrame();
|
||||
|
||||
private:
|
||||
void Frame(const List<mt::RawVertex>& _vertices);
|
||||
void UpdateConstantBuffer();
|
||||
void DisposeTextures();
|
||||
void CreateTextures(int _iWidth, int _iHeight);
|
||||
Viewer();
|
||||
|
||||
mt::OpMesh* m_Mesh;
|
||||
bool m_bCaptureFrame = false;
|
||||
bool m_bLeftDrag = false;
|
||||
bool m_bDragging = false;
|
||||
int m_iLastDragX = 0;
|
||||
int m_iLastDragY = 0;
|
||||
float m_fPivotX = 0.0f;
|
||||
float m_fPivotY = 0.0f;
|
||||
float m_fPivotZ = 0.0f;
|
||||
float m_fDistanceToCenter = 5.0f;
|
||||
|
||||
ArcBall* m_ArcBall;
|
||||
static Viewer^ s_Instance;
|
||||
};
|
||||
}
|
||||
193
meshToolsV5/src/Lib/Lib.vcxproj
Normal file
193
meshToolsV5/src/Lib/Lib.vcxproj
Normal file
@@ -0,0 +1,193 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{FDEBD01E-0317-4400-9208-58D7DD7CEE44}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>Lib</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(SolutionDir)lib\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)obj\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<IncludePath>$(ProjectDir);$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(SolutionDir)lib\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)obj\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<IncludePath>$(ProjectDir);$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>$(SolutionDir)bin\$(ConfigurationName)\Codegen.exe</Command>
|
||||
</PreBuildEvent>
|
||||
<PreBuildEvent>
|
||||
<Message>Generating operator code...</Message>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>$(SolutionDir)bin\$(ConfigurationName)\Codegen.exe</Command>
|
||||
</PreBuildEvent>
|
||||
<PreBuildEvent>
|
||||
<Message>Generating operator code...</Message>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="mt\common\common.h" />
|
||||
<ClInclude Include="mt\common\Linq.h" />
|
||||
<ClInclude Include="mt\common\List.h" />
|
||||
<ClInclude Include="mt\common\Map.h" />
|
||||
<ClInclude Include="mt\common\Performancer.h" />
|
||||
<ClInclude Include="mt\core\core.h" />
|
||||
<ClInclude Include="mt\core\edge.h" />
|
||||
<ClInclude Include="mt\core\Element.h" />
|
||||
<ClInclude Include="mt\core\Face.h" />
|
||||
<ClInclude Include="mt\core\Mesh.h" />
|
||||
<ClInclude Include="mt\core\Path.h" />
|
||||
<ClInclude Include="mt\core\Triangle.h" />
|
||||
<ClInclude Include="mt\core\typedefs.h" />
|
||||
<ClInclude Include="mt\core\Vertex.h" />
|
||||
<ClInclude Include="mt\math\Bounds.h" />
|
||||
<ClInclude Include="mt\math\Matrix.h" />
|
||||
<ClInclude Include="mt\math\math.h" />
|
||||
<ClInclude Include="mt\math\Plane.h" />
|
||||
<ClInclude Include="mt\math\Quaternion.h" />
|
||||
<ClInclude Include="mt\math\vec3.h" />
|
||||
<ClInclude Include="mt\mt.h" />
|
||||
<ClInclude Include="mt\operators\OpDocument.h" />
|
||||
<ClInclude Include="mt\operators\operators.h" />
|
||||
<ClInclude Include="mt\operators\OpMesh.h" />
|
||||
<ClInclude Include="mt\parser\ops.h" />
|
||||
<ClInclude Include="mt\parser\parser.h" />
|
||||
<ClInclude Include="mt\tools\Calculate.h" />
|
||||
<ClInclude Include="mt\tools\convert.h" />
|
||||
<ClInclude Include="mt\tools\Copy.h" />
|
||||
<ClInclude Include="mt\tools\CSG.h" />
|
||||
<ClInclude Include="mt\tools\CSGBase.h" />
|
||||
<ClInclude Include="mt\tools\Delete.h" />
|
||||
<ClInclude Include="mt\tools\Detach.h" />
|
||||
<ClInclude Include="mt\tools\Extrude.h" />
|
||||
<ClInclude Include="mt\tools\FFD.h" />
|
||||
<ClInclude Include="mt\tools\Flip.h" />
|
||||
<ClInclude Include="mt\tools\Group.h" />
|
||||
<ClInclude Include="mt\tools\Prefab.h" />
|
||||
<ClInclude Include="mt\tools\Project.h" />
|
||||
<ClInclude Include="mt\tools\Select.h" />
|
||||
<ClInclude Include="mt\tools\Split.h" />
|
||||
<ClInclude Include="mt\tools\Subdivide.h" />
|
||||
<ClInclude Include="mt\tools\Tags.h" />
|
||||
<ClInclude Include="mt\tools\tools.h" />
|
||||
<ClInclude Include="mt\tools\Transform.h" />
|
||||
<ClInclude Include="mt\tools\Triangulate.h" />
|
||||
<ClInclude Include="mt\tools\typedefs.h" />
|
||||
<ClInclude Include="mt\tools\Weld.h" />
|
||||
<ClInclude Include="mt\typedef.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="mt\common\Performancer.cpp" />
|
||||
<ClCompile Include="mt\core\Edge.cpp" />
|
||||
<ClCompile Include="mt\core\Face.cpp" />
|
||||
<ClCompile Include="mt\core\Mesh.cpp" />
|
||||
<ClCompile Include="mt\core\Path.cpp" />
|
||||
<ClCompile Include="mt\core\Triangle.cpp" />
|
||||
<ClCompile Include="mt\core\Vertex.cpp" />
|
||||
<ClCompile Include="mt\math\Matrix.cpp" />
|
||||
<ClCompile Include="mt\math\Math.cpp" />
|
||||
<ClCompile Include="mt\math\Plane.cpp" />
|
||||
<ClCompile Include="mt\math\Quaternion.cpp" />
|
||||
<ClCompile Include="mt\math\vec3.cpp" />
|
||||
<ClCompile Include="mt\operators\OpDocument.cpp" />
|
||||
<ClCompile Include="mt\operators\operators.cpp" />
|
||||
<ClCompile Include="mt\operators\OpMesh.cpp" />
|
||||
<ClCompile Include="mt\parser\parser.cpp" />
|
||||
<ClCompile Include="mt\tools\Calculate.cpp" />
|
||||
<ClCompile Include="mt\tools\Copy.cpp" />
|
||||
<ClCompile Include="mt\tools\CSG.cpp" />
|
||||
<ClCompile Include="mt\tools\CSGBase.cpp" />
|
||||
<ClCompile Include="mt\tools\Delete.cpp" />
|
||||
<ClCompile Include="mt\tools\Detach.cpp" />
|
||||
<ClCompile Include="mt\tools\Extrude.cpp" />
|
||||
<ClCompile Include="mt\tools\FFD.cpp" />
|
||||
<ClCompile Include="mt\tools\Flip.cpp" />
|
||||
<ClCompile Include="mt\tools\Group.cpp" />
|
||||
<ClCompile Include="mt\tools\Prefab.cpp" />
|
||||
<ClCompile Include="mt\tools\Project.cpp" />
|
||||
<ClCompile Include="mt\tools\Select.cpp" />
|
||||
<ClCompile Include="mt\tools\Split.cpp" />
|
||||
<ClCompile Include="mt\tools\Subdivide.cpp" />
|
||||
<ClCompile Include="mt\tools\Tags.cpp" />
|
||||
<ClCompile Include="mt\tools\Transform.cpp" />
|
||||
<ClCompile Include="mt\tools\Triangulate.cpp" />
|
||||
<ClCompile Include="mt\tools\Weld.cpp" />
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="List.natvis" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
285
meshToolsV5/src/Lib/Lib.vcxproj.filters
Normal file
285
meshToolsV5/src/Lib/Lib.vcxproj.filters
Normal file
@@ -0,0 +1,285 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="targetver.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\mt.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\common\common.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\common\Linq.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\common\List.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\common\Map.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\common\Performancer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\core\Element.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\core\Face.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\core\Mesh.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\core\Vertex.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\math\Bounds.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\math\math.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\math\Plane.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\math\Quaternion.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\math\vec3.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\tools\Prefab.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="stdafx.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\math\Matrix.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\operators\operators.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\parser\parser.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\parser\ops.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\tools\Calculate.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\tools\Transform.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\tools\Select.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\core\edge.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\typedef.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\tools\Weld.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\core\Triangle.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\core\core.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\core\Path.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\tools\Copy.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\tools\CSG.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\tools\CSGBase.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\tools\Delete.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\tools\Detach.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\tools\Extrude.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\tools\FFD.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\tools\Flip.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\tools\Group.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\tools\Project.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\tools\Split.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\tools\Subdivide.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\tools\Tags.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\tools\tools.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\tools\Triangulate.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\tools\typedefs.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\operators\OpMesh.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\core\typedefs.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\tools\convert.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mt\operators\OpDocument.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="mt\common\Performancer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\core\Edge.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\core\Face.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\core\Mesh.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\core\Vertex.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\math\Math.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\math\Plane.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\math\Quaternion.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\math\vec3.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\tools\Prefab.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\math\Matrix.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\parser\parser.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\tools\Calculate.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\tools\Transform.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\tools\Select.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\tools\Weld.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\core\Triangle.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\core\Path.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\tools\Copy.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\tools\CSG.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\tools\CSGBase.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\tools\Delete.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\tools\Detach.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\tools\Extrude.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\tools\FFD.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\tools\Flip.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\tools\Group.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\tools\Project.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\tools\Split.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\tools\Subdivide.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\tools\Tags.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\tools\Triangulate.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\operators\operators.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\operators\OpMesh.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mt\operators\OpDocument.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="List.natvis" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
6
meshToolsV5/src/Lib/Lib.vcxproj.user
Normal file
6
meshToolsV5/src/Lib/Lib.vcxproj.user
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ShowAllFiles>true</ShowAllFiles>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
15
meshToolsV5/src/Lib/List.natvis
Normal file
15
meshToolsV5/src/Lib/List.natvis
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
||||
<Type Name="List<*>">
|
||||
<DisplayString Condition="count == 0">empty</DisplayString>
|
||||
<DisplayString>{{ size={count} }}</DisplayString>
|
||||
<Expand>
|
||||
<ArrayItems>
|
||||
<Size>count</Size>
|
||||
<ValuePointer>data</ValuePointer>
|
||||
</ArrayItems>
|
||||
<Item Name="[size]" ExcludeView="simple">count</Item>
|
||||
<Item Name="[capacity]" ExcludeView="simple">capacity</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
</AutoVisualizer>
|
||||
296
meshToolsV5/src/Lib/mt/common/Linq.h
Normal file
296
meshToolsV5/src/Lib/mt/common/Linq.h
Normal file
@@ -0,0 +1,296 @@
|
||||
#pragma once
|
||||
|
||||
template<class TKey, class TValue>
|
||||
struct Pair
|
||||
{
|
||||
Pair()
|
||||
{
|
||||
}
|
||||
|
||||
Pair(TKey key, TValue value)
|
||||
: Key{ key }
|
||||
, Value{ value }
|
||||
{
|
||||
}
|
||||
|
||||
TKey Key;
|
||||
TValue Value;
|
||||
};
|
||||
|
||||
namespace Linq
|
||||
{
|
||||
template<class T>
|
||||
Map<T, T> ToSet(const List<T>& what)
|
||||
{
|
||||
Map<T, T> result;
|
||||
for (const auto& element : what)
|
||||
result.Add(element, element);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
List<T> ToList(const T& what)
|
||||
{
|
||||
List<T> result;
|
||||
result.Add(what);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
List<T> ToList(T array[], size_t size)
|
||||
{
|
||||
List<T> result;
|
||||
for (int i = 0; i < size; ++i)
|
||||
result.Add(array[i]);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
List<T> Concat(const List<T>& a, const List<T>& b)
|
||||
{
|
||||
List<T> result(a.Count() + b.Count());
|
||||
for (auto i = 0; i < a.Count(); ++i)
|
||||
result.Add(a[i]);
|
||||
for (auto i = 0; i < b.Count(); ++i)
|
||||
result.Add(b[i]);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
List<T> Reverse(const List<T>& what)
|
||||
{
|
||||
List<T> result;
|
||||
|
||||
for (auto i = what.Count() - 1; i >= 0; --i)
|
||||
result.Add(what[i]);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
List<T> Distinct(const List<T>& what)
|
||||
{
|
||||
List<T> result(what.Count());
|
||||
|
||||
Map<T, bool> map;
|
||||
for (const auto& element : what)
|
||||
if (!map.ContainsKey(element))
|
||||
{
|
||||
map.Add(element, false);
|
||||
result.Add(element);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void AddRange(List<T>& destination, const List<T>& what)
|
||||
{
|
||||
for (const auto& element : what)
|
||||
destination.Add(element);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
List<T> Except(const List<T>& what, const List<T>& except)
|
||||
{
|
||||
List<T> result;
|
||||
|
||||
for (const auto& element : what)
|
||||
if (except.IndexOf(element) == -1)
|
||||
result.Add(element);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
List<T> Union(const List<T>& what, const List<T>& other)
|
||||
{
|
||||
List<T> result = what;
|
||||
Linq::AddRange(result, other);
|
||||
result = Linq::Distinct(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
List<T> Intersect(const List<T>& what, const List<T>& other)
|
||||
{
|
||||
List<T> result;
|
||||
|
||||
for (const auto& element : what)
|
||||
if (other.IndexOf(element) != -1)
|
||||
result.Add(element);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class T, class TGroupValue, typename Func>
|
||||
void GroupBy(const List<T>& what, Map<TGroupValue, List<T>>& dest, Func groupByFunc)
|
||||
{
|
||||
for (const auto& element : what)
|
||||
{
|
||||
auto key = groupByFunc(element);
|
||||
List<T>* values;
|
||||
if (dest.TryGetValue(key, values))
|
||||
values->Add(element);
|
||||
else
|
||||
{
|
||||
List<T> value(1);
|
||||
value.Add(element);
|
||||
dest.Add(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Map<T, int> Group(const List<T>& what)
|
||||
{
|
||||
Map<T, int> result;
|
||||
|
||||
for (const auto& element : what)
|
||||
{
|
||||
int cnt;
|
||||
if (result.TryGetValue(element, cnt))
|
||||
result[element] = ++cnt;
|
||||
else
|
||||
result.Add(element, 1);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Map<T, int> GroupValues(const List<T>& what)
|
||||
{
|
||||
Map<T, int> result;
|
||||
|
||||
for (const auto& element : what)
|
||||
{
|
||||
int cnt;
|
||||
if (result.TryGetValue(element, cnt))
|
||||
result[element] = ++cnt;
|
||||
else
|
||||
result.Add(element, 1);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class T, class Func>
|
||||
T Max(const List<T>& what, Func sortCallback)
|
||||
{
|
||||
List<Pair<T, float>> sortData;
|
||||
|
||||
int maxId = 0;
|
||||
float maxSortValue = -Math::Infinity;
|
||||
for (int i = 0; i < what.Count(); ++i)
|
||||
{
|
||||
auto sortValue = sortCallback(what[i]);
|
||||
if (i == 0 || maxSortValue < sortValue)
|
||||
{
|
||||
maxId = i;
|
||||
maxSortValue = sortValue;
|
||||
}
|
||||
}
|
||||
|
||||
return what[maxId];
|
||||
}
|
||||
|
||||
template<class T, class Func>
|
||||
T Min(const List<T>& what, Func sortCallback)
|
||||
{
|
||||
List<Pair<T, float>> sortData;
|
||||
|
||||
int index = 0;
|
||||
float sortValue = Math::Infinity;
|
||||
for (int i = 0; i < what.Count(); ++i)
|
||||
{
|
||||
auto currentSortValue = sortCallback(what[i]);
|
||||
if (i == 0 || sortValue > currentSortValue)
|
||||
{
|
||||
index = i;
|
||||
sortValue = currentSortValue;
|
||||
}
|
||||
}
|
||||
|
||||
return what[index];
|
||||
}
|
||||
|
||||
template<class T, class Func>
|
||||
List<T> OrderByDescending(const List<T>& what, Func sortCallback)
|
||||
{
|
||||
List<T> result;
|
||||
List<T> tmp = what;
|
||||
while (tmp.Count() > 0)
|
||||
{
|
||||
auto max = Linq::Max(tmp, sortCallback);
|
||||
tmp.Remove(max);
|
||||
result.Add(max);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class T, class Func>
|
||||
List<T> Where(const List<T>& what, Func whereCallback)
|
||||
{
|
||||
List<T> result;
|
||||
|
||||
for (auto& element : what)
|
||||
if (whereCallback(element))
|
||||
result.Add(element);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class T2, class T, class Func>
|
||||
List<T2> Select(const List<T>& what, Func selectCallback)
|
||||
{
|
||||
List<T2> result;
|
||||
for (auto& element : what)
|
||||
result.Add(selectCallback(element));
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class TResult, class T, class Func>
|
||||
List<TResult> SelectMany(const List<T>& what, Func selectCallback)
|
||||
{
|
||||
List<TResult> result;
|
||||
for (auto& element : what)
|
||||
Linq::AddRange<TResult>(result, selectCallback(element));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class TResult, class T, class Func>
|
||||
List<TResult> SelectUniqueMany(const List<T>& what, Func selectCallback)
|
||||
{
|
||||
List<TResult> result(what.Count());
|
||||
Map<TResult, bool> map;
|
||||
|
||||
for (auto& element : what)
|
||||
{
|
||||
auto subResult = selectCallback(element);
|
||||
for (const auto& subElement : subResult)
|
||||
{
|
||||
if (!map.ContainsKey(subElement))
|
||||
{
|
||||
map.Add(subElement, false);
|
||||
result.Add(subElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class T, class Func>
|
||||
bool Any(const List<T>& what, Func callback)
|
||||
{
|
||||
for (auto& element : what)
|
||||
if (callback(element))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
202
meshToolsV5/src/Lib/mt/common/List.h
Normal file
202
meshToolsV5/src/Lib/mt/common/List.h
Normal file
@@ -0,0 +1,202 @@
|
||||
#pragma once
|
||||
#if _DEBUG
|
||||
//#include <assert.h>
|
||||
#define assert(a) if (!(a)) { throw #a; }
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
class List;
|
||||
|
||||
template<typename TSrc, typename TDest>
|
||||
struct convert
|
||||
{
|
||||
static TDest Convert(const TSrc& srx)
|
||||
{
|
||||
static_assert(false, "Conversion is not possible, implement a custom conversion method.");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<class T>
|
||||
class List
|
||||
{
|
||||
public:
|
||||
List(int capacity = 1)
|
||||
: capacity{ capacity }
|
||||
, count{0}
|
||||
, data{ new T[capacity] }
|
||||
{
|
||||
}
|
||||
|
||||
List(List<T>&& other)
|
||||
: count{ other.count }
|
||||
, capacity{ other.capacity }
|
||||
, data{ other.data }
|
||||
{
|
||||
other.count = 0;
|
||||
other.capacity = 0;
|
||||
other.data = nullptr;
|
||||
}
|
||||
|
||||
List(const List<T>& other)
|
||||
: count{other.count}
|
||||
, capacity{ other.count }
|
||||
, data{ new T[other.count] }
|
||||
{
|
||||
for (int index = 0; index < count; ++index)
|
||||
data[index] = other.data[index];
|
||||
}
|
||||
|
||||
~List()
|
||||
{
|
||||
delete[] data;
|
||||
data = nullptr;
|
||||
}
|
||||
|
||||
List<T>& operator=(List<T>&& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
delete[] data;
|
||||
|
||||
count = other.count;
|
||||
capacity = other.capacity;
|
||||
data = other.data;
|
||||
other.count = 0;
|
||||
other.capacity = 0;
|
||||
other.data = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
List<T>& operator=(const List<T>& other)
|
||||
{
|
||||
count = other.count;
|
||||
capacity = other.count;
|
||||
data = new T[other.count];
|
||||
for (int index = 0; index < count; ++index)
|
||||
data[index] = other.data[index];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Add(const T& value)
|
||||
{
|
||||
if (count == capacity)
|
||||
Grow();
|
||||
data[count] = value;
|
||||
count++;
|
||||
}
|
||||
|
||||
void Remove(const T& value)
|
||||
{
|
||||
auto index = IndexOf(value);
|
||||
if (index == -1)
|
||||
return;
|
||||
RemoveAt(index);
|
||||
}
|
||||
|
||||
void RemoveAt(int index)
|
||||
{
|
||||
#if _DEBUG
|
||||
assert(index >= 0 && index < count);
|
||||
#endif
|
||||
|
||||
//data[index++].~T();
|
||||
index++;
|
||||
for (; index < count; ++index)
|
||||
data[index - 1] = data[index];
|
||||
|
||||
count--;
|
||||
}
|
||||
|
||||
bool Contains(const T& value) const
|
||||
{
|
||||
return IndexOf(value) != -1;
|
||||
}
|
||||
|
||||
int IndexOf(const T& value) const
|
||||
{
|
||||
int i = 0;
|
||||
for (; i < count; ++i)
|
||||
if (data[i] == value)
|
||||
break;
|
||||
|
||||
if (i == count)
|
||||
return -1;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int Count() const
|
||||
{
|
||||
return count;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
/*for (int i = 0; i < count; ++i)
|
||||
data[i].~T();*/
|
||||
|
||||
count = 0;
|
||||
/*capacity = 1;
|
||||
delete[] data;
|
||||
data = new T[capacity];*/
|
||||
}
|
||||
|
||||
T& operator[](int index)
|
||||
{
|
||||
#if _DEBUG
|
||||
assert(index >= 0 && index < count);
|
||||
#endif
|
||||
return data[index];
|
||||
}
|
||||
|
||||
const T& operator[](int index) const
|
||||
{
|
||||
#if _DEBUG
|
||||
assert(index >= 0 && index < count);
|
||||
#endif
|
||||
return data[index];
|
||||
}
|
||||
|
||||
T* Get() const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
T* begin() const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
T* end() const
|
||||
{
|
||||
return data + count;
|
||||
}
|
||||
|
||||
template<typename TDest>
|
||||
operator TDest() const
|
||||
{
|
||||
return convert<List<T>, TDest>::Convert(*this);
|
||||
}
|
||||
|
||||
private:
|
||||
void Grow()
|
||||
{
|
||||
auto newCapacity = capacity ? capacity * 2 : 1;
|
||||
|
||||
T* newData = new T[newCapacity];
|
||||
for (int i = 0; i < count; ++i)
|
||||
newData[i] = data[i]; //newData[i] = (T&&)data[i];
|
||||
|
||||
capacity = newCapacity;
|
||||
delete[] data;
|
||||
data = newData;
|
||||
}
|
||||
|
||||
private:
|
||||
T* data;
|
||||
int count;
|
||||
int capacity;
|
||||
};
|
||||
317
meshToolsV5/src/Lib/mt/common/Map.h
Normal file
317
meshToolsV5/src/Lib/mt/common/Map.h
Normal file
@@ -0,0 +1,317 @@
|
||||
#pragma once
|
||||
#if _DEBUG
|
||||
//#include <assert.h>
|
||||
#define assert(a) if (!(a)) { throw #a; }
|
||||
#endif
|
||||
|
||||
|
||||
template<typename T>
|
||||
struct equality { static bool Equals(T a, T b) { return a == b; } };
|
||||
|
||||
template<typename T>
|
||||
struct hashing
|
||||
{
|
||||
static int Generate(T a)
|
||||
{
|
||||
return (int)a;
|
||||
}
|
||||
};
|
||||
|
||||
// Finetune this value for better performance.
|
||||
#define MAXBUCKETSIZE 10
|
||||
|
||||
template<typename TKey, typename TValue>
|
||||
class Map
|
||||
{
|
||||
public:
|
||||
struct Pair
|
||||
{
|
||||
int Hash;
|
||||
TKey Key;
|
||||
TValue Value;
|
||||
};
|
||||
|
||||
private:
|
||||
class HashBucket
|
||||
{
|
||||
public:
|
||||
HashBucket(const List<Pair*> pairs)
|
||||
: left{ nullptr }
|
||||
, right{ nullptr }
|
||||
, pairs { pairs }
|
||||
{
|
||||
if (pairs.Count() > 0)
|
||||
centerHash = pairs[0]->Hash;
|
||||
|
||||
}
|
||||
|
||||
HashBucket()
|
||||
: left{ nullptr }
|
||||
, right{ nullptr }
|
||||
{
|
||||
}
|
||||
|
||||
~HashBucket()
|
||||
{
|
||||
delete left;
|
||||
delete right;
|
||||
}
|
||||
|
||||
HashBucket* GetValue(const TKey& key, int hash, bool& success, TValue*& result) const
|
||||
{
|
||||
if ((hash == centerHash || left == nullptr) && pairs.Count() != 0)
|
||||
{
|
||||
for (const auto& pair : pairs)
|
||||
if (equality<const TKey&>::Equals(pair->Key, key))
|
||||
{
|
||||
success = true;
|
||||
result = &pair->Value;
|
||||
return nullptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
else if (left != nullptr)
|
||||
return hash < centerHash ? left : right;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
HashBucket* Remove(const TKey key, int hash, Pair*& pairResult)
|
||||
{
|
||||
if (left == nullptr || hash == centerHash)
|
||||
{
|
||||
for (int i = 0, iLength = pairs.Count(); i < iLength; ++i)
|
||||
{
|
||||
auto pair = pairs[i];
|
||||
if (equality<const TKey&>::Equals(pair->Key, key))
|
||||
{
|
||||
pairs.RemoveAt(i);
|
||||
pairResult = pair;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
else if (left != nullptr)
|
||||
return hash < centerHash ? left : right;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
HashBucket* Add(Pair* pair)
|
||||
{
|
||||
if (pairs.Count() == 0)
|
||||
centerHash = pair->Hash;
|
||||
if (centerHash == pair->Hash || (left == nullptr && pairs.Count() < MAXBUCKETSIZE))
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
for (const auto& oldPair : pairs)
|
||||
if (equality<const TKey&>::Equals(oldPair->Key, pair->Key))
|
||||
assert("Key already exists in map" && false);
|
||||
#endif
|
||||
pairs.Add(pair);
|
||||
}
|
||||
else if (left == nullptr)
|
||||
{
|
||||
centerHash = pairs[pairs.Count() / 2]->Hash;
|
||||
|
||||
List<Pair*> leftPairs;
|
||||
List<Pair*> centerPairs;
|
||||
List<Pair*> rightPairs;
|
||||
|
||||
for (const auto& oldPair : pairs)
|
||||
{
|
||||
if (oldPair->Hash < centerHash)
|
||||
leftPairs.Add(oldPair);
|
||||
if (oldPair->Hash > centerHash)
|
||||
rightPairs.Add(oldPair);
|
||||
else
|
||||
centerPairs.Add(oldPair);
|
||||
}
|
||||
|
||||
left = new HashBucket(leftPairs);
|
||||
right = new HashBucket(rightPairs);
|
||||
pairs = centerPairs;
|
||||
|
||||
return Add(pair);
|
||||
}
|
||||
else
|
||||
return pair->Hash < centerHash ? left : right;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
int centerHash;
|
||||
HashBucket* left;
|
||||
HashBucket* right;
|
||||
List<Pair*> pairs;
|
||||
};
|
||||
|
||||
public:
|
||||
Map()
|
||||
: rootBucket{ new HashBucket() }
|
||||
{
|
||||
}
|
||||
|
||||
Map(Map&& other)
|
||||
: pairs{ other.pairs }
|
||||
, rootBucket{ other.rootBucket }
|
||||
{
|
||||
other.rootBucket = nullptr;
|
||||
other.pairs.Clear();
|
||||
}
|
||||
|
||||
Map(const Map& other)
|
||||
{
|
||||
throw "Implement me bitch!";
|
||||
}
|
||||
|
||||
~Map()
|
||||
{
|
||||
for (int i = 0, iLength = pairs.Count(); i < iLength; ++i)
|
||||
delete pairs[i];
|
||||
|
||||
delete rootBucket;
|
||||
}
|
||||
|
||||
Map& operator=(Map&& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
delete rootBucket;
|
||||
pairs = other.pairs;
|
||||
rootBucket = other.rootBucket;
|
||||
other.rootBucket = nullptr;
|
||||
other.pairs.Clear();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void Add(const TKey& key, const TValue& value)
|
||||
{
|
||||
auto pair = new Pair();
|
||||
pair->Key = key;
|
||||
pair->Value = value;
|
||||
pair->Hash = hashing<const TKey&>::Generate(key);
|
||||
|
||||
auto bucket = rootBucket;
|
||||
do
|
||||
{
|
||||
bucket = bucket->Add(pair);
|
||||
} while (bucket != nullptr);
|
||||
|
||||
pairs.Add(pair);
|
||||
}
|
||||
|
||||
bool TryGetValue(const TKey& key, TValue& value) const
|
||||
{
|
||||
bool success = false;
|
||||
auto hash = hashing<const TKey&>::Generate(key);
|
||||
TValue* result;
|
||||
|
||||
auto bucket = rootBucket;
|
||||
do
|
||||
{
|
||||
bucket = bucket->GetValue(key, hash, success, result);
|
||||
} while (bucket != nullptr);
|
||||
if (success)
|
||||
value = *result;
|
||||
return success;
|
||||
}
|
||||
|
||||
bool TryGetValue(const TKey& key, TValue*& value) const
|
||||
{
|
||||
bool success = false;
|
||||
auto hash = hashing<const TKey&>::Generate(key);
|
||||
TValue* result;
|
||||
|
||||
auto bucket = rootBucket;
|
||||
do
|
||||
{
|
||||
bucket = bucket->GetValue(key, hash, success, result);
|
||||
} while (bucket != nullptr);
|
||||
if (success)
|
||||
value = result;
|
||||
return success;
|
||||
}
|
||||
|
||||
void Remove(const TKey& key)
|
||||
{
|
||||
auto hash = hashing<const TKey&>::Generate(key);
|
||||
|
||||
auto bucket = rootBucket;
|
||||
Pair* pair;
|
||||
do
|
||||
{
|
||||
bucket = bucket->Remove(key, hash, pair);
|
||||
} while (bucket != nullptr);
|
||||
|
||||
if (pair != nullptr)
|
||||
{
|
||||
pairs.Remove(pair);
|
||||
}
|
||||
}
|
||||
|
||||
TValue& GetValue(const TKey& key) const
|
||||
{
|
||||
TValue* result;
|
||||
bool success = false;
|
||||
auto hash = hashing<const TKey&>::Generate(key);
|
||||
|
||||
auto bucket = rootBucket;
|
||||
do
|
||||
{
|
||||
bucket = bucket->GetValue(key, hash, success, result);
|
||||
} while (bucket != nullptr);
|
||||
|
||||
#if _DEBUG
|
||||
assert("No value found!" && success);
|
||||
#endif
|
||||
return *result;
|
||||
}
|
||||
|
||||
Pair** begin() const
|
||||
{
|
||||
return pairs.begin();
|
||||
}
|
||||
|
||||
Pair** end() const
|
||||
{
|
||||
return pairs.end();
|
||||
}
|
||||
|
||||
int Count() const
|
||||
{
|
||||
return pairs.Count();
|
||||
}
|
||||
|
||||
bool ContainsKey(const TKey& key) const
|
||||
{
|
||||
TValue tmp;
|
||||
return TryGetValue(key, tmp);
|
||||
}
|
||||
|
||||
TValue& operator[](const TKey& key)
|
||||
{
|
||||
return GetValue(key);
|
||||
}
|
||||
|
||||
const TValue& operator[](const TKey& key) const
|
||||
{
|
||||
return GetValue(key);
|
||||
}
|
||||
|
||||
List<TValue> GetValues() const
|
||||
{
|
||||
List<TValue> result;
|
||||
for (const auto& pair : pairs)
|
||||
result.Add(pair->Value);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
HashBucket* rootBucket;
|
||||
List<Pair*> pairs;
|
||||
};
|
||||
162
meshToolsV5/src/Lib/mt/common/Performancer.cpp
Normal file
162
meshToolsV5/src/Lib/mt/common/Performancer.cpp
Normal file
@@ -0,0 +1,162 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#if _DEBUG
|
||||
|
||||
#include "Windows.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace
|
||||
{
|
||||
const long long g_Frequency = []() -> long long
|
||||
{
|
||||
LARGE_INTEGER frequency;
|
||||
QueryPerformanceFrequency(&frequency);
|
||||
return frequency.QuadPart;
|
||||
}();
|
||||
}
|
||||
|
||||
HighResClock::time_point HighResClock::now()
|
||||
{
|
||||
LARGE_INTEGER count;
|
||||
QueryPerformanceCounter(&count);
|
||||
return time_point(duration(count.QuadPart * static_cast<rep>(period::den) / g_Frequency));
|
||||
}
|
||||
|
||||
Performancer Performancer::Instance;
|
||||
|
||||
int Performancer::RegisterMethod(const std::string& name, const std::string& fullName)
|
||||
{
|
||||
data.push_back({ name, fullName });
|
||||
return data.size() - 1;
|
||||
}
|
||||
|
||||
void Performancer::AddData(int index, long long duration)
|
||||
{
|
||||
data[index].Add(duration);
|
||||
}
|
||||
|
||||
struct my_numpunct : std::numpunct<char> {
|
||||
std::string do_grouping() const { return "\03"; }
|
||||
};
|
||||
|
||||
void Performancer::Dump()
|
||||
{
|
||||
auto sorted = data;
|
||||
std::sort(sorted.begin(), sorted.end(), [](const PerformancerData& lhs, const PerformancerData& rhs)
|
||||
{
|
||||
return lhs.Elapsed > rhs.Elapsed;
|
||||
});
|
||||
|
||||
long long total = 0;
|
||||
long long average = 0;
|
||||
size_t maxNameLength = 0;
|
||||
for (const auto& data : sorted)
|
||||
{
|
||||
maxNameLength = data.Name.size() > maxNameLength ? data.Name.size() : maxNameLength;
|
||||
total += data.Elapsed;
|
||||
average += data.Elapsed / data.Calls;
|
||||
}
|
||||
|
||||
maxNameLength += 2;
|
||||
|
||||
const int usWidth = 20;
|
||||
std::locale loc(std::cout.getloc(), new my_numpunct);
|
||||
std::stringstream ss;
|
||||
ss.imbue(loc);
|
||||
ss << "Performancer summary:\n";
|
||||
ss.width(10);
|
||||
ss << std::left << "Rank";
|
||||
ss.width(maxNameLength);
|
||||
ss << std::left << "Name";
|
||||
ss.width(usWidth);
|
||||
ss << std::left << "Calls";
|
||||
ss.width(usWidth);
|
||||
ss << std::left << "Min (us)";
|
||||
ss.width(usWidth);
|
||||
ss << std::left << "Max (us)";
|
||||
ss.width(usWidth);
|
||||
ss << std::left << "Average (us)";
|
||||
ss.width(usWidth);
|
||||
ss << std::left << "Average (%)";
|
||||
ss.width(usWidth);
|
||||
ss << std::left << "Total (us)";
|
||||
ss.width(usWidth);
|
||||
ss << std::left << "Total (%)";
|
||||
ss.width(usWidth);
|
||||
ss << "Full Name";
|
||||
ss << "\n";
|
||||
|
||||
|
||||
|
||||
int i = 0;
|
||||
for (const auto& data : sorted)
|
||||
{
|
||||
i++;
|
||||
ss.width(10);
|
||||
ss << std::left << i;
|
||||
ss.width(maxNameLength);
|
||||
ss << std::left << data.Name;
|
||||
ss.width(usWidth);
|
||||
ss << std::left << data.Calls;
|
||||
ss.width(usWidth);
|
||||
ss << std::left << data.Min;
|
||||
ss.width(usWidth);
|
||||
ss << std::left << data.Max;
|
||||
ss.width(usWidth);
|
||||
ss << std::left << data.Elapsed / data.Calls;
|
||||
ss.width(usWidth);
|
||||
ss << std::left << (int)(((data.Elapsed / data.Calls) / (double)average) * 100);
|
||||
ss.width(usWidth);
|
||||
ss << std::left << data.Elapsed;
|
||||
ss.width(usWidth);
|
||||
ss << std::left << (int)((data.Elapsed / (double)total) * 100);
|
||||
ss << data.FullName;
|
||||
ss << "\n";
|
||||
}
|
||||
ss << "\n";
|
||||
|
||||
OutputDebugStringA(ss.str().c_str());
|
||||
}
|
||||
|
||||
|
||||
PerformancerEntry::PerformancerEntry(int index)
|
||||
: index{ index }
|
||||
, start{ HighResClock::now() }
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PerformancerEntry::~PerformancerEntry()
|
||||
{
|
||||
auto end = HighResClock::now();
|
||||
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
|
||||
Performancer::Instance.AddData(index, duration);
|
||||
}
|
||||
|
||||
PerformancerData::PerformancerData(const std::string& name, const std::string& fullName)
|
||||
: Name(name)
|
||||
, FullName(fullName)
|
||||
, Calls{ 0 }
|
||||
, Elapsed{ 0 }
|
||||
, Max{ 0 }
|
||||
, Min{ 0 }
|
||||
{
|
||||
}
|
||||
|
||||
void PerformancerData::Add(long long duration)
|
||||
{
|
||||
if (Calls == 0)
|
||||
{
|
||||
Min = duration;
|
||||
Max = duration;
|
||||
}
|
||||
else
|
||||
{
|
||||
Min = Min > duration ? duration : Min;
|
||||
Max = Max < duration ? duration : Max;
|
||||
}
|
||||
|
||||
Elapsed += duration;
|
||||
Calls++;
|
||||
}
|
||||
#endif
|
||||
65
meshToolsV5/src/Lib/mt/common/Performancer.h
Normal file
65
meshToolsV5/src/Lib/mt/common/Performancer.h
Normal file
@@ -0,0 +1,65 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
class PerformancerData
|
||||
{
|
||||
public:
|
||||
PerformancerData(const std::string& name, const std::string& fullName);
|
||||
void Add(long long duration);
|
||||
|
||||
std::string Name;
|
||||
std::string FullName;
|
||||
long long Calls;
|
||||
long long Elapsed;
|
||||
long long Max;
|
||||
long long Min;
|
||||
};
|
||||
|
||||
|
||||
#include <chrono>
|
||||
|
||||
struct HighResClock
|
||||
{
|
||||
typedef long long rep;
|
||||
typedef std::nano period;
|
||||
typedef std::chrono::duration<rep, period> duration;
|
||||
typedef std::chrono::time_point<HighResClock> time_point;
|
||||
static const bool is_steady = true;
|
||||
|
||||
static time_point now();
|
||||
};
|
||||
|
||||
|
||||
class Performancer
|
||||
{
|
||||
public:
|
||||
int RegisterMethod(const std::string& name, const std::string& fullName);
|
||||
void AddData(int index, long long duration);
|
||||
void Dump();
|
||||
|
||||
static Performancer Instance;
|
||||
|
||||
private:
|
||||
std::vector<PerformancerData> data;
|
||||
};
|
||||
|
||||
|
||||
class PerformancerEntry
|
||||
{
|
||||
public:
|
||||
PerformancerEntry(int index);
|
||||
~PerformancerEntry();
|
||||
|
||||
private:
|
||||
std::chrono::time_point<HighResClock> start;
|
||||
int index;
|
||||
};
|
||||
|
||||
#define PERFORMANCER \
|
||||
static int __performancerIndex = Performancer::Instance.RegisterMethod( __FUNCTION__, __FUNCSIG__); \
|
||||
PerformancerEntry __performancerEntry(__performancerIndex);
|
||||
|
||||
#define PERFORMANCER_DUMP Performancer::Instance.Dump();
|
||||
5
meshToolsV5/src/Lib/mt/common/common.h
Normal file
5
meshToolsV5/src/Lib/mt/common/common.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "List.h"
|
||||
#include "Map.h"
|
||||
#include "Linq.h"
|
||||
99
meshToolsV5/src/Lib/mt/core/Edge.cpp
Normal file
99
meshToolsV5/src/Lib/mt/core/Edge.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
namespace mt
|
||||
{
|
||||
Edge::Edge()
|
||||
: mesh{ nullptr }
|
||||
, vertices{ 2 }
|
||||
{
|
||||
PERFORMANCER;
|
||||
}
|
||||
|
||||
|
||||
Edge::Edge(Vertex* a, Vertex* b)
|
||||
: mesh{ nullptr }
|
||||
, vertices{ 2 }
|
||||
{
|
||||
PERFORMANCER;
|
||||
vertices.Add(a);
|
||||
vertices.Add(b);
|
||||
}
|
||||
|
||||
|
||||
Edge::~Edge()
|
||||
{
|
||||
PERFORMANCER;
|
||||
}
|
||||
|
||||
|
||||
Vertex* Edge::GetOtherVertex(Vertex* vertex) const
|
||||
{
|
||||
PERFORMANCER;
|
||||
return vertices[0] == vertex ? vertices[1] : vertices[0];
|
||||
}
|
||||
|
||||
|
||||
const VertexList& Edge::GetVertices() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
return vertices;
|
||||
}
|
||||
|
||||
|
||||
const FaceList& Edge::GetFaces() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
return faces;
|
||||
}
|
||||
|
||||
|
||||
EdgeList Edge::GetEdges() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
auto result = Linq::SelectUniqueMany<Edge*>(faces, [](Face* face) { return face->GetEdges(); });
|
||||
result.Remove(const_cast<Edge*>(this));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
vec3 Edge::GetDirection() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
auto direction = vertices[1]->Position - vertices[0]->Position;
|
||||
direction.Normalize();
|
||||
return direction;
|
||||
}
|
||||
|
||||
|
||||
vec3 Edge::GetCenter() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
return (vertices[1]->Position + vertices[0]->Position) * 0.5f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
float Edge::GetLength() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
auto length = vertices[0]->Position - vertices[1]->Position;
|
||||
return length.GetLength();
|
||||
}
|
||||
|
||||
|
||||
Edge* Edge::GetHalfEdge(Face* face) const
|
||||
{
|
||||
PERFORMANCER;
|
||||
|
||||
auto edges = face->GetEdges();
|
||||
auto index = edges.IndexOf(const_cast<Edge*>(this));
|
||||
auto faceVertices = face->GetVertices();
|
||||
|
||||
auto next = (index + 1) % faceVertices.Count();
|
||||
|
||||
auto newEdge = new Edge(faceVertices[index], faceVertices[next]);
|
||||
newEdge->faces = faces;
|
||||
|
||||
return newEdge;
|
||||
}
|
||||
}
|
||||
103
meshToolsV5/src/Lib/mt/core/Element.h
Normal file
103
meshToolsV5/src/Lib/mt/core/Element.h
Normal file
@@ -0,0 +1,103 @@
|
||||
#pragma once
|
||||
|
||||
namespace mt
|
||||
{
|
||||
const unsigned int InvalidElementIndex = -1;
|
||||
|
||||
template<class TData, class TMetaData, class TWrapper>
|
||||
class Element
|
||||
{
|
||||
friend class Mesh;
|
||||
friend class ElementSection;
|
||||
public:
|
||||
struct ElementSection
|
||||
{
|
||||
friend class Element;
|
||||
friend class Mesh;
|
||||
|
||||
List<TData> Data;
|
||||
List<TMetaData> MetaData;
|
||||
|
||||
ElementSection()
|
||||
{
|
||||
}
|
||||
|
||||
ElementSection(const ElementSection& other)
|
||||
: Data(other.Data)
|
||||
, MetaData(other.MetaData)
|
||||
{
|
||||
}
|
||||
|
||||
void operator=(const ElementSection& other)
|
||||
{
|
||||
Data = other.Data;
|
||||
MetaData = other.MetaData;
|
||||
}
|
||||
|
||||
~ElementSection()
|
||||
{
|
||||
for (auto& element : _wrapperList)
|
||||
element->_isDetached = true;
|
||||
}
|
||||
|
||||
TWrapper Get(unsigned int index, bool trackIndexChanges = false)
|
||||
{
|
||||
return{ index, this, _mesh, trackIndexChanges };
|
||||
}
|
||||
|
||||
private:
|
||||
List<Element*> _wrapperList;
|
||||
Mesh* _mesh;
|
||||
};
|
||||
|
||||
Element(unsigned int index, ElementSection* section, Mesh* mesh, bool trackIndexChanges)
|
||||
: _index(index)
|
||||
, _section(section)
|
||||
, _isDetached(!trackIndexChanges)
|
||||
, _mesh(mesh)
|
||||
{
|
||||
if (trackIndexChanges)
|
||||
_section->_wrapperList.Add(this);
|
||||
}
|
||||
|
||||
~Element()
|
||||
{
|
||||
if (!_isDetached)
|
||||
_section->_wrapperList.Remove(this);
|
||||
}
|
||||
|
||||
Element& operator=(const Element& other)
|
||||
{
|
||||
_isDetached = other._isDetached;
|
||||
_index = other._index;
|
||||
_section = other._section;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TData& GetData() const
|
||||
{
|
||||
return _section->Data[_index];
|
||||
}
|
||||
|
||||
void SetData(const TData& data)
|
||||
{
|
||||
_section->Data[_index] = data;
|
||||
}
|
||||
|
||||
TMetaData& GetMetaData() const
|
||||
{
|
||||
return _section->MetaData[_index];
|
||||
}
|
||||
|
||||
int GetIndex() const
|
||||
{
|
||||
return _index;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool _isDetached;
|
||||
unsigned int _index;
|
||||
ElementSection* _section;
|
||||
Mesh* _mesh;
|
||||
};
|
||||
}
|
||||
304
meshToolsV5/src/Lib/mt/core/Face.cpp
Normal file
304
meshToolsV5/src/Lib/mt/core/Face.cpp
Normal file
@@ -0,0 +1,304 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
namespace mt
|
||||
{
|
||||
Face::Face()
|
||||
{
|
||||
PERFORMANCER;
|
||||
}
|
||||
|
||||
|
||||
Face::Face(Vertex* a, Vertex* b, Vertex* c, Vertex* d)
|
||||
: materialId{ 0 }
|
||||
//, uvGenerator{ nullptr }
|
||||
, mesh{ nullptr }
|
||||
{
|
||||
PERFORMANCER;
|
||||
vertices.Add(a);
|
||||
vertices.Add(b);
|
||||
vertices.Add(c);
|
||||
if (d != nullptr)
|
||||
vertices.Add(d);
|
||||
}
|
||||
|
||||
|
||||
Face::Face(const VertexList& otherVertices)
|
||||
: materialId{ 0 }
|
||||
//, uvGenerator{ nullptr }
|
||||
, mesh{ nullptr }
|
||||
{
|
||||
PERFORMANCER;
|
||||
vertices = otherVertices;
|
||||
}
|
||||
|
||||
|
||||
Face::~Face()
|
||||
{
|
||||
PERFORMANCER;
|
||||
}
|
||||
|
||||
|
||||
vec3 Face::GetNormal() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
vec3 normal;
|
||||
|
||||
auto cnt = vertices.Count();
|
||||
for (int i = 0; i < cnt; i++)
|
||||
normal += vec3::Cross(vertices[i]->Position, vertices[(i + 1) % cnt]->Position); // cross product
|
||||
|
||||
normal.Normalize();
|
||||
return normal;
|
||||
}
|
||||
|
||||
Plane Face::GetPlane() const
|
||||
{
|
||||
return Plane(vertices[0]->Position, vertices[1]->Position, vertices[2]->Position);
|
||||
}
|
||||
|
||||
|
||||
bool Face::IsTriangle() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
return vertices.Count() == 3;
|
||||
}
|
||||
|
||||
|
||||
List<Triangle> Face::GetTriangles() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
|
||||
List<Triangle> result(2);
|
||||
if (vertices.Count() == 3)
|
||||
result.Add({ vertices[0], vertices[1], vertices[2] });
|
||||
else
|
||||
{
|
||||
result.Add({ vertices[0], vertices[1], vertices[2] });
|
||||
result.Add({ vertices[2], vertices[3], vertices[0] });
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
List<unsigned int> Face::GetIndices(bool allowQuads) const
|
||||
{
|
||||
PERFORMANCER;
|
||||
|
||||
if (allowQuads)
|
||||
return Linq::Select<unsigned int>(vertices, [](Vertex* vertex) { return vertex->GetIndex(); });
|
||||
|
||||
const int quadIndices[7] =
|
||||
{
|
||||
6,
|
||||
0, 1, 2,
|
||||
2, 3, 0
|
||||
};
|
||||
const int triangleIndices[4] =
|
||||
{
|
||||
3,
|
||||
0, 1, 2
|
||||
};
|
||||
|
||||
const int* metaIndices = vertices.Count() == 3 ? triangleIndices : quadIndices;
|
||||
|
||||
List<unsigned int> result;
|
||||
for (int i = 0; i < metaIndices[0]; ++i)
|
||||
result.Add(vertices[metaIndices[i + 1]]->GetIndex());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void Face::FlipNormal()
|
||||
{
|
||||
PERFORMANCER;
|
||||
vertices = Linq::Reverse(vertices);
|
||||
}
|
||||
|
||||
|
||||
void Face::FlipNormal(const vec3& dir)
|
||||
{
|
||||
PERFORMANCER;
|
||||
if (vec3::Dot(GetNormal(), dir) < 0)
|
||||
FlipNormal();
|
||||
}
|
||||
|
||||
|
||||
FaceList Face::Triangulate()
|
||||
{
|
||||
PERFORMANCER;
|
||||
FaceList result;
|
||||
if (IsTriangle() && !IsDegenerated())
|
||||
{
|
||||
result.Add(this);
|
||||
return result;
|
||||
}
|
||||
|
||||
auto triangles = GetTriangles();
|
||||
for (const auto& triangle : triangles)
|
||||
{
|
||||
if (triangle.IsDegenerated())
|
||||
continue;
|
||||
auto newFace = new Face(triangle.GetVertices());
|
||||
newFace->CopyProperties(this);
|
||||
mesh->AddFace(newFace);
|
||||
result.Add(newFace);
|
||||
}
|
||||
mesh->RemoveFace(this);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void Face::FlipEdge()
|
||||
{
|
||||
if (IsTriangle())
|
||||
return;
|
||||
|
||||
auto oldVertices = vertices;
|
||||
vertices.Clear();
|
||||
vertices.Add(oldVertices[1]);
|
||||
vertices.Add(oldVertices[2]);
|
||||
vertices.Add(oldVertices[3]);
|
||||
vertices.Add(oldVertices[0]);
|
||||
}
|
||||
|
||||
|
||||
bool Face::IsDegenerated() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
auto triangles = GetTriangles();
|
||||
for (const auto& triangle : triangles)
|
||||
if (!triangle.IsDegenerated())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Face::RegainIntegrity()
|
||||
{
|
||||
PERFORMANCER;
|
||||
auto triangles = GetTriangles();
|
||||
for (const auto& triangle : triangles)
|
||||
if (triangle.IsDegenerated())
|
||||
{
|
||||
vertices = Linq::Distinct(vertices);
|
||||
return vertices.Count() > 2;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Face::CopyProperties(Face* other, bool merge)
|
||||
{
|
||||
PERFORMANCER;
|
||||
if (!merge)
|
||||
tags = other->tags;
|
||||
else
|
||||
tags = Linq::Union(tags, other->tags);
|
||||
materialId = other->materialId;
|
||||
}
|
||||
|
||||
|
||||
Mesh* Face::GetMesh() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
return mesh;
|
||||
}
|
||||
|
||||
|
||||
const VertexList& Face::GetVertices() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
return vertices;
|
||||
}
|
||||
|
||||
|
||||
FaceList Face::GetFaces() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
auto result = Linq::SelectUniqueMany<Face*>(edges, [](Edge* edge) { return edge->GetFaces(); });
|
||||
result.Remove(const_cast<Face*>(this));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
const EdgeList& Face::GetEdges() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
return edges;
|
||||
}
|
||||
|
||||
|
||||
bool Face::HasTag(int tag) const
|
||||
{
|
||||
PERFORMANCER;
|
||||
return tags.IndexOf(tag) != -1;
|
||||
}
|
||||
|
||||
|
||||
bool Face::HasTagsAny(const List<int>& tagsToCheck) const
|
||||
{
|
||||
PERFORMANCER;
|
||||
return Linq::Intersect(tags, tagsToCheck).Count() > 0;
|
||||
}
|
||||
|
||||
|
||||
bool Face::HasTagsAll(const List<int>& tagsToCheck) const
|
||||
{
|
||||
PERFORMANCER;
|
||||
return Linq::Intersect(tags, tagsToCheck).Count() == tags.Count();
|
||||
}
|
||||
|
||||
|
||||
void Face::AddTag(int tag)
|
||||
{
|
||||
PERFORMANCER;
|
||||
if (HasTag(tag))
|
||||
return;
|
||||
tags.Add(tag);
|
||||
}
|
||||
|
||||
|
||||
void Face::RemoveTag(int tag)
|
||||
{
|
||||
PERFORMANCER;
|
||||
if (!HasTag(tag))
|
||||
return;
|
||||
tags.Remove(tag);
|
||||
}
|
||||
|
||||
|
||||
List<int> Face::GetTags() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
return tags;
|
||||
}
|
||||
|
||||
|
||||
void Face::SetMaterialId(int materialId)
|
||||
{
|
||||
PERFORMANCER;
|
||||
this->materialId = materialId;
|
||||
}
|
||||
|
||||
|
||||
int Face::GetMaterialId() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
return materialId;
|
||||
}
|
||||
|
||||
|
||||
/*void Face::SetUVGenerator(UVGeneratorBase* generator)
|
||||
{
|
||||
PERFORMANCER;
|
||||
uvGenerator = generator;
|
||||
}
|
||||
|
||||
|
||||
UVGeneratorBase* Face::GetUVGenerator() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
return uvGenerator;
|
||||
}*/
|
||||
}
|
||||
63
meshToolsV5/src/Lib/mt/core/Face.h
Normal file
63
meshToolsV5/src/Lib/mt/core/Face.h
Normal file
@@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
#include "typedefs.h"
|
||||
|
||||
namespace mt
|
||||
{
|
||||
class Face
|
||||
{
|
||||
friend class Mesh;
|
||||
public:
|
||||
Face();
|
||||
Face(Vertex* a, Vertex* b, Vertex* c, Vertex* d = nullptr);
|
||||
Face(const VertexList& vertices);
|
||||
~Face();
|
||||
|
||||
vec3 GetNormal() const;
|
||||
Plane GetPlane() const;
|
||||
|
||||
bool IsTriangle() const;
|
||||
void FlipNormal();
|
||||
void FlipNormal(const vec3& dir);
|
||||
FaceList Triangulate();
|
||||
void FlipEdge();
|
||||
|
||||
bool IsDegenerated() const;
|
||||
bool RegainIntegrity();
|
||||
|
||||
const VertexList& GetVertices() const;
|
||||
FaceList GetFaces() const;
|
||||
const EdgeList& GetEdges() const;
|
||||
|
||||
bool HasTag(int tag) const;
|
||||
bool HasTagsAny(const List<int>& tagsToCheck) const;
|
||||
bool HasTagsAll(const List<int>& tagsToCheck) const;
|
||||
void AddTag(int tag);
|
||||
void RemoveTag(int tag);
|
||||
List<int> GetTags() const;
|
||||
|
||||
void SetMaterialId(int materialId);
|
||||
int GetMaterialId() const;
|
||||
//void SetUVGenerator(UVGeneratorBase* generator);
|
||||
//UVGeneratorBase* GetUVGenerator() const;
|
||||
|
||||
List<unsigned int> GetIndices(bool allowQuads) const;
|
||||
|
||||
void CopyProperties(Face* other, bool merge = false);
|
||||
Mesh* GetMesh() const;
|
||||
|
||||
operator FaceList() { FaceList result; result.Add(const_cast<Face*>(this)); return result; }
|
||||
|
||||
private:
|
||||
List<Triangle> GetTriangles() const;
|
||||
List<int> GetMetaIndices() const;
|
||||
|
||||
List<int> tags;
|
||||
|
||||
//UVGeneratorBase* uvGenerator;
|
||||
VertexList vertices;
|
||||
EdgeList edges;
|
||||
int materialId;
|
||||
Mesh* mesh;
|
||||
};
|
||||
}
|
||||
302
meshToolsV5/src/Lib/mt/core/Mesh.cpp
Normal file
302
meshToolsV5/src/Lib/mt/core/Mesh.cpp
Normal file
@@ -0,0 +1,302 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
namespace mt
|
||||
{
|
||||
Mesh::Mesh()
|
||||
{
|
||||
PERFORMANCER;
|
||||
}
|
||||
|
||||
|
||||
Mesh::~Mesh()
|
||||
{
|
||||
PERFORMANCER;
|
||||
}
|
||||
|
||||
|
||||
const VertexList& Mesh::GetVertices() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
return vertices;
|
||||
}
|
||||
|
||||
|
||||
List<RawVertex> Mesh::GetRawVertices() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
return Linq::Select<RawVertex>(vertices, [](Vertex* vertex)
|
||||
{
|
||||
return vertex->GetRaw();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const FaceList& Mesh::GetFaces() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
return faces;
|
||||
}
|
||||
|
||||
|
||||
EdgeList Mesh::GetEdges() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
return Linq::SelectUniqueMany<Edge*>(faces, [](Face* face) { return face->GetEdges(); });
|
||||
}
|
||||
|
||||
|
||||
void Mesh::AddFace(Face* faceToAdd)
|
||||
{
|
||||
PERFORMANCER;
|
||||
faceToAdd->mesh = this;
|
||||
faces.Add(faceToAdd);
|
||||
|
||||
auto& faceVertices = faceToAdd->vertices;
|
||||
auto& faceEdges = faceToAdd->edges;
|
||||
|
||||
faceEdges.Add(FindEdge(faceVertices[0], faceVertices[1]));
|
||||
faceEdges.Add(FindEdge(faceVertices[1], faceVertices[2]));
|
||||
if (faceToAdd->IsTriangle())
|
||||
faceEdges.Add(FindEdge(faceVertices[2], faceVertices[0]));
|
||||
else
|
||||
{
|
||||
faceEdges.Add(FindEdge(faceVertices[2], faceVertices[3]));
|
||||
faceEdges.Add(FindEdge(faceVertices[3], faceVertices[0]));
|
||||
}
|
||||
|
||||
for (const auto& edge : faceEdges)
|
||||
edge->faces.Add(faceToAdd);
|
||||
}
|
||||
|
||||
|
||||
// Removing a face results in an update to all affected elements of the face
|
||||
// We remove the face from the meshs face list and from all neighbourfaces, edges and vertices.
|
||||
void Mesh::RemoveFace(Face* faceToRemove)
|
||||
{
|
||||
PERFORMANCER;
|
||||
faceToRemove->mesh = nullptr;
|
||||
faces.Remove(faceToRemove);
|
||||
|
||||
auto& faceEdges = faceToRemove->edges;
|
||||
for (const auto& edge : faceEdges)
|
||||
RemoveFaceFromEdge(edge, faceToRemove);
|
||||
faceEdges.Clear();
|
||||
}
|
||||
|
||||
|
||||
Edge* Mesh::FindEdge(Vertex* a, Vertex* b)
|
||||
{
|
||||
PERFORMANCER;
|
||||
for (const auto& existingEdge : a->edges)
|
||||
for (const auto& edgeVertex : existingEdge->vertices)
|
||||
if (edgeVertex == b)
|
||||
return existingEdge;
|
||||
|
||||
Edge* newEdge = new Edge{ a, b };
|
||||
newEdge->mesh = this;
|
||||
|
||||
a->edges.Add(newEdge);
|
||||
b->edges.Add(newEdge);
|
||||
|
||||
if (a->mesh == nullptr)
|
||||
{
|
||||
a->mesh = this;
|
||||
vertices.Add(a);
|
||||
}
|
||||
|
||||
if (b->mesh == nullptr)
|
||||
{
|
||||
b->mesh = this;
|
||||
vertices.Add(b);
|
||||
}
|
||||
|
||||
return newEdge;
|
||||
}
|
||||
|
||||
|
||||
List<unsigned int> Mesh::GetIndices(bool allowQuads)
|
||||
{
|
||||
PERFORMANCER;
|
||||
UpdateIndices();
|
||||
return Linq::SelectMany<unsigned int>(faces, [allowQuads](Face* face) { return face->GetIndices(allowQuads); });
|
||||
}
|
||||
|
||||
|
||||
void Mesh::UpdateIndices()
|
||||
{
|
||||
PERFORMANCER;
|
||||
for (int i = 0, iLength = vertices.Count(); i < iLength; ++i)
|
||||
vertices[i]->index = i;
|
||||
}
|
||||
|
||||
|
||||
FaceList Mesh::SplitEdge(Edge* edgeToSplit, Vertex* splitVertex)
|
||||
{
|
||||
PERFORMANCER;
|
||||
auto attachedFaces = edgeToSplit->faces;
|
||||
FaceList allNewFaces;
|
||||
|
||||
for (const auto& attachedFace : attachedFaces)
|
||||
{
|
||||
auto normal = attachedFace->GetNormal();
|
||||
auto faceEdges = attachedFace->edges;
|
||||
|
||||
FaceList newFaces;
|
||||
for (const auto& faceEdge : faceEdges)
|
||||
{
|
||||
if (faceEdge != edgeToSplit)
|
||||
{
|
||||
auto newFace = new Face(faceEdge->vertices[0], faceEdge->vertices[1], splitVertex);
|
||||
newFace->FlipNormal(normal);
|
||||
newFace->CopyProperties(attachedFace);
|
||||
|
||||
AddFace(newFace);
|
||||
allNewFaces.Add(newFace);
|
||||
newFaces.Add(newFace);
|
||||
}
|
||||
}
|
||||
|
||||
TriggerFaceReplaced(attachedFace, newFaces);
|
||||
RemoveFace(attachedFace);
|
||||
}
|
||||
|
||||
return allNewFaces;
|
||||
}
|
||||
|
||||
|
||||
void Mesh::ReplaceVertexFromFaces(const FaceList& faces, Vertex* oldVertex, Vertex* newVertex)
|
||||
{
|
||||
PERFORMANCER;
|
||||
for (const auto& face : faces)
|
||||
{
|
||||
bool isRemoved = false;
|
||||
for (int i = 0; i < face->vertices.Count(); ++i)
|
||||
if (face->vertices[i] == oldVertex)
|
||||
{
|
||||
if (!isRemoved)
|
||||
{
|
||||
RemoveFace(face);
|
||||
isRemoved = true;
|
||||
}
|
||||
face->vertices[i] = newVertex;
|
||||
}
|
||||
|
||||
if (isRemoved)
|
||||
AddFace(face);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Mesh::ReplaceVertices(const VertexList& verticesToReplace, Vertex* newVertex)
|
||||
{
|
||||
PERFORMANCER;
|
||||
for (const auto& vertex : verticesToReplace)
|
||||
{
|
||||
auto faces = vertex->GetFaces();
|
||||
ReplaceVertexFromFaces(faces, vertex, newVertex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Mesh::RemoveFaceFromEdge(Edge* edge, Face* face)
|
||||
{
|
||||
PERFORMANCER;
|
||||
edge->faces.Remove(face);
|
||||
if (edge->faces.Count() == 0)
|
||||
{
|
||||
edge->mesh = nullptr;
|
||||
|
||||
for (const auto& vertex : edge->vertices)
|
||||
RemoveEdgeFromVertex(vertex, edge);
|
||||
|
||||
delete edge;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Mesh::RemoveEdgeFromVertex(Vertex* vertex, Edge* edge)
|
||||
{
|
||||
PERFORMANCER;
|
||||
vertex->edges.Remove(edge);
|
||||
if (vertex->edges.Count() == 0)
|
||||
{
|
||||
vertex->mesh = nullptr;
|
||||
vertices.Remove(vertex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Map<int, FaceList> Mesh::GetSubMeshs()
|
||||
{
|
||||
PERFORMANCER;
|
||||
UpdateIndices();
|
||||
Map<int, FaceList> groups;
|
||||
Linq::GroupBy(this->GetFaces(), groups, [](Face* face)
|
||||
{
|
||||
return face->GetMaterialId();
|
||||
});
|
||||
return groups;
|
||||
}
|
||||
|
||||
|
||||
void Mesh::StartAutoUpdate(FaceList& faceList)
|
||||
{
|
||||
PERFORMANCER;
|
||||
autoUpdateHandles.Add(&faceList);
|
||||
}
|
||||
|
||||
|
||||
void Mesh::StopAutoUpdate(FaceList& handle)
|
||||
{
|
||||
PERFORMANCER;
|
||||
autoUpdateHandles.Remove(&handle);
|
||||
}
|
||||
|
||||
|
||||
void Mesh::TriggerFaceReplaced(Face* oldFace, const FaceList& newFaces)
|
||||
{
|
||||
PERFORMANCER;
|
||||
for (const auto& faces : autoUpdateHandles)
|
||||
{
|
||||
auto index = faces->IndexOf(oldFace);
|
||||
if (index == -1)
|
||||
continue;
|
||||
|
||||
faces->RemoveAt(index);
|
||||
|
||||
for (auto const& newFace : newFaces)
|
||||
if (!faces->Contains(newFace))
|
||||
faces->Add(newFace);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////
|
||||
AutoFaceList::AutoFaceList(FaceList&& other)
|
||||
: FaceList(other)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
AutoFaceList::AutoFaceList(const FaceList& other)
|
||||
: FaceList(other)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
AutoFaceList::~AutoFaceList()
|
||||
{
|
||||
if (mesh != nullptr)
|
||||
mesh->StopAutoUpdate(*this);
|
||||
}
|
||||
|
||||
void AutoFaceList::Init()
|
||||
{
|
||||
if (Count() == 0)
|
||||
{
|
||||
mesh = nullptr;
|
||||
return;
|
||||
}
|
||||
mesh = (*this)[0]->GetMesh();
|
||||
mesh->StartAutoUpdate(*this);
|
||||
}
|
||||
}
|
||||
67
meshToolsV5/src/Lib/mt/core/Mesh.h
Normal file
67
meshToolsV5/src/Lib/mt/core/Mesh.h
Normal file
@@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
|
||||
#include "typedefs.h"
|
||||
|
||||
namespace mt
|
||||
{
|
||||
class Mesh
|
||||
{
|
||||
public:
|
||||
Mesh();
|
||||
~Mesh();
|
||||
|
||||
const VertexList& GetVertices() const;
|
||||
List<RawVertex> GetRawVertices() const;
|
||||
const FaceList& GetFaces() const;
|
||||
EdgeList GetEdges() const;
|
||||
|
||||
void AddFace(Face* face);
|
||||
void RemoveFace(Face* face);
|
||||
|
||||
FaceList SplitEdge(Edge* edgeToSplit, Vertex* splitVertex);
|
||||
|
||||
void ReplaceVertexFromFaces(const FaceList& faces, Vertex* oldVertex, Vertex* newVertex);
|
||||
void ReplaceVertices(const VertexList& verticesToReplace, Vertex* newVertex);
|
||||
|
||||
List<unsigned int> GetIndices(bool allowQuads);
|
||||
|
||||
Map<int, FaceList> GetSubMeshs();
|
||||
|
||||
void StartAutoUpdate(FaceList& faceList);
|
||||
void StopAutoUpdate(FaceList& faceList);
|
||||
void TriggerFaceReplaced(Face* oldFace, const FaceList& newFaces);
|
||||
void UpdateIndices();
|
||||
|
||||
private:
|
||||
Edge* FindEdge(Vertex* a, Vertex* b);
|
||||
|
||||
void RemoveFaceFromEdge(Edge* edge, Face* face);
|
||||
void RemoveEdgeFromVertex(Vertex* vertex, Edge* edge);
|
||||
|
||||
private:
|
||||
VertexList vertices;
|
||||
FaceList faces;
|
||||
List<FaceList*> autoUpdateHandles;
|
||||
};
|
||||
|
||||
|
||||
// AutoFaceList will watch for changes (replace & remove) on the content of this list and will reflect these.
|
||||
// This means, when an operation removes a face which is contained in the AutoFaceList it will removed from the
|
||||
// list even when the operation was performed on a different list.
|
||||
// Example:
|
||||
// FaceList a;
|
||||
// .. // fill a
|
||||
// AutoFaceList b(a);
|
||||
// mt::Delete(a); // b.Count() == 0;
|
||||
class AutoFaceList : public FaceList
|
||||
{
|
||||
public:
|
||||
AutoFaceList(FaceList&& other);
|
||||
AutoFaceList(const FaceList& other);
|
||||
~AutoFaceList();
|
||||
|
||||
private:
|
||||
void Init();
|
||||
Mesh* mesh;
|
||||
};
|
||||
}
|
||||
100
meshToolsV5/src/Lib/mt/core/Path.cpp
Normal file
100
meshToolsV5/src/Lib/mt/core/Path.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
namespace mt
|
||||
{
|
||||
void Path::SetPoints(const List<vec3>& points)
|
||||
{
|
||||
PERFORMANCER;
|
||||
this->points = points;
|
||||
}
|
||||
|
||||
|
||||
void Path::SetScale(const List<float>& scale)
|
||||
{
|
||||
PERFORMANCER;
|
||||
this->scale = scale;
|
||||
}
|
||||
|
||||
|
||||
void Path::SetRotation(const List<float>& rotation)
|
||||
{
|
||||
PERFORMANCER;
|
||||
this->rotation = rotation;
|
||||
}
|
||||
|
||||
|
||||
vec3 Path::GetPoint(float t) const
|
||||
{
|
||||
PERFORMANCER;
|
||||
vec3 p1;
|
||||
vec3 p2;
|
||||
vec3 p0;
|
||||
vec3 p3;
|
||||
Path::GetValues(points, t, p0, p1, p2, p3);
|
||||
return Spline(p0, p1, p2, p3, t);
|
||||
}
|
||||
|
||||
|
||||
float Path::GetScale(float t) const
|
||||
{
|
||||
PERFORMANCER;
|
||||
if (scale.Count() == 0)
|
||||
return 1.0f;
|
||||
|
||||
float p1;
|
||||
float p2;
|
||||
float p0;
|
||||
float p3;
|
||||
Path::GetValues(scale, t, p0, p1, p2, p3);
|
||||
return Math::Max(0, Spline(p0, p1, p2, p3, t));
|
||||
}
|
||||
|
||||
|
||||
float Path::GetRotation(float t) const
|
||||
{
|
||||
PERFORMANCER;
|
||||
if (rotation.Count() == 0)
|
||||
return 0.0f;
|
||||
|
||||
float p1;
|
||||
float p2;
|
||||
float p0;
|
||||
float p3;
|
||||
Path::GetValues(rotation, t, p0, p1, p2, p3);
|
||||
return Spline(p0, p1, p2, p3, t);
|
||||
}
|
||||
|
||||
|
||||
vec3 Path::GetDirection(float t) const
|
||||
{
|
||||
PERFORMANCER;
|
||||
const float delta = 0.0001f;
|
||||
auto a = GetPoint(t);
|
||||
auto b = GetPoint(t + delta);
|
||||
b -= a;
|
||||
b.Normalize();
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
float Path::Spline(float p0, float p1, float p2, float p3, float t)
|
||||
{
|
||||
PERFORMANCER;
|
||||
return 0.5f *((2 * p1) +
|
||||
(-p0 + p2) * t +
|
||||
(2 * p0 - 5 * p1 + 4 * p2 - p3) * (t*t) +
|
||||
(-p0 + 3 * p1 - 3 * p2 + p3) * (t*t*t));
|
||||
}
|
||||
|
||||
|
||||
vec3 Path::Spline(const vec3& p0, const vec3& p1, const vec3& p2, const vec3& p3, float t)
|
||||
{
|
||||
PERFORMANCER;
|
||||
return
|
||||
{
|
||||
Spline(p0.x, p1.x, p2.x, p3.x, t),
|
||||
Spline(p0.y, p1.y, p2.y, p3.y, t),
|
||||
Spline(p0.z, p1.z, p2.z, p3.z, t)
|
||||
};
|
||||
}
|
||||
}
|
||||
43
meshToolsV5/src/Lib/mt/core/Path.h
Normal file
43
meshToolsV5/src/Lib/mt/core/Path.h
Normal file
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
namespace mt
|
||||
{
|
||||
class Path
|
||||
{
|
||||
public:
|
||||
void SetPoints(const List<vec3>& points);
|
||||
void SetScale(const List<float>& scale);
|
||||
void SetRotation(const List<float>& rotation);
|
||||
|
||||
vec3 GetPoint(float t) const;
|
||||
float GetScale(float t) const;
|
||||
float GetRotation(float t) const;
|
||||
vec3 GetDirection(float t) const;
|
||||
|
||||
private:
|
||||
template <typename T> static void GetValues(const List<T>& source, float& t, T& p0, T& p1, T& p2, T& p3)
|
||||
{
|
||||
auto maxT = source.Count();
|
||||
auto p1Index = (int)Math::Min(t * maxT, maxT - 1.0f);
|
||||
auto p0Index = (int)Math::Max(p1Index - 1.0f, 0.0f);
|
||||
auto p2Index = (int)Math::Min(p1Index + 1.0f, maxT - 1.0f);
|
||||
auto p3Index = (int)Math::Min(p2Index + 1.0f, maxT - 1.0f);
|
||||
|
||||
p1 = source[p1Index];
|
||||
p2 = p1Index == p2Index ? p1 + (p1 - source[p0Index]) : source[p2Index];
|
||||
p0 = p0Index == p1Index ? p1 - (p2 - p1) : source[p0Index];
|
||||
p3 = p3Index == p2Index ? p1 + (p2 - p1) : source[p3Index];
|
||||
|
||||
t = (t - (1.0f / maxT * p1Index)) / (1.0f / maxT);
|
||||
}
|
||||
|
||||
static float Spline(float p0, float p1, float p2, float p3, float t);
|
||||
static vec3 Spline(const vec3& p0, const vec3& p1, const vec3& p2, const vec3& p3, float t);
|
||||
|
||||
|
||||
private:
|
||||
List<vec3> points;
|
||||
List<float> rotation;
|
||||
List<float> scale;
|
||||
};
|
||||
}
|
||||
80
meshToolsV5/src/Lib/mt/core/Triangle.cpp
Normal file
80
meshToolsV5/src/Lib/mt/core/Triangle.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
namespace mt
|
||||
{
|
||||
Triangle::Triangle()
|
||||
{
|
||||
PERFORMANCER;
|
||||
}
|
||||
|
||||
|
||||
Triangle::Triangle(Vertex* a, Vertex* b, Vertex* c)
|
||||
{
|
||||
PERFORMANCER;
|
||||
vertices.Add(a);
|
||||
vertices.Add(b);
|
||||
vertices.Add(c);
|
||||
}
|
||||
|
||||
|
||||
Triangle::~Triangle()
|
||||
{
|
||||
PERFORMANCER;
|
||||
}
|
||||
|
||||
|
||||
vec3 Triangle::GetNormal() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
auto v1 = vertices[0]->Position;
|
||||
auto v2 = vertices[1]->Position;
|
||||
auto v3 = vertices[2]->Position;
|
||||
|
||||
auto normal = vec3::Cross(v2 - v1, v3 - v1);
|
||||
normal.Normalize();
|
||||
|
||||
return normal;
|
||||
}
|
||||
|
||||
|
||||
const List<Vertex*>& Triangle::GetVertices() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
return vertices;
|
||||
}
|
||||
|
||||
|
||||
bool Triangle::IsDegenerated() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
if (vertices[0] == vertices[1] || vertices[1] == vertices[2] || vertices[2] == vertices[0])
|
||||
return true;
|
||||
|
||||
auto d = (vertices[0]->Position - vertices[1]->Position).GetLengthSq();
|
||||
if (d <= Math::FloatEpsilon)
|
||||
return true;
|
||||
|
||||
d = (vertices[1]->Position - vertices[2]->Position).GetLengthSq();
|
||||
if (d <= Math::FloatEpsilon)
|
||||
return true;
|
||||
|
||||
d = (vertices[2]->Position - vertices[0]->Position).GetLengthSq();
|
||||
if (d <= Math::FloatEpsilon)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
float Triangle::GetArea() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
// http://www.iquilezles.org/blog/?p=1579
|
||||
auto a = (vertices[0]->Position - vertices[1]->Position).GetLengthSq();
|
||||
auto b = (vertices[1]->Position - vertices[2]->Position).GetLengthSq();
|
||||
auto c = (vertices[2]->Position - vertices[0]->Position).GetLengthSq();
|
||||
auto area = (2 * a*b + 2 * b*c + 2 * c*a - a*a - b*b - c*c) / 16;
|
||||
return Math::Sqrt(area);
|
||||
}
|
||||
}
|
||||
21
meshToolsV5/src/Lib/mt/core/Triangle.h
Normal file
21
meshToolsV5/src/Lib/mt/core/Triangle.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
namespace mt
|
||||
{
|
||||
class Triangle
|
||||
{
|
||||
public:
|
||||
Triangle();
|
||||
Triangle(Vertex* a, Vertex* b, Vertex* c);
|
||||
~Triangle();
|
||||
|
||||
vec3 GetNormal() const;
|
||||
const VertexList& GetVertices() const;
|
||||
|
||||
bool IsDegenerated() const;
|
||||
float GetArea() const;
|
||||
|
||||
private:
|
||||
VertexList vertices;
|
||||
};
|
||||
}
|
||||
142
meshToolsV5/src/Lib/mt/core/Vertex.cpp
Normal file
142
meshToolsV5/src/Lib/mt/core/Vertex.cpp
Normal file
@@ -0,0 +1,142 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
namespace mt
|
||||
{
|
||||
Vertex::Vertex(const vec3& position)
|
||||
: index{ -1 }
|
||||
, normal{ nullptr }
|
||||
, Position{ position }
|
||||
, mesh{ nullptr }
|
||||
{
|
||||
PERFORMANCER;
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
UV[i] = 0;
|
||||
UV2[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Vertex::Vertex(Vertex* other)
|
||||
: index{ -1 }
|
||||
, normal{ nullptr }
|
||||
, Position{ other->Position }
|
||||
, mesh{ nullptr }
|
||||
{
|
||||
PERFORMANCER;
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
UV[i] = other->UV[i];
|
||||
UV2[i] = other->UV2[i];
|
||||
}
|
||||
|
||||
if (other->normal != nullptr)
|
||||
normal = new vec3{ *other->normal };
|
||||
}
|
||||
|
||||
|
||||
Vertex::~Vertex()
|
||||
{
|
||||
PERFORMANCER;
|
||||
delete normal;
|
||||
}
|
||||
|
||||
|
||||
int Vertex::GetIndex() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
vec3 Vertex::GetNormal() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
if (normal == nullptr)
|
||||
{
|
||||
vec3 n;
|
||||
for (const auto& face : GetFaces())
|
||||
n += face->GetNormal();
|
||||
|
||||
n.Normalize();
|
||||
return n;
|
||||
}
|
||||
else
|
||||
return *normal;
|
||||
}
|
||||
|
||||
|
||||
void Vertex::SetNormal(const vec3& newNormal)
|
||||
{
|
||||
PERFORMANCER;
|
||||
delete normal;
|
||||
if (newNormal == vec3::zero)
|
||||
normal = nullptr;
|
||||
else
|
||||
normal = new vec3{ newNormal };
|
||||
}
|
||||
|
||||
|
||||
VertexList Vertex::GetVertices() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
auto result = Linq::SelectUniqueMany<Vertex*>(edges, [](Edge* edge) { return edge->GetVertices(); });
|
||||
result.Remove(const_cast<Vertex*>(this));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
FaceList Vertex::GetFaces() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
FaceList result;
|
||||
for (const auto& edge : edges)
|
||||
for (const auto& face : edge->GetFaces())
|
||||
if (!result.Contains(face))
|
||||
result.Add(face);
|
||||
|
||||
//auto result = Linq::SelectUniqueMany<Face*>(edges, [](Edge* edge){ return edge->GetFaces(); });
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
const EdgeList& Vertex::GetEdges() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
return edges;
|
||||
}
|
||||
|
||||
|
||||
Mesh* Vertex::GetMesh() const
|
||||
{
|
||||
PERFORMANCER;
|
||||
return mesh;
|
||||
}
|
||||
|
||||
|
||||
void Vertex::Interpolate(Vertex* other, float t)
|
||||
{
|
||||
Position = vec3::Lerp(Position, other->Position, t);
|
||||
|
||||
if (other->HasManualNormal() && HasManualNormal())
|
||||
*normal = vec3::Lerp(*normal, *other->normal, t);
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
UV[i] = Math::Lerp(UV[i], other->UV[i], t);
|
||||
UV2[i] = Math::Lerp(UV2[i], other->UV2[i], t);
|
||||
}
|
||||
}
|
||||
|
||||
RawVertex Vertex::GetRaw() const
|
||||
{
|
||||
RawVertex result;
|
||||
result.Position = Position;
|
||||
result.Normal = GetNormal();
|
||||
for (int i = 0; i < 4; ++i)
|
||||
result.UV[i] = UV[i];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
52
meshToolsV5/src/Lib/mt/core/Vertex.h
Normal file
52
meshToolsV5/src/Lib/mt/core/Vertex.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include "typedefs.h"
|
||||
|
||||
namespace mt
|
||||
{
|
||||
struct RawVertex
|
||||
{
|
||||
vec3 Position;
|
||||
vec3 Normal;
|
||||
float UV[4];
|
||||
};
|
||||
|
||||
class Vertex
|
||||
{
|
||||
friend class Mesh;
|
||||
friend class Selection;
|
||||
public:
|
||||
Vertex(const vec3& position);
|
||||
Vertex(Vertex* other);
|
||||
//Vertex();
|
||||
~Vertex();
|
||||
|
||||
int GetIndex() const;
|
||||
|
||||
vec3 GetNormal() const;
|
||||
void SetNormal(const vec3& normal);
|
||||
|
||||
bool HasManualNormal() const { return normal != nullptr; }
|
||||
|
||||
VertexList GetVertices() const;
|
||||
FaceList GetFaces() const;
|
||||
const EdgeList& GetEdges() const;
|
||||
|
||||
Mesh* GetMesh() const;
|
||||
|
||||
void Interpolate(Vertex* other, float t);
|
||||
|
||||
RawVertex GetRaw() const;
|
||||
|
||||
public:
|
||||
vec3 Position;
|
||||
float UV[4];
|
||||
float UV2[4];
|
||||
|
||||
private:
|
||||
vec3* normal;
|
||||
int index;
|
||||
EdgeList edges;
|
||||
Mesh* mesh;
|
||||
};
|
||||
}
|
||||
8
meshToolsV5/src/Lib/mt/core/core.h
Normal file
8
meshToolsV5/src/Lib/mt/core/core.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "Vertex.h"
|
||||
#include "Triangle.h"
|
||||
#include "Face.h"
|
||||
#include "Mesh.h"
|
||||
#include "Edge.h"
|
||||
#include "Path.h"
|
||||
29
meshToolsV5/src/Lib/mt/core/edge.h
Normal file
29
meshToolsV5/src/Lib/mt/core/edge.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
namespace mt
|
||||
{
|
||||
class Edge
|
||||
{
|
||||
friend class Mesh;
|
||||
public:
|
||||
Edge();
|
||||
Edge(Vertex* a, Vertex* b);
|
||||
~Edge();
|
||||
|
||||
Vertex* GetOtherVertex(Vertex* vertex) const;
|
||||
|
||||
const VertexList& GetVertices() const;
|
||||
const FaceList& GetFaces() const;
|
||||
EdgeList GetEdges() const;
|
||||
|
||||
vec3 GetDirection() const;
|
||||
vec3 GetCenter() const;
|
||||
float GetLength() const;
|
||||
|
||||
Edge* GetHalfEdge(Face* face) const;
|
||||
private:
|
||||
VertexList vertices;
|
||||
FaceList faces;
|
||||
Mesh* mesh;
|
||||
};
|
||||
}
|
||||
12
meshToolsV5/src/Lib/mt/core/typedefs.h
Normal file
12
meshToolsV5/src/Lib/mt/core/typedefs.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
namespace mt
|
||||
{
|
||||
class Vertex;
|
||||
class Edge;
|
||||
class Face;
|
||||
|
||||
typedef List<Vertex*> VertexList;
|
||||
typedef List<Edge*> EdgeList;
|
||||
typedef List<Face*> FaceList;
|
||||
}
|
||||
29
meshToolsV5/src/Lib/mt/math/Bounds.h
Normal file
29
meshToolsV5/src/Lib/mt/math/Bounds.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
namespace mt
|
||||
{
|
||||
class Bounds
|
||||
{
|
||||
public:
|
||||
Bounds(vec3 min, vec3 max)
|
||||
: Min{ min }
|
||||
, Max{ max }
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
vec3 Min;
|
||||
vec3 Max;
|
||||
|
||||
float GetRadius() const
|
||||
{
|
||||
auto length = (Max - Min).GetLength();
|
||||
return length / 2;
|
||||
}
|
||||
|
||||
vec3 GetCenter() const
|
||||
{
|
||||
return (Min + Max) * 0.5f;
|
||||
}
|
||||
};
|
||||
}
|
||||
10
meshToolsV5/src/Lib/mt/math/Math.cpp
Normal file
10
meshToolsV5/src/Lib/mt/math/Math.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
#include <stdafx.h>
|
||||
|
||||
namespace mt
|
||||
{
|
||||
const float Math::Rad2Deg = 57.2957795f;
|
||||
const float Math::Deg2Rad = 3.14159265359f / 180;
|
||||
const float Math::FloatEpsilon = 1E-5f;
|
||||
const float Math::Pi = 3.14159265359f;
|
||||
const float Math::Infinity = 3.402823466e+38F;
|
||||
}
|
||||
61
meshToolsV5/src/Lib/mt/math/Matrix.cpp
Normal file
61
meshToolsV5/src/Lib/mt/math/Matrix.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#include <stdafx.h>
|
||||
|
||||
namespace mt
|
||||
{
|
||||
Matrix Matrix::identity;
|
||||
|
||||
|
||||
Matrix::Matrix()
|
||||
: M11{ 1 }
|
||||
, M12{ 0 }
|
||||
, M13{ 0 }
|
||||
, M14{ 0 }
|
||||
, M21{ 0 }
|
||||
, M22{ 1 }
|
||||
, M23{ 0 }
|
||||
, M24{ 0 }
|
||||
, M31{ 0 }
|
||||
, M32{ 0 }
|
||||
, M33{ 1 }
|
||||
, M34{ 0 }
|
||||
, M41{ 0 }
|
||||
, M42{ 0 }
|
||||
, M43{ 0 }
|
||||
, M44{ 1 }
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Matrix Matrix::FromQuaternion(const Quaternion& quat)
|
||||
{
|
||||
float xx = 2 * quat.x * quat.x;
|
||||
float xy = 2 * quat.x * quat.y;
|
||||
float xw = 2 * quat.x * quat.w;
|
||||
float yy = 2 * quat.y * quat.y;
|
||||
float yz = 2 * quat.y * quat.z;
|
||||
float yw = 2 * quat.y * quat.w;
|
||||
float zx = 2 * quat.z * quat.x;
|
||||
float zz = 2 * quat.z * quat.z;
|
||||
float zw = 2 * quat.z * quat.w;
|
||||
|
||||
Matrix result;
|
||||
result.M11 = 1 - (yy + zz);
|
||||
result.M12 = xy + zw;
|
||||
result.M13 = zx - yw;
|
||||
result.M14 = 0;
|
||||
result.M21 = xy - zw;
|
||||
result.M22 = 1 - (zz + xx);
|
||||
result.M23 = yz + xw;
|
||||
result.M24 = 0;
|
||||
result.M31 = zx + yw;
|
||||
result.M32 = yz - xw;
|
||||
result.M33 = 1 - (yy + xx);
|
||||
result.M34 = 0;
|
||||
result.M41 = 0;
|
||||
result.M42 = 0;
|
||||
result.M43 = 0;
|
||||
result.M44 = 1;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
32
meshToolsV5/src/Lib/mt/math/Matrix.h
Normal file
32
meshToolsV5/src/Lib/mt/math/Matrix.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
namespace mt
|
||||
{
|
||||
class Matrix
|
||||
{
|
||||
public:
|
||||
static Matrix identity;
|
||||
static Matrix FromQuaternion(const Quaternion& quat);
|
||||
|
||||
public:
|
||||
Matrix();
|
||||
|
||||
public:
|
||||
float M11;
|
||||
float M12;
|
||||
float M13;
|
||||
float M14;
|
||||
float M21;
|
||||
float M22;
|
||||
float M23;
|
||||
float M24;
|
||||
float M31;
|
||||
float M32;
|
||||
float M33;
|
||||
float M34;
|
||||
float M41;
|
||||
float M42;
|
||||
float M43;
|
||||
float M44;
|
||||
};
|
||||
}
|
||||
67
meshToolsV5/src/Lib/mt/math/Plane.cpp
Normal file
67
meshToolsV5/src/Lib/mt/math/Plane.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
namespace mt
|
||||
{
|
||||
Plane::Plane(const vec3& normal, const vec3& point)
|
||||
: normal{ normal }
|
||||
, distance{ vec3::Dot(normal, point) }
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Plane::Plane(const vec3& a, const vec3& b, const vec3& c)
|
||||
{
|
||||
normal = vec3::Cross(b - a, c - a);
|
||||
normal.Normalize();
|
||||
distance = vec3::Dot(normal, a);
|
||||
}
|
||||
|
||||
|
||||
Plane::~Plane()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
float Plane::GetDistanceToPoint(const vec3& point) const
|
||||
{
|
||||
return vec3::Dot(normal, point) - distance;
|
||||
}
|
||||
|
||||
|
||||
vec3 Plane::GetNormal() const
|
||||
{
|
||||
return normal;
|
||||
}
|
||||
|
||||
|
||||
float Plane::GetDistance() const
|
||||
{
|
||||
return distance;
|
||||
}
|
||||
|
||||
|
||||
bool Plane::GetSide(const vec3& point) const
|
||||
{
|
||||
return GetDistanceToPoint(point) > 0.0;
|
||||
}
|
||||
|
||||
|
||||
void Plane::Flip()
|
||||
{
|
||||
normal = -normal;
|
||||
distance = -distance;
|
||||
}
|
||||
|
||||
|
||||
float Plane::IntersectLinesegment(vec3 a, vec3 b, vec3& result) const
|
||||
{
|
||||
auto ba = b - a;
|
||||
float nDotA = vec3::Dot(normal, a);
|
||||
float nDotBA = vec3::Dot(normal, ba);
|
||||
|
||||
auto d = (distance - nDotA) / nDotBA;
|
||||
result = a + (ba * d);
|
||||
return d;
|
||||
}
|
||||
}
|
||||
#include <stdafx.h>
|
||||
23
meshToolsV5/src/Lib/mt/math/Plane.h
Normal file
23
meshToolsV5/src/Lib/mt/math/Plane.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
namespace mt
|
||||
{
|
||||
class Plane
|
||||
{
|
||||
public:
|
||||
Plane(const vec3& normal, const vec3& point);
|
||||
Plane(const vec3& a, const vec3& b, const vec3& c);
|
||||
~Plane();
|
||||
|
||||
float GetDistanceToPoint(const vec3& point) const;
|
||||
vec3 GetNormal() const;
|
||||
float GetDistance() const;
|
||||
bool GetSide(const vec3& point) const;
|
||||
void Flip();
|
||||
float IntersectLinesegment(vec3 a, vec3 b, vec3& result) const;
|
||||
|
||||
private:
|
||||
vec3 normal;
|
||||
float distance;
|
||||
};
|
||||
}
|
||||
125
meshToolsV5/src/Lib/mt/math/Quaternion.cpp
Normal file
125
meshToolsV5/src/Lib/mt/math/Quaternion.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
#include <stdafx.h>
|
||||
|
||||
namespace mt
|
||||
{
|
||||
Quaternion Quaternion::identity;
|
||||
|
||||
|
||||
Quaternion::Quaternion()
|
||||
: x{ 0 }
|
||||
, y{ 0 }
|
||||
, z{ 0 }
|
||||
, w{ 1 }
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Quaternion Quaternion::FromAxisAngle(const vec3& axis, float angle)
|
||||
{
|
||||
float halfAngle = angle * .5f;
|
||||
float s = (float)Math::Sin(halfAngle);
|
||||
Quaternion q;
|
||||
q.x = axis.x * s;
|
||||
q.y = axis.y * s;
|
||||
q.z = axis.z * s;
|
||||
q.w = (float)Math::Cos(halfAngle);
|
||||
return q;
|
||||
}
|
||||
|
||||
|
||||
Quaternion Quaternion::LookRotation(const vec3& forward)
|
||||
{
|
||||
float dot = vec3::Dot(vec3::up, forward);
|
||||
|
||||
if (Math::Abs(dot - (-1.0f)) < 0.000001f)
|
||||
{
|
||||
return FromAxisAngle(vec3::forward, Math::Pi);
|
||||
}
|
||||
if (Math::Abs(dot - (1.0f)) < 0.000001f)
|
||||
{
|
||||
return Quaternion::identity;
|
||||
}
|
||||
|
||||
float rotAngle = (float)Math::Acos(dot);
|
||||
vec3 rotAxis = vec3::Cross(vec3::up, forward);
|
||||
rotAxis.Normalize();
|
||||
|
||||
return FromAxisAngle(rotAxis, rotAngle);
|
||||
}
|
||||
|
||||
|
||||
Quaternion Quaternion::FromTo(vec3 v0, vec3 v1)
|
||||
{
|
||||
Quaternion q;
|
||||
v0.Normalize();
|
||||
v1.Normalize();
|
||||
|
||||
float d = vec3::Dot(v0, v1);
|
||||
// If dot == 1, vectors are the same
|
||||
if (d >= 1.0f)
|
||||
{
|
||||
return Quaternion::identity;
|
||||
}
|
||||
if (d < (1e-6f - 1.0f))
|
||||
{
|
||||
vec3 axis = vec3::Cross(vec3::right, v0);
|
||||
if (axis.GetLengthSq() < Math::FloatEpsilon) // pick another if colinear
|
||||
axis = vec3::Cross(vec3::up, v0);
|
||||
axis.Normalize();
|
||||
return Quaternion::FromAxisAngle(axis, Math::Pi);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto s = Math::Sqrt((1 + d) * 2);
|
||||
auto invs = 1 / s;
|
||||
|
||||
auto c = vec3::Cross(v0, v1);
|
||||
|
||||
q.x = c.x * invs;
|
||||
q.y = c.y * invs;
|
||||
q.z = c.z * invs;
|
||||
q.w = s * 0.5f;
|
||||
q.Normalize();
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
||||
|
||||
void Quaternion::Inverse()
|
||||
{
|
||||
auto newX = w;
|
||||
auto newY = -x;
|
||||
auto newZ = -y;
|
||||
auto newW = -z;
|
||||
x = newX;
|
||||
y = newY;
|
||||
z = newZ;
|
||||
w = newW;
|
||||
|
||||
Normalize();
|
||||
}
|
||||
|
||||
|
||||
void Quaternion::Normalize()
|
||||
{
|
||||
auto norm = w*w + x*x + y*y + z*z;
|
||||
auto s = 1 / norm;
|
||||
|
||||
x *= s;
|
||||
y *= s;
|
||||
z *= s;
|
||||
w *= s;
|
||||
}
|
||||
|
||||
|
||||
Quaternion Quaternion::operator*(Quaternion b) const
|
||||
{
|
||||
Quaternion result;
|
||||
result.x = (b.x * w) + (b.w * x) + ((y * b.z) - (z * b.y));
|
||||
result.y = (b.y * w) + (b.w * y) + ((z * b.x) - (x * b.z));
|
||||
result.z = (b.z * w) + (b.w * z) + ((x * b.y) - (y * b.x));
|
||||
result.w = (b.w * w) - ((b.x * x) + (y * b.y) + (z * b.z));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
26
meshToolsV5/src/Lib/mt/math/Quaternion.h
Normal file
26
meshToolsV5/src/Lib/mt/math/Quaternion.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
namespace mt
|
||||
{
|
||||
class Quaternion
|
||||
{
|
||||
public:
|
||||
static Quaternion identity;
|
||||
static Quaternion LookRotation(const vec3& normal);
|
||||
static Quaternion FromAxisAngle(const vec3& axis, float angle);
|
||||
static Quaternion FromTo(vec3 v0, vec3 v1);
|
||||
Quaternion operator* (Quaternion other) const;
|
||||
|
||||
public:
|
||||
Quaternion();
|
||||
|
||||
void Inverse();
|
||||
void Normalize();
|
||||
|
||||
public:
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float w;
|
||||
};
|
||||
}
|
||||
118
meshToolsV5/src/Lib/mt/math/math.h
Normal file
118
meshToolsV5/src/Lib/mt/math/math.h
Normal file
@@ -0,0 +1,118 @@
|
||||
#pragma once
|
||||
|
||||
#include <cmath> // acos and shit
|
||||
#include "vec3.h"
|
||||
#include "Bounds.h"
|
||||
|
||||
namespace mt
|
||||
{
|
||||
struct vec2
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
|
||||
struct vec4
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float w;
|
||||
};
|
||||
|
||||
class Math
|
||||
{
|
||||
public:
|
||||
static const float Rad2Deg;
|
||||
static const float Deg2Rad;
|
||||
static const float FloatEpsilon;
|
||||
static const float Pi;
|
||||
static const float Infinity;
|
||||
|
||||
static float Clamp01(float a)
|
||||
{
|
||||
return a > 1 ? 1 : a < 0 ? 0 : a;
|
||||
}
|
||||
|
||||
static float Pow(float a, float b)
|
||||
{
|
||||
return std::pow(a, b);
|
||||
}
|
||||
|
||||
static float Max(float a, float b)
|
||||
{
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
static float Min(float a, float b)
|
||||
{
|
||||
return a > b ? b : a;
|
||||
}
|
||||
|
||||
static float Abs(float a)
|
||||
{
|
||||
return a > 0 ? a : -a;
|
||||
}
|
||||
|
||||
static float Sin(float x)
|
||||
{
|
||||
/*_asm fld x
|
||||
_asm fsin*/
|
||||
return std::sin(x);
|
||||
}
|
||||
|
||||
static float Cos(float x)
|
||||
{
|
||||
/*_asm fld x
|
||||
_asm fcos*/
|
||||
return std::cos(x);
|
||||
}
|
||||
|
||||
static float Acos(float x)
|
||||
{
|
||||
/*_asm
|
||||
{
|
||||
fld x
|
||||
fld x
|
||||
fmul
|
||||
fld1
|
||||
fsubr
|
||||
fsqrt
|
||||
fxch
|
||||
fpatan
|
||||
}*/
|
||||
return std::acos(x);
|
||||
}
|
||||
|
||||
static float Atan2(float x, float y)
|
||||
{
|
||||
return std::atan2(x, y);
|
||||
}
|
||||
|
||||
static float Lerp(float a, float b, float t)
|
||||
{
|
||||
return a + t * (b - a);
|
||||
}
|
||||
|
||||
static float Sqrt(float x)
|
||||
{
|
||||
#if _DEBUG
|
||||
return std::sqrt(x);
|
||||
#else
|
||||
float xhalf = 0.5f*x;
|
||||
int i = *(int*)&x;
|
||||
i = 0x5f375a86 - (i >> 1);
|
||||
x = *(float*)&i;
|
||||
x = x*(1.5f - xhalf*x*x);
|
||||
x = x*(1.5f - xhalf*x*x);
|
||||
x = x*(1.5f - xhalf*x*x);
|
||||
x = 1 / x;
|
||||
return x;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#include "Plane.h"
|
||||
#include "Matrix.h"
|
||||
#include "Quaternion.h"
|
||||
228
meshToolsV5/src/Lib/mt/math/vec3.cpp
Normal file
228
meshToolsV5/src/Lib/mt/math/vec3.cpp
Normal file
@@ -0,0 +1,228 @@
|
||||
#include <stdafx.h>
|
||||
|
||||
namespace mt
|
||||
{
|
||||
vec3 const vec3::zero = { 0, 0, 0 };
|
||||
vec3 const vec3::one = { 1,1,1 };
|
||||
vec3 const vec3::up = { 0, 1, 0 };
|
||||
vec3 const vec3::down = { 0, -1, 0 };
|
||||
vec3 const vec3::left = { -1, 0, 0 };
|
||||
vec3 const vec3::right = { 1, 0, 0 };
|
||||
vec3 const vec3::forward = { 0, 0, 1 };
|
||||
vec3 const vec3::back = { 0, 0, -1 };
|
||||
|
||||
vec3::vec3()
|
||||
: x{ 0 }
|
||||
, y{ 0 }
|
||||
, z{ 0 }
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
vec3::vec3(float x, float y, float z)
|
||||
: x{ x }
|
||||
, y{ y }
|
||||
, z{ z }
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
vec3::vec3(const vec3& other)
|
||||
: x{ other.x }
|
||||
, y{ other.y }
|
||||
, z{ other.z }
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
vec3::~vec3()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
float vec3::GetLength() const
|
||||
{
|
||||
return Math::Sqrt(x*x + y*y + z*z);
|
||||
}
|
||||
|
||||
|
||||
float vec3::GetLengthSq() const
|
||||
{
|
||||
return x*x + y*y + z*z;
|
||||
}
|
||||
|
||||
|
||||
void vec3::Normalize()
|
||||
{
|
||||
auto length = GetLength();
|
||||
if (length == 0)
|
||||
{
|
||||
x = y = z = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
x /= length;
|
||||
y /= length;
|
||||
z /= length;
|
||||
}
|
||||
|
||||
|
||||
vec3 vec3::Mul(const vec3& a, const vec3& b)
|
||||
{
|
||||
return vec3(a.x * b.x, a.y * b.y, a.z * b.z);
|
||||
}
|
||||
|
||||
|
||||
float vec3::Dot(const vec3& a, const vec3& b)
|
||||
{
|
||||
float result = 0;
|
||||
result += a.x * b.x;
|
||||
result += a.y * b.y;
|
||||
result += a.z * b.z;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
vec3 vec3::Cross(const vec3& a, const vec3& b)
|
||||
{
|
||||
return vec3(
|
||||
a.y * b.z - a.z * b.y,
|
||||
a.z * b.x - a.x * b.z,
|
||||
a.x * b.y - a.y * b.x
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
vec3 vec3::Transform(const vec3& a, const Matrix& m)
|
||||
{
|
||||
return{
|
||||
(a.x * m.M11) + (a.y * m.M21) + (a.z * m.M31) + m.M41,
|
||||
(a.x * m.M12) + (a.y * m.M22) + (a.z * m.M32) + m.M42,
|
||||
(a.x * m.M13) + (a.y * m.M23) + (a.z * m.M33) + m.M43
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
vec3 vec3::Min(const vec3& a, const vec3& b)
|
||||
{
|
||||
return{
|
||||
Math::Min(a.x, b.x),
|
||||
Math::Min(a.y, b.y),
|
||||
Math::Min(a.z, b.z),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
vec3 vec3::Max(const vec3& a, const vec3& b)
|
||||
{
|
||||
return{
|
||||
Math::Max(a.x, b.x),
|
||||
Math::Max(a.y, b.y),
|
||||
Math::Max(a.z, b.z),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
float vec3::Distance(const vec3& a, const vec3& b)
|
||||
{
|
||||
return (a - b).GetLength();
|
||||
}
|
||||
|
||||
|
||||
float vec3::DistanceSq(const vec3& a, const vec3& b)
|
||||
{
|
||||
return (a - b).GetLengthSq();
|
||||
}
|
||||
|
||||
|
||||
vec3 vec3::Lerp(const vec3& a, const vec3& b, float t)
|
||||
{
|
||||
return{
|
||||
Math::Lerp(a.x, b.x, t),
|
||||
Math::Lerp(a.y, b.y, t),
|
||||
Math::Lerp(a.z, b.z, t)
|
||||
};
|
||||
}
|
||||
|
||||
vec3 vec3::operator- () const
|
||||
{
|
||||
return{ -x, -y, -z };
|
||||
}
|
||||
|
||||
|
||||
bool vec3::operator== (const vec3& other) const
|
||||
{
|
||||
return x == other.x && y == other.y && z == other.z;
|
||||
}
|
||||
|
||||
|
||||
bool vec3::operator!= (const vec3& other) const
|
||||
{
|
||||
return x != other.x || y != other.y || z != other.z;
|
||||
}
|
||||
|
||||
|
||||
vec3 vec3::operator+ (const vec3& other) const
|
||||
{
|
||||
return{ x + other.x, y + other.y, z + other.z };
|
||||
}
|
||||
|
||||
|
||||
void vec3::operator+= (const vec3& other)
|
||||
{
|
||||
x += other.x;
|
||||
y += other.y;
|
||||
z += other.z;
|
||||
}
|
||||
|
||||
|
||||
void vec3::operator-= (const vec3& other)
|
||||
{
|
||||
x -= other.x;
|
||||
y -= other.y;
|
||||
z -= other.z;
|
||||
}
|
||||
|
||||
|
||||
void vec3::operator/= (float other)
|
||||
{
|
||||
x /= other;
|
||||
y /= other;
|
||||
z /= other;
|
||||
}
|
||||
|
||||
|
||||
void vec3::operator*= (float other)
|
||||
{
|
||||
x *= other;
|
||||
y *= other;
|
||||
z *= other;
|
||||
}
|
||||
|
||||
|
||||
vec3 vec3::operator- (const vec3& other) const
|
||||
{
|
||||
return{ x - other.x, y - other.y, z - other.z };
|
||||
}
|
||||
|
||||
|
||||
vec3 vec3::operator* (float other) const
|
||||
{
|
||||
return{ x * other, y * other, z * other };
|
||||
}
|
||||
|
||||
|
||||
vec3 vec3::operator/ (float other) const
|
||||
{
|
||||
return{ x / other, y / other, z / other };
|
||||
}
|
||||
|
||||
|
||||
vec3 vec3::operator* (const Quaternion& q) const
|
||||
{
|
||||
vec3 qxyz = { q.x, q.y, q.z };
|
||||
auto t = vec3::Cross(qxyz, *this) * 2;
|
||||
return *this + t * q.w + vec3::Cross(qxyz, t);
|
||||
}
|
||||
}
|
||||
59
meshToolsV5/src/Lib/mt/math/vec3.h
Normal file
59
meshToolsV5/src/Lib/mt/math/vec3.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
namespace mt
|
||||
{
|
||||
class Matrix;
|
||||
class Quaternion;
|
||||
|
||||
class vec3
|
||||
{
|
||||
public:
|
||||
static const vec3 zero;
|
||||
static const vec3 one;
|
||||
static const vec3 up;
|
||||
static const vec3 down;
|
||||
static const vec3 left;
|
||||
static const vec3 right;
|
||||
static const vec3 forward;
|
||||
static const vec3 back;
|
||||
|
||||
vec3();
|
||||
vec3(float x, float y, float z);
|
||||
vec3(const vec3& other);
|
||||
~vec3();
|
||||
|
||||
float GetLength() const;
|
||||
float GetLengthSq() const;
|
||||
void Normalize();
|
||||
|
||||
static vec3 Mul(const vec3& a, const vec3& b);
|
||||
|
||||
static float Dot(const vec3& a, const vec3& b);
|
||||
static vec3 Cross(const vec3& a, const vec3& b);
|
||||
static vec3 Transform(const vec3& a, const Matrix& m);
|
||||
|
||||
static vec3 Min(const vec3& a, const vec3& b);
|
||||
static vec3 Max(const vec3& a, const vec3& b);
|
||||
static float Distance(const vec3& a, const vec3& b);
|
||||
static float DistanceSq(const vec3& a, const vec3& b);
|
||||
static vec3 Lerp(const vec3& a, const vec3& b, float t);
|
||||
|
||||
vec3 operator- () const;
|
||||
bool operator== (const vec3& other) const;
|
||||
bool operator!= (const vec3& other) const;
|
||||
vec3 operator+ (const vec3& other) const;
|
||||
void operator+= (const vec3& other);
|
||||
void operator-= (const vec3& other);
|
||||
void operator/= (float other);
|
||||
void operator*= (float other);
|
||||
vec3 operator- (const vec3& other) const;
|
||||
vec3 operator* (float other) const;
|
||||
vec3 operator/ (float other) const;
|
||||
vec3 operator* (const Quaternion& q) const;
|
||||
|
||||
public:
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
};
|
||||
}
|
||||
20
meshToolsV5/src/Lib/mt/mt.h
Normal file
20
meshToolsV5/src/Lib/mt/mt.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "typedef.h"
|
||||
|
||||
#include "common/common.h"
|
||||
#include "math/math.h"
|
||||
#include "core/core.h"
|
||||
|
||||
#if _DEBUG
|
||||
#include "common/Performancer.h"
|
||||
#else
|
||||
#define PERFORMANCER
|
||||
#define PERFORMANCER_DUMP
|
||||
#endif
|
||||
|
||||
#include "operators/OpMesh.h"
|
||||
#include "operators/operators.h"
|
||||
#include "parser/registers.h"
|
||||
#include "parser/parser.h"
|
||||
#include "tools/tools.h"
|
||||
26
meshToolsV5/src/Lib/mt/operators/OpDocument.cpp
Normal file
26
meshToolsV5/src/Lib/mt/operators/OpDocument.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#include "stdafx.h"
|
||||
#include "OpDocument.h"
|
||||
#include "OpMesh.h"
|
||||
|
||||
namespace mt
|
||||
{
|
||||
OpDocument::OpDocument(unsigned int _iRegisterCount)
|
||||
{
|
||||
r = new void*[_iRegisterCount];
|
||||
memset(r, 0, sizeof(void*) * _iRegisterCount);
|
||||
}
|
||||
|
||||
|
||||
OpDocument::~OpDocument()
|
||||
{
|
||||
delete[] r;
|
||||
}
|
||||
|
||||
|
||||
OpMesh* OpDocument::GetMesh(unsigned int _index)
|
||||
{
|
||||
auto result = new mt::OpMesh();
|
||||
result->Copy(*(OpMesh*)r[_index], false);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
16
meshToolsV5/src/Lib/mt/operators/OpDocument.h
Normal file
16
meshToolsV5/src/Lib/mt/operators/OpDocument.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
namespace mt
|
||||
{
|
||||
class OpMesh;
|
||||
class OpDocument
|
||||
{
|
||||
public:
|
||||
OpDocument(unsigned int _iRegisterCount);
|
||||
~OpDocument();
|
||||
|
||||
OpMesh* GetMesh(unsigned int _index);
|
||||
|
||||
void** r;
|
||||
};
|
||||
}
|
||||
60
meshToolsV5/src/Lib/mt/operators/OpMesh.cpp
Normal file
60
meshToolsV5/src/Lib/mt/operators/OpMesh.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
namespace mt
|
||||
{
|
||||
OpMesh::OpMesh()
|
||||
: _mesh { nullptr }
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
OpMesh::OpMesh(Mesh* mesh)
|
||||
: _mesh{ mesh }
|
||||
{
|
||||
}
|
||||
|
||||
OpMesh::~OpMesh()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void OpMesh::Copy(const OpMesh& other, bool shareMesh)
|
||||
{
|
||||
if (shareMesh)
|
||||
_mesh = other._mesh ;
|
||||
else
|
||||
_mesh = mt::ToMesh(other.GetMesh()->GetFaces());
|
||||
|
||||
Selection = other.Selection;
|
||||
}
|
||||
|
||||
FaceList OpMesh::GetSelectedFaces() const
|
||||
{
|
||||
const auto& faces = GetMesh()->GetFaces();
|
||||
return Linq::Select<Face*>(Selection, [&](unsigned int index) { return faces[index]; });
|
||||
}
|
||||
|
||||
List<RawVertex> OpMesh::GetSelectedFaceVertices() const
|
||||
{
|
||||
auto selectedFaces = GetSelectedFaces();
|
||||
auto selectedVertices = Linq::SelectMany<mt::RawVertex>(selectedFaces, [](mt::Face* face)
|
||||
{
|
||||
return ::Linq::Select<mt::RawVertex>(face->GetVertices(), [](mt::Vertex* vertex)
|
||||
{
|
||||
return vertex->GetRaw();
|
||||
});
|
||||
});
|
||||
return selectedVertices;
|
||||
}
|
||||
|
||||
List<unsigned int> OpMesh::GetSelectedFaceIndices() const
|
||||
{
|
||||
GetMesh()->UpdateIndices();
|
||||
auto selectedFaces = GetSelectedFaces();
|
||||
auto selectedIndices = Linq::SelectMany<unsigned int>(selectedFaces, [](mt::Face* face)
|
||||
{
|
||||
return face->GetIndices(false);
|
||||
});
|
||||
return selectedIndices;
|
||||
}
|
||||
}
|
||||
83
meshToolsV5/src/Lib/mt/operators/OpMesh.h
Normal file
83
meshToolsV5/src/Lib/mt/operators/OpMesh.h
Normal file
@@ -0,0 +1,83 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace mt
|
||||
{
|
||||
template<class T>
|
||||
class RefCounter
|
||||
{
|
||||
struct RefValue
|
||||
{
|
||||
RefValue(T* value)
|
||||
: Count { 1 }
|
||||
, Value { value }
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Add() { Count++; }
|
||||
bool Remove()
|
||||
{
|
||||
if (--Count == 0 && Value != nullptr)
|
||||
delete Value;
|
||||
return Count == 0;
|
||||
}
|
||||
int Count;
|
||||
T* Value;
|
||||
};
|
||||
|
||||
public:
|
||||
RefCounter(T* input)
|
||||
: _value{ new RefValue {input} }
|
||||
{
|
||||
}
|
||||
|
||||
RefCounter(const RefCounter& other)
|
||||
: _value{other._value}
|
||||
{
|
||||
_value->Add();
|
||||
}
|
||||
|
||||
~RefCounter()
|
||||
{
|
||||
if (_value->Remove())
|
||||
delete _value;
|
||||
}
|
||||
|
||||
RefCounter<T>& operator=(const RefCounter<T>& other)
|
||||
{
|
||||
if (_value->Remove())
|
||||
delete _value;
|
||||
_value = other._value;
|
||||
_value->Add();
|
||||
return *this;
|
||||
}
|
||||
|
||||
T* Value() const { return _value->Value; }
|
||||
private:
|
||||
RefCounter()
|
||||
{
|
||||
int a = 0;
|
||||
}
|
||||
RefValue* _value;
|
||||
};
|
||||
|
||||
class OpMesh
|
||||
{
|
||||
public:
|
||||
OpMesh();
|
||||
OpMesh(Mesh* mesh);
|
||||
~OpMesh();
|
||||
|
||||
void Copy(const OpMesh& other, bool shareMesh);
|
||||
|
||||
FaceList GetSelectedFaces() const;
|
||||
Mesh* GetMesh() const { return _mesh.Value(); }
|
||||
List<unsigned int> Selection;
|
||||
List<RawVertex> OpMesh::GetSelectedFaceVertices() const;
|
||||
List<unsigned int> OpMesh::GetSelectedFaceIndices() const;
|
||||
|
||||
private:
|
||||
RefCounter<Mesh> _mesh;
|
||||
};
|
||||
}
|
||||
46
meshToolsV5/src/Lib/mt/operators/operators.cpp
Normal file
46
meshToolsV5/src/Lib/mt/operators/operators.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
namespace mt
|
||||
{
|
||||
namespace op
|
||||
{
|
||||
void CreateCube(OpMesh& output, bool weldVertices, vec3 position, float size)
|
||||
{
|
||||
output = { mt::CreateCube(weldVertices, position, size) };
|
||||
}
|
||||
|
||||
void Subdivide(OpMesh& output, const OpMesh& input, int amount, bool smooth)
|
||||
{
|
||||
output.Copy(input, false);
|
||||
auto faces = AutoFaceList(output.GetSelectedFaces());
|
||||
for(int i = 0; i < amount;++i)
|
||||
mt::Subdivide(faces, smooth);
|
||||
}
|
||||
|
||||
void SelectAllFaces(OpMesh& output, const OpMesh& input)
|
||||
{
|
||||
output.Copy(input, true);
|
||||
output.Selection.Clear();
|
||||
for (int i = 0; i < output.GetMesh()->GetFaces().Count(); ++i)
|
||||
output.Selection.Add(i);
|
||||
}
|
||||
|
||||
void SelectFacesByDirection(OpMesh& output, const OpMesh& input, vec3 direction, float threshold, bool mirror)
|
||||
{
|
||||
output.Copy(input, true);
|
||||
const auto& meshFaces = output.GetMesh()->GetFaces();
|
||||
auto selectedFaces = mt::GetFacesByDirection(output.GetSelectedFaces(), direction, threshold, mirror);
|
||||
output.Selection = Linq::Select<unsigned int>(selectedFaces, [&](Face* face)
|
||||
{
|
||||
return meshFaces.IndexOf(face);
|
||||
});
|
||||
}
|
||||
|
||||
void Delete(OpMesh& output, const OpMesh& input)
|
||||
{
|
||||
output.Copy(input, false);
|
||||
const auto& meshFaces = output.GetMesh()->GetFaces();
|
||||
mt::Delete(output.GetSelectedFaces());
|
||||
}
|
||||
}
|
||||
}
|
||||
29
meshToolsV5/src/Lib/mt/operators/operators.h
Normal file
29
meshToolsV5/src/Lib/mt/operators/operators.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
// API guidelines:
|
||||
//
|
||||
// - All return types must be void
|
||||
// - All methods need at least one argument
|
||||
// - The first argument must be of a non-const reference type and must be named "output"
|
||||
// - All following (optional) input arguments must be of const reference or primitive types, and must have default values
|
||||
|
||||
namespace mt
|
||||
{
|
||||
namespace op
|
||||
{
|
||||
// [toolTip] Creates a cube mesh with the given size, direction and center position, the cube may be optionally smooth or sharp.
|
||||
// [weldVertices] DisplayName="Weld vertices"
|
||||
// [position] DisplayName="Position"
|
||||
// [edgeSize] DisplayName="Edge size" Min="0" Max="Infinity" Step="0.1"
|
||||
// [smooth] DisplayName="Smooth"
|
||||
void CreateCube(OpMesh& output, bool weldVertices = true, vec3 position = vec3::zero, float edgeSize = 1);
|
||||
|
||||
// Subdivide
|
||||
void Subdivide(OpMesh& output, const OpMesh& input, int amount = 2, bool smooth = true);
|
||||
|
||||
void Delete(OpMesh& output, const OpMesh& input);
|
||||
|
||||
void SelectAllFaces(OpMesh& output, const OpMesh& input);
|
||||
void SelectFacesByDirection(OpMesh& output, const OpMesh& input, vec3 direction, float threshold = 0.0f, bool mirror = false);
|
||||
}
|
||||
}
|
||||
24
meshToolsV5/src/Lib/mt/parser/parser.cpp
Normal file
24
meshToolsV5/src/Lib/mt/parser/parser.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#include "stdafx.h"
|
||||
#include "../operators/OpDocument.h"
|
||||
#include "ops.h"
|
||||
|
||||
mt::OpDocument* mt::Parser::ParseDocument(unsigned char* _data)
|
||||
{
|
||||
auto iRegisterCount = *((unsigned short*)_data); _data += sizeof(unsigned short);
|
||||
auto doc = new OpDocument(iRegisterCount);
|
||||
|
||||
auto iGroupCount = *((unsigned short*)_data); _data += sizeof(unsigned short);
|
||||
auto groupPtr = _data + iGroupCount * sizeof(unsigned short*);
|
||||
for (auto i = 0u; i < iGroupCount; ++i)
|
||||
{
|
||||
doc->r[i] = groupPtr + *((unsigned short*)_data); _data += sizeof(unsigned short);
|
||||
}
|
||||
|
||||
auto iOpCount = *((unsigned short*)_data); _data += sizeof(unsigned short);
|
||||
for (auto i = 0u; i < iOpCount; ++i)
|
||||
{
|
||||
mt::ParseOp(doc->r, &_data);
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
11
meshToolsV5/src/Lib/mt/parser/parser.h
Normal file
11
meshToolsV5/src/Lib/mt/parser/parser.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
namespace mt
|
||||
{
|
||||
class OpDocument;
|
||||
class Parser
|
||||
{
|
||||
public:
|
||||
OpDocument* ParseDocument(unsigned char* _data);
|
||||
};
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user