3D Rendering in C# WPF and Anti-Aliasing - c#

Hello sorry for my bad English!
I created lines in a Viewport3D. Those lines are represented by parallelipipeds.
Problem: When I create multiple lines with the same caracteristics (width/height/depht), some are wider than the others.
Solution: I use Anti-Aliasing by setting the attached property of the
viewport3D => RenderOptions.SetEdgeMode(myViewport, EdgeMode.Unspecified);
The lines are now exactly the same. To find out the above solution, first I :
Checked if the lines had really the same caracteristics (in case I made mistakes in my programmation).
Result: The lines had exactly the same caracteristics (except they have differents coordinates).
Checked if it was because I represent one line with one parallelipiped. I supposed that if the parallelipiped was slightly rotated, then the width of the line projected could change.
So: I change parallelipiped for cylinder => the projection of a cylinder, regardless to the rotation of this one, always have the same width. But even with cylinders, some lines were wider than the others.
I realised that it wasn't my programmation the problem, but the rendering. And I found that I could change the rendering with the attached property EdgeMode.
When I set the EdgeMode to Unspecified (= Anti-Aliasing enabled) then all lines were perfectly rendered, they all have the same width. But if I set back EdgeMode to Aliased (= Anti-Aliasing disabled) then the problem was there.
My question is: Why do I have this problem? Can I do something else instead of changing the EdgeMode?
Thank you for any help.

Related

Polygon difference - strange results from Clipperlib

I am trying to create iso-area polygons ("donuts") from a set of contours. This is the process:
Generate the contours.
Sort the contours into a tree structure, such that all contours held within a specific contour are children of that contour.
For each contour, execute a difference operation with all of its children, using Clipperlib.
The resulting polygon(s) and holes constitute the iso-area "donut". These iso-areas can then be rendered as a contour map, or used for other purposes. Note that if all I wanted to do was render the contours, I could stop after the initial sort and render the contours in order, such that inner-most render on top. I do require the actual areas.
First up - Clipperlib is a fantastic library, and one that I would be very happy to pay good money for - thanks Angus!
My issue is that I seem to get some strange results from the difference operation in certain situations - I suspect this may be user error on my part, so I will illustrate the problem:
This image shows two polygons - the subject is outlined in red, and the children are filled in blue. I wish to subtract the children from the subject. Note the small area near the mouse-pointer. What I would expect from this diff is two outer polygons - the small one near the mouse pointer and the large one. I would further expect all of the "islands" to be holes within the second, large, polygon.
What I actually get is two outers (as expected), with children (holes) associated with each:
In the second image, the tiny polygon near the mouse pointer is the "outer", and all of the other filled polygons are "holes" belonging to it. Note that I show the outlines of both solutions in both images - just focus on the filled polygons.
I am executing clipperlib using the red polygon in the first image as the subject, and all of the children as clips. Clip type is ctDifference (I have also tried Xor with the same results - which they should be, given that all children are within the subject).
I am requesting a PolyTree back, which has two Childs. I am using the c# library, and have also tried v6.
On one level, the results that I need are all there - all of the "holes" are designated such, the problem is that many of these holes are returned as children of the tiny outer area at the top-right of the image. Am I reading the PolyTree incorrectly, using ClipperLib incorrectly, or is this result simply wrong?
On a further note - I noticed that the new ClipperLib (v6) now accepts Z values. I'm wondering now if there may be a better method than I am using for generating these iso-areas from a given collection of un-ordered contour lines?
thanks,
Matt
EDIT: I have uploaded the raw data for the polygons in a text file.
here is the link
The file has the subject polygon as the first set of vertices, followed by each of the children. Each polygon is represented as X/Y pairs on a single row, with a newline between each polygon.
In the second image, the tiny polygon near the mouse pointer is the "outer", and all of the other filled polygons are "holes" belonging to it. Note that I show the outlines of both solutions in both images - just focus on the filled polygons.
This sounds like there's a bug somewhere but it's hard to tell without the raw data.
Also, this isn't the best place for Clipper support, there is a discussion forum and a place to report suspected bugs at SourceForge. Anyhow, it's probably best now to post your raw data here (as little as possible please while still reproducing the problem).
Edit:
OK, I've had a look at the data and I don't understand why you believe ... "all of the other filled polygons are "holes" belonging to it".
PolyTree solutiontree = new PolyTree();
cpr.Execute(ClipType.ctDifference, solutiontree,
PolyFillType.pftNonZero, PolyFillType.pftNonZero);
solution = new Polygons(solutiontree.ChildCount);
foreach (PolyNode pn in solutiontree.Childs)
solution.Add(pn.Contour);
Just filtering the top level PolyNodes of the solution PolyTree (and top level nodes must be 'outers') using the code snippet above, this is what I get (the solution is shaded green) ...
There's no way from this result that "the tiny polygon near the mouse pointer" can own the other polygons. Having said that, there are evidently still holes in the solution so there's a bug somewhere that needs fixing.
Edit 2: I've found and fixed the bug and uploaded Clipper version 6.0.2 to the SourceForge repository. I'll need to do a bit more error checking before I formally update the main Zip package.
Edit 3:
Evidently still not right after all.
Edit 4:
I think I've finally nailed this bug (see revision 420 in SourceForge repository).
Follow up there.

How to hide "cracks" between GeometryModel3Ds in one ModelVisual3D?

I am writing a geoscience visualization application that uses wpf 3d. The user needs to be able to zoom deep into detail and out quick with minimum resources taken. I've decided to divide my slice (ModelVisual3D) into subrectangles (GeometryModel3D), so that each has it's own texture that changes when the camera zooms in (similar to Google maps).
The problem is that "cracks" are appearing between subrectangles, even though they actually have no empty space between them.
How to hide these? or is there any other way to assign multiple materials with different sizes to one ModelVisual3D?
PS I've tried making the background gray, light-gray, silver and white-smoke. It helps a little, but it's not acceptable. I've also tried overlapping the subrectangles, with no result.
Instead of your current setup you might want to make several textures at different resolutions and switch between these depending on the zoom level. (Mipmaps)
When getting really close you might replace the entire object and switch it for a much smaller one) and use a highly detailed texture.
It will require a bit more pre-processing but you will be able to use a single geometry.
Seems like changing ImageBrush's stretch to Stretch.None and using textures larger than the subsquare helps. Although now I need more precise control over texture coordinates for the surface.

Ugly Line and Border Rendering

I just started diving into WPF. First thing I noticed and which I really hate is the ugly rendering.
I don't know why but for example borders or lines turning ugly sometimes.
Take a look at the Screenshot. The bottom line is ugly. Not that crisp like the centered line.
Any suggestions to make that better?
See the second answer of this SO question
which suggests using UseLayoutRounding=False in preference to SnapsToDevicePixels.
As an aside if you're using bitmaps then RenderOptions.BitmapScalingMode can be useful (from this SO question
It looks like your lines don't fall on pixel boundaries. Two ways I've used to get around this are:
Use SnapsToDevicePixels. This can cause some noticeably odd spacing if you have lines sufficiently close together.
or
Increase the width of your line so that it full hits a line of pixels. (this has the drawback that the needed width is, again, device dependent).

How do I position lines exactly in C#

I do NOT want the system trying to scale my drawing, I want to do it entirely on my own as any attempt to squeeze/stretch the graphics will produce ugly results. The problem is that as the image gets bigger I want to add more detail rather than have it simply scale up.
Right now I'm looking at two sets of stripes. One is black/white, the other is black/white/white. The pen width is set to 1.
When the line is drawn horizontally it's correct. The same logic drawing vertical lines appears to be doing some antialiasing, bleeding the black onto the nearby white. The black/white/white doesn't look as good as the horizontal, the black/white looks more like medium++ gray/medium-- gray.
The same code is generating the coordinates in all cases, the transform logic is simply selecting what offset to apply where as I am only supporting orientations on the cardinals. Since there's no floating point involved I can't be looking at precision issues.
How do I get the system to leave my graphics alone???
(Yeah, I realize this won't work at very high resolution and eventually I'll have to scale up the lines. Over any reasonable on-screen zoom factor this won't matter, for printer use I'll have to play with it and see where I need to scale. The basic problem is that I'm trying to shoehorn things into too few pixels without just making blobs.)
Edit: There is no scaling going on. I'm generating a bitmap the exact size of the target window. All lines are drawn at integer coordinates. The recommendation of setting SmoothingMode to None changes the situation: Now the black/white/white draws as a very clear gray/gray/white and the black/white draws as a solid gray box. Now that this is cleaned up I can see some individual vertical lines that were supposed to be black are actually doing the same thing of drawing as 2-pixel gray bars. It's like all my vertical lines are off by 1/2 pixel--yet every drawing command gets only integers.
Edit again: I've learned more about the problem. The image is being drawn correctly but trashed when displayed to the screen. (Saving it to disk and viewing it on the very same monitor shows it drawn correctly.)
You really should let the system manage it for you. You have described a certain behavior that is specific to the hardware you are using. Given different hardware, the problem may not exist at all, or it may exist horizontally but not vertically, or may only exist at much smaller or much larger resolutions, etc. etc.
The basic problem you described sounds like the vertical lines are being drawn "between" vertical stacks of pixels, which is causing the system to draw an anti-aliased line. The alternative to anti-aliasing the line is to shift it. The problem with that is the lines will "jitter" or "jerk" if the image is moved around, animated, or scaled or transformed in any other way. Generally, jerk is MUCH less desirable than anti-aliasing because it is more distracting.
You should be able to turn off anti-aliasing using the SmoothingMode enum, or you could try to handle positioning yourself. Either way, you are trading anti-aliasing for jittery, jerky rendering during any movement or transformation.
Have a look at System.Drawing.Drawing2d.SmoothingMode. Setting it to 'Default' or 'None' should turn off anti aliasing when doing line drawing. If you're talking about scaling an image without anti aliasing effects, have a look at InterpolationMode. Specifically, you might wish to set it to 'Nearest-Neighbor' which will keep your rectangular blocks perfectly crisp. Note that you will see some odd effects if you scale your image by anything other than whole numbers.
Perhaps you need to align your lines on half-pixel coordinates? A one pixel line drawn at say x = 5 would be drawn on the center of the line, which means it would go from x = 4.5 to x = 5.5. If you want it to go from x = 4 to x = 5 then you'd need to set its coordinate to x = 4.5.
GDI+ has a property: http://msdn.microsoft.com/en-us/library/system.drawing.graphics.pixeloffsetmode.aspx that allows you to control this behavior.
Sounds like you need to change your application to tell the system it is DPI aware so scaling doesn't occur. Here's an article on doing that: http://msdn.microsoft.com/en-us/library/ms701681%28VS.85%29.aspx

Z-fighting between lines in XNA

I'm having a problem where drawing a grid using LineList and another (larger) grid overlapping it will make them flicker due to z-fighting. Using DepthBias will reduce that kind of problem when polygons and lines overlap but it apparently doesn't work when drawing lines in two separate DrawIndexedPrimitives calls.
Currently I "fixed" it by adding to the position of the second grid a small vector pointing towards the camera to simulate the DepthBias but the problem still happens when the camera is far from the grids.
Is there a better way to work around this problem?
From what I've heard you should take a look at your clip-planes. Example thread: xna.com
Edit: Dunno, about grids though, but you could always try! :)
Unfortunately, this is the natural behavior due to the limited precision of 32bit floating point numbers (as used by the depth buffer). You can either translate one set of lines minimally (as You do now) and try to chose Your clipping planes as close to each other as possible (as Rob mentioned), or:
Disable the depth buffer by setting device.RenderState.CompareFunction = CompareFunction.Allways, not by actually disabling the buffer!
Draw all Your lines.
Enable the depth buffer again by reversing the changes in step 1.
Draw all Your other geometry.

Categories

Resources