Skip to content

Commit 8b53f7f

Browse files
authored
Merge pull request #11 from CptWesley/texture-filter#10
Texture filter
2 parents 4dfff27 + 5e13856 commit 8b53f7f

9 files changed

Lines changed: 168 additions & 51 deletions

File tree

src/Brush.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ private static ClippingPlane[] CreateClippingPlanes(string[] code)
4242
Vertex v2 = Vertex.CreateFromCode(m.Groups[5].ToString());
4343
Vertex v3 = Vertex.CreateFromCode(m.Groups[9].ToString());
4444

45-
planes.Add(new ClippingPlane(v1, v2, v3));
45+
planes.Add(new ClippingPlane(v1, v2, v3, m.Groups[13].ToString()));
4646
}
4747
}
4848

src/ClippingPlane.cs

Lines changed: 12 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,24 @@
1-
using System.Collections.Generic;
2-
1+

32
namespace RadiantMapToWavefrontObj
43
{
5-
public class ClippingPlane
4+
public class ClippingPlane : Plane
65
{
7-
public readonly double D;
8-
public readonly Vector Normal;
9-
10-
public double A => Normal.X;
11-
public double B => Normal.Y;
12-
public double C => Normal.Z;
6+
public string Texture { get; private set; }
137

148
// Constructor for a clipping plane.
15-
public ClippingPlane(Vertex v1, Vertex v2, Vertex v3)
9+
public ClippingPlane(Vertex v1, Vertex v2, Vertex v3, string texture) : base(v1, v2, v3)
1610
{
17-
Vector vector1 = new Vector(v2.X - v1.X, v2.Y - v1.Y, v2.Z - v1.Z).Unit();
18-
Vector vector2 = new Vector(v3.X - v1.X, v3.Y - v1.Y, v3.Z - v1.Z).Unit();
19-
20-
Normal = Vector.CrossProduct(vector1, vector2).Unit();
21-
D = -(A * v2.X + B * v2.Y + C * v2.Z);
11+
Texture = texture;
2212
}
2313

24-
// Returns the object as a string.
25-
public override string ToString()
14+
// Set the texture of a clipping plane.
15+
public void SetTexture(string texture)
2616
{
27-
return "<" + A + ", " + B + ", " + C + ", " + D + ">";
17+
Texture = texture;
2818
}
2919

3020
// Checks if three clipping planes intersect and if so, returns an intersection point.
31-
public static bool FindIntersection(ClippingPlane a, ClippingPlane b, ClippingPlane c, out Vertex intersection)
21+
public static bool FindIntersection(Plane a, Plane b, Plane c, out Vertex intersection)
3222
{
3323
// Calculates the possible intersection point using the Cramer's rule.
3424
double det = Determinant(a.A, a.B, a.C, b.A, b.B, b.C, c.A, c.B, c.C);
@@ -38,28 +28,16 @@ public static bool FindIntersection(ClippingPlane a, ClippingPlane b, ClippingPl
3828
return false;
3929
}
4030

41-
double x = Determinant(a.D, a.B, a.C, b.D, b.B, b.C, c.D, c.B, c.C)/det;
42-
double y = Determinant(a.A, a.D, a.C, b.A, b.D, b.C, c.A, c.D, c.C)/det;
43-
double z = Determinant(a.A, a.B, a.D, b.A, b.B, b.D, c.A, c.B, c.D)/det;
31+
double x = Determinant(a.D, a.B, a.C, b.D, b.B, b.C, c.D, c.B, c.C) / det;
32+
double y = Determinant(a.A, a.D, a.C, b.A, b.D, b.C, c.A, c.D, c.C) / det;
33+
double z = Determinant(a.A, a.B, a.D, b.A, b.B, b.D, c.A, c.B, c.D) / det;
4434

4535
intersection = new Vertex(x, y, z);
4636
intersection.SetNormal((a.Normal + b.Normal + c.Normal).Unit());
4737

4838
return true;
4939
}
5040

51-
// Creates an array of all vertices that lie on this plane.
52-
public Vertex[] FindVerticesInPlane(Vertex[] vertices)
53-
{
54-
List<Vertex> res = new List<Vertex>();
55-
foreach (Vertex v in vertices)
56-
{
57-
if (v.OnPlane(this))
58-
res.Add(v);
59-
}
60-
return res.ToArray();
61-
}
62-
6341
// Calculates the determinant of a 2x2 matrix. (Can be done less verbose...)
6442
private static double Determinant(double a11, double a12, double a21, double a22)
6543
{

src/Face.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ namespace RadiantMapToWavefrontObj
55
public class Face
66
{
77
private Vertex[] _vertices;
8+
public string Texture { get; private set; }
89

910
// Empty contructor that creates an empty face.
1011
public Face()
@@ -27,6 +28,12 @@ public Face(Vertex a, Vertex b, Vertex c)
2728
_vertices[2] = c;
2829
}
2930

31+
// Set the texture of a clipping plane.
32+
public void SetTexture(string texture)
33+
{
34+
Texture = texture;
35+
}
36+
3037
// Returns the vertices of the face.
3138
public Vertex[] GetVertices()
3239
{
@@ -104,6 +111,12 @@ public Edge[] GetEdges()
104111
return edges;
105112
}
106113

114+
// Checks if a face contains a certain vertex.
115+
public bool Contains(Vertex vertex)
116+
{
117+
return _vertices.Contains(vertex);
118+
}
119+
107120
// Returns a stringified version of the object.
108121
public override string ToString()
109122
{

src/ObjObject.cs

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ namespace RadiantMapToWavefrontObj
55
{
66
public class ObjObject
77
{
8-
public readonly Vertex[] Vertices;
9-
public readonly Face[] Faces;
8+
public Vertex[] Vertices { get; private set; }
9+
public Face[] Faces { get; private set; }
1010
private string _name;
1111

1212
// Constructor for an .obj object.
@@ -15,6 +15,7 @@ public ObjObject(string name, Vertex[] vertices, Face[] faces)
1515
_name = name;
1616
Vertices = vertices;
1717
Faces = faces;
18+
Cleanup();
1819
}
1920

2021
// Returns the name of the object.
@@ -72,6 +73,52 @@ public string ToCode(double scale, int faceOffset)
7273
return res;
7374
}
7475

76+
// Removes all faces containing a texture listed in the filter.
77+
public void FilterTextures(string[] filter)
78+
{
79+
if (Faces == null)
80+
return;
81+
82+
List<Face> newFaces = new List<Face>();
83+
84+
foreach (Face face in Faces)
85+
{
86+
if (!filter.Contains(face.Texture))
87+
newFaces.Add(face);
88+
}
89+
90+
Faces = newFaces.ToArray();
91+
Cleanup();
92+
}
93+
94+
// Remove all vertices that have no faces.
95+
private void Cleanup()
96+
{
97+
if (Faces == null)
98+
return;
99+
100+
List<Vertex> newVertices = new List<Vertex>();
101+
102+
foreach (Vertex vertex in Vertices)
103+
{
104+
bool contained = false;
105+
106+
foreach (Face face in Faces)
107+
{
108+
if (face.Contains(vertex))
109+
{
110+
contained = true;
111+
break;
112+
}
113+
}
114+
115+
if (contained)
116+
newVertices.Add(vertex);
117+
}
118+
119+
Vertices = newVertices.ToArray();
120+
}
121+
75122
// Converts a radiant brush to an obj object.
76123
public static ObjObject CreateFromBrush(string name, Brush brush)
77124
{
@@ -153,6 +200,7 @@ private static Face[] CreateFaces(Vertex[] vertices, ClippingPlane[] planes)
153200
foreach (Face face in BowyerWatson(verts))
154201
{
155202
FixNormal(face, planes[i].Normal);
203+
face.SetTexture(planes[i].Texture);
156204
faces.Add(face);
157205
}
158206
}
@@ -251,7 +299,7 @@ private static Face FindSuperTriangle(Vertex[] vertices)
251299
maxZ = v.Z;
252300
}
253301

254-
ClippingPlane plane = new ClippingPlane(vertices[0], vertices[1], vertices[2]);
302+
Plane plane = new Plane(vertices[0], vertices[1], vertices[2]);
255303

256304
Vertex a = new Vertex(minX, minY, minZ);
257305
Vertex b = new Vertex(maxX, maxY, maxZ);

src/Plane.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using System.Collections.Generic;
2+
3+
namespace RadiantMapToWavefrontObj
4+
{
5+
public class Plane
6+
{
7+
public readonly double D;
8+
public readonly Vector Normal;
9+
10+
public double A => Normal.X;
11+
public double B => Normal.Y;
12+
public double C => Normal.Z;
13+
14+
// Constructor for a plane.
15+
public Plane(Vertex v1, Vertex v2, Vertex v3)
16+
{
17+
Vector vector1 = new Vector(v2.X - v1.X, v2.Y - v1.Y, v2.Z - v1.Z).Unit();
18+
Vector vector2 = new Vector(v3.X - v1.X, v3.Y - v1.Y, v3.Z - v1.Z).Unit();
19+
20+
Normal = Vector.CrossProduct(vector1, vector2).Unit();
21+
D = -(A * v2.X + B * v2.Y + C * v2.Z);
22+
}
23+
24+
// Returns the object as a string.
25+
public override string ToString()
26+
{
27+
return "<" + A + ", " + B + ", " + C + ", " + D + ">";
28+
}
29+
30+
// Creates an array of all vertices that lie on this plane.
31+
public Vertex[] FindVerticesInPlane(Vertex[] vertices)
32+
{
33+
List<Vertex> res = new List<Vertex>();
34+
foreach (Vertex v in vertices)
35+
{
36+
if (v.OnPlane(this))
37+
res.Add(v);
38+
}
39+
return res.ToArray();
40+
}
41+
}
42+
}

src/Program.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ internal class Program
99
{
1010
private static double _scale = 0.01;
1111
private static bool _autoclose = false;
12+
private static string[] _textureFilter = new string[0];
1213

1314
static void Main(string[] args)
1415
{
@@ -49,6 +50,9 @@ private static void ConvertFile(string path)
4950
RadiantMap map = RadiantMap.Parse(path);
5051
WavefrontObj obj = WavefrontObj.CreateFromRadiantMap(map);
5152

53+
if (_textureFilter.Length > 0)
54+
obj.FilterTextures(_textureFilter);
55+
5256
obj.SaveFile(Path.Combine(Path.GetDirectoryName(path), Path.GetFileNameWithoutExtension(path)) + ".obj", _scale);
5357

5458
DateTime endTime = DateTime.Now;
@@ -58,7 +62,7 @@ private static void ConvertFile(string path)
5862
// Handle a settings argument.
5963
private static void HandleArgument(string arg)
6064
{
61-
string pattern = @"-(\w+)=(\w+)";
65+
string pattern = @"-(\w+)=(\S+)";
6266
Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);
6367
Match m = regex.Match(arg);
6468
if (m.Success)
@@ -79,6 +83,11 @@ private static void HandleArgument(string arg)
7983
if (Double.TryParse(mode, out scale))
8084
_scale = scale;
8185
}
86+
else if (type == "filter")
87+
{
88+
if (File.Exists(mode))
89+
_textureFilter = File.ReadAllLines(mode);
90+
}
8291
}
8392
}
8493
}

src/RadiantMapToWavefrontObj.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
<Compile Include="ArrayExtension.cs" />
109109
<Compile Include="Brush.cs" />
110110
<Compile Include="ClippingPlane.cs" />
111+
<Compile Include="Plane.cs" />
111112
<Compile Include="Edge.cs" />
112113
<Compile Include="Face.cs" />
113114
<Compile Include="LineSegment.cs" />

src/Vertex.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public static Vertex CreateFromCode(string code)
4343
}
4444

4545
// Check if this vertex lies on a certain clipping plane.
46-
public bool OnPlane(ClippingPlane plane)
46+
public bool OnPlane(Plane plane)
4747
{
4848
double left = X * plane.A + Y * plane.B + Z * plane.C;
4949
double right = plane.D;

src/WavefrontObj.cs

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,23 @@ namespace RadiantMapToWavefrontObj
55
{
66
public class WavefrontObj
77
{
8-
public readonly ObjObject[] Objects;
8+
public ObjObject[] Objects { get; private set; }
99

1010
// Constructor for an entire wavefront .obj file object.
1111
public WavefrontObj(ObjObject[] objects)
1212
{
1313
Objects = objects;
14+
Cleanup();
1415
}
1516

16-
// Converts a RadiantMap object to a WavefrontObj object.
17-
public static WavefrontObj CreateFromRadiantMap(RadiantMap map)
17+
// Removes all faces containing a texture listed in the filter from all subobjects.
18+
public void FilterTextures(string[] filter)
1819
{
19-
List<ObjObject> objects = new List<ObjObject>();
20-
21-
for (int i = 0; i < map.Brushes.Length; ++i)
20+
foreach (ObjObject obj in Objects)
2221
{
23-
Brush brush = map.Brushes[i];
24-
ObjObject obj = ObjObject.CreateFromBrush("Brush_" + i, brush);
25-
objects.Add(obj);
22+
obj.FilterTextures(filter);
2623
}
27-
28-
return new WavefrontObj(objects.ToArray());
24+
Cleanup();
2925
}
3026

3127
// Returns .obj formatted text of this object.
@@ -50,5 +46,35 @@ public void SaveFile(string path, double scale)
5046
{
5147
File.WriteAllText(path, ToCode(scale));
5248
}
49+
50+
// Removes objects that lack faces or vertices.
51+
private void Cleanup()
52+
{
53+
List<ObjObject> newObjects = new List<ObjObject>();
54+
55+
foreach (ObjObject obj in Objects)
56+
{
57+
if (obj.Faces != null && obj.Faces.Length > 0 && obj.Vertices.Length > 0)
58+
newObjects.Add(obj);
59+
}
60+
61+
Objects = newObjects.ToArray();
62+
63+
}
64+
65+
// Converts a RadiantMap object to a WavefrontObj object.
66+
public static WavefrontObj CreateFromRadiantMap(RadiantMap map)
67+
{
68+
List<ObjObject> objects = new List<ObjObject>();
69+
70+
for (int i = 0; i < map.Brushes.Length; ++i)
71+
{
72+
Brush brush = map.Brushes[i];
73+
ObjObject obj = ObjObject.CreateFromBrush("Brush_" + i, brush);
74+
objects.Add(obj);
75+
}
76+
77+
return new WavefrontObj(objects.ToArray());
78+
}
5379
}
5480
}

0 commit comments

Comments
 (0)