Tuesday, September 24, 2013

ClickOnce Woes with VSTO's

So, I'm trying to redeploy a VSTO application and I get the following beautiful, beautiful, beautiful error...

Unable to install this application because an application with the same identity is already installed. To install this application, either modify the manifest version for this application or uninstall the preexisting application.

It's frustrating, because I know it has been uninstalled and everything is fine.  Registry doesn't even show it deployed.  Commence "tearing out my hair" mode.

And then, I found the problem.  Apparently, VSTO's can sometimes screw up the ClickOnce cache.  Awesome!  So, that being said, if you run this from the command line (and it's very fast, so don't freak out and think nothing popped up/succeeded) all will be better:

rundll32 dfshim CleanOnlineAppCache

And thus, order and balance was restored to the universe again... for a short time.

Wednesday, September 11, 2013

MSB3326 "Cannot import the following key file: ."

Due to restrictions, I'm limited in some of the things I'm allowed to post, so these updates will be less frequent than before... which isn't saying too much.

In any case, I bumped into a new problem: MSB3326 "Cannot import the following key file: ."

Where is the key file?  Why is it blank?  I know I'd deployed the key and everything was fine prior, so what was the big deal?

What this means is that it cannot access the key file -- maybe you're like me and have to use an alternative administrative account for building and keys and the like.  So, I had to manually open certmgr.msc as the same administrator that was building the project.

After that -- all was pie in the sky.  Things work, life is good, and finally there is an answer to this horrific question.

Tuesday, February 5, 2013

Windows 8 and Windows Server 2012 Hiccups


So, I recently was trying to put together a copy of SharePoint 2013 on Windows Server 2012, on a box that came with Windows 8.  My initial hope was to build a VHD and just have it capable of being transported around easily, but this caused issues.

The more I played with it, the harder it was to get Windows Server 2012 to install at all!  All sorts of trips through bcdedit and bcdboot were fruitless.  So were my attempts at using an easier editor on top.

Even throwing a simple partition on is difficult to install to.  The end result was that I had to go back to the tried and true method -- dump the install to a bootable flash drive.  After doing this, everything went peachy.

For anyone else having issues, this is the only way I was capable of dual-booting Windows 8 and Windows Server 2012, after playing with it in the evenings for a couple of weeks.  

Wednesday, January 16, 2013

SetResourceReference is the Awesome-Sauce for Styling

One of the biggest issues I've had with developing custom views is that there are so many different ways to implement your styling and linkage.  The best way I've found is just to call the following in the constructor:


SetResourceReference(StyleProperty, typeof(MyControl));

Wherein MyControl is the control you're working with.

A lot of people work with the default style key -- but I've found that in larger projects, there can sometimes be issues with this.  Using SetResourceReference has worked for me every single time.

Food for thought!

Monday, January 7, 2013

The type or namespace cannot be found... C# and the Client Profile woes

So, this is a very funny and unusual error I bumped into today -- and it drove me mad for a few hours.

When I build components, I generally like to abstract them out into a little test-bed WPF application.  Every time I kept compiling, it would blow up on a simple, new component I had just added, with a message looking like...

"The type or namespace '{0}' cannot be found."

When I did try to resolve it -- it pointed out a flaw in our architecture, wherein some numb-skull decided to rename a namespace in one assembly to that of another.  After I fixed that, I found that it was STILL not the problem.

Then I looked again -- for whatever I could find -- in my test-bed's properties.

It was set to run in .NET 4.0 Client Profile.  When I changed it back to .NET 4.0, everything compiled and worked fine.

In the future, I need to double check these things -- hopefully someone else will read this post and later figure this out as well!

Tuesday, October 2, 2012

Saving JPEG Metadata the FIRST Time with WPF

So, I've been seeing a bunch of problems at StackOverflow and bumped into this new problem at work...  Turns out that setting the EXIF metadata on an image is EXTREMELY difficult.  Most solutions involve first saving the image and then opening it back up...

Of course, I couldn't just "accept" that.  Unfortunately, the work-around is a bit of a hack, but it does work reliably!

So, in the following example, assume that I have a RenderTargetBitmap from WPF...

                    JpegBitmapEncoder imageEncoder = new JpegBitmapEncoder { QualityLevel = 100 };
                    imageEncoder.Frames.Add(BitmapFrame.Create(renderTarget));

                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        imageEncoder.Save(memoryStream);
                        memoryStream.Position = 0;

                        JpegBitmapDecoder decoder = new JpegBitmapDecoder(memoryStream, BitmapCreateOptions.None, BitmapCacheOption.Default);
                        BitmapFrame frame = decoder.Frames[0];
                        BitmapMetadata metadata = (BitmapMetadata) frame.Metadata.Clone();

                        metadata.Subject = "This is a test subject.";
                        metadata.Title = "This is a test title.";
                        metadata.Comment = "This is a test comment.";

                        imageEncoder = new JpegBitmapEncoder() { QualityLevel = 100 };
                        imageEncoder.Frames.Add(BitmapFrame.Create((BitmapSource)frame, (BitmapSource)frame.Thumbnail, metadata, frame.ColorContexts));

                        using (var fileStream = new FileStream(saveFileDialog.FileName, FileMode.Create))
                        {
                            imageEncoder.Save(fileStream);
                        }
                    }

This is, of course, a hack -- it saves the image to the memory stream and then is capable of creating a "good" metadata object (normally, this blows up in your face if you try to send one in that you created on the fly).

Now, you can set it up however you like -- go nuts!

Tuesday, August 7, 2012

3D Programming and Calculating Normals

So, I've had a really difficult time with calculating normal vectors (herein referred to as "normals") in OpenGL, and I've learned a lot to make sense of it, finally.  There are a few good tutorials, but they still don't explain everything you want to know.  So, I've decided to post about how they work and how to build them.

A normal is a vector that describes a direction perpendicular (pointing away) to a point (i.e. a vertex) or a face (i.e. a polygon).  It is important for lighting, since light needs to know how to reflect off of something.  I always figured lighting should be able to figure this out -- I mean, why shouldn't it?  However, that's another topic entirely.

Vertex and face normals serve their purposes.  For example, streamlined terrain generally looks better with vertex normals.  Since OpenGL blends the colors (and therefore lighting) between each point, you'll see a gradient between all vertices of your polygon with normals.  A face normal will basically have one normal for a vertex be applied to all vertices in the polygon, so the polygon as a whole will be flat with its lighting and uniformly lit/shaded.  This looks great for something like a cube where you'll want clear lines separating the object faces.  This looks really terrible on terrain.

For the sake of this tutorial, I'm going to explain how to calculate a face normal.  Since all polygons are composed of triangles, I will be using a triangle for our face.  You can calculate a face normal by averaging all of the normals in a complex polygon together (using a geometric average is the ideal way, but sometimes slow).


So, suppose we have a triangle with vertices A, B, and C.

We need to calculate the individual vectors and multiply them together.  Please note that you need to observe the right-hand rule when calculating the normals, such that you need to always build normals or vertices in the same order.  For example, in my example above, ABC is built counter-clockwise, from A to B to C.  Some people build their triangles in a format where the vertices A, B, C are the upper left corner, upper right corner, and then the lower left corner (whereas mine are upper left corner, lower left corner, and lower right corner, respectfully).  In the alternate case, it would built clockwise.  However, there are a number of ways to build a triangle -- just make sure you either build them all clockwise or counter-clockwise.  Make sure that each triangle is calculated in the same order as the prior.

From here, we need to calculate the vector of each component.  We use the middle vertex of a triangle (again, this can change based on how you build your triangles).  For my version, it is "B."  So, we want to calculate the vector of each direction around this "pivot" vertex.

Simply put, we will have two vectors, U and V, which will be built as follows:

U = B - A
V = C - B

To do vector addition and subtraction, we just add/subtract the components, so simply put...

method AddVectors( Vertex A, Vertex B )
{
  create Vector where Vector.X = A.X + B.X, Vector.Y = A.Y + B.Y, Vector.Z = A.Z + B.Z;
}

Now that we have U and V, we'll have to multiply the two vectors together... which is a bit more painful.

method MultiplyVectors( Vector U, Vector V )
{
  create MultipliedVector;
  MultipliedVector.X = ( ( U.Y x V.Z ) - ( U.Z x V.Y ) );
  MultipliedVector.Y = ( ( U.Z x V.X ) - ( U.X x V.Z ) );
  MultipliedVector.Z = ( ( U.X x V.Y ) - ( U.Y x V.X ) );
}

Aren't you glad we used vector names U and V, instead of X and Y?  That code would be impossible to read!

Now, you have a "normal" of the face of the triangle -- but you're STILL not done.  The normal should be normalized to a unit length.  If you want to calculate a vertex normal, you may save this operation until after you're finished calculating all of your face normals.

To normalize a vertex, you need to find the unit length, which is done with Pythagorean's theorem.

The unit length is built as follows with a vector T:

UnitLength = SquareRoot( ( T.X x T.X ) + ( T.Y x T.Y ) + ( T.Z x T.Z ) );

Then, divide each component of the normal by the unit length as follows:

T.X = T.X / UnitLength;
T.Y = T.Y / UnitLength;
T.Z = T.Z / UnitLength;

You have now "normalized" your normal.

But wait, there's more!  We really wanted to get the vertex normals!

We can calculate a vertex normal by adding all of the face normals that a vertex is used in and then performing the normalization we did prior after.

Suppose we use a data structure (I have a persistent Dictionary<int, Dictionary<int, Vertex>> object I use) that contains all of the vertices of a mesh by their X, Y values.  X, Y would refer to the X and Y coordinates of the triangle mesh, which in my case (and many others) are generally uniform distance from each other (i.e. always 1 unit away from the other).

Assume my earlier triangle now has another point directly above C, called D.  We now have a quadrangle.


Assume my format has several of these next to each other to make a surface of terrain or something else.  Assume that these share points, such that D and C become the next A and B vertices for a quad that would have an E and F added on.  (i.e. quad one is built with A, B, C, D; quad two is built with D, C, E, F)

Assume also, I can calculate a face normal by providing three vertices of a triangle with the method CalculateNormal.  This would utilize the same pseudo-code mentioned above.

I could loop through a mesh as follows:

normals = create Dictionary[int][int] containing Vector;

for( y = 0; y < mesh.Height - 1; y++ )
{
  for( x = 0; x < mesh.Width - 1; x++ )
  {
    //Triangle ABC
    Vector normal = CalculateNormal( mesh[x][y], mesh[x][y + 1], mesh[x + 1][y + 1] );
    
    //Add the normal components to the vertices that are used
    normals[x][y] += normal;
    normals[x][y + 1] += normal;
    normals[x + 1][y + 1] += normal;

    //Triangle ACD
    normal = CalculateNormal( mesh[x][y], mesh[x + 1][y + 1], mesh[X + 1][y] );

    //Add the normal components to the vertices that are used
    normals[x][y] += normal;
    normals[x + 1][y + 1] += normal;
    normals[x + 1][y] += normal;
  }
}
At this point I would have all of my normals added up, but they'd be huge and non-normalized.  So, we'd normalize them by calculating the unit length as I did for a face normal, and then finally dividing the components by that unit length.

That, my friends, is how you would go about building normals from a uniform mesh with differing heights.

References: