Why do obj. files contain normals [closed] - object

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Simple question, why do object files contain normals, you can just calculate the normals right?
If I'm correct I'd just have to take the crossproduct between the vector point1-point2 and point1-point3, so which would save me the time of reading them from a file.
EDIT:
Trying to be more specific, this is a file I've found and which I want to use:
g cube
v 0.0 0.0 0.0
v 0.0 0.0 1.0
v 0.0 1.0 0.0
v 0.0 1.0 1.0
v 1.0 0.0 0.0
v 1.0 0.0 1.0
v 1.0 1.0 0.0
v 1.0 1.0 1.0
vn 0.0 0.0 1.0
vn 0.0 0.0 -1.0
vn 0.0 1.0 0.0
vn 0.0 -1.0 0.0
vn 1.0 0.0 0.0
vn -1.0 0.0 0.0
f 1//2 7//2 5//2
f 1//2 3//2 7//2
f 1//6 4//6 3//6
f 1//6 2//6 4//6
f 3//3 8//3 7//3
f 3//3 4//3 8//3
f 5//5 7//5 8//5
f 5//5 8//5 6//5
f 1//4 5//4 6//4
f 1//4 6//4 2//4
f 2//1 6//1 8//1
f 2//1 8//1 4//1
EDIT 2:
Because people complained:
http://en.wikipedia.org/wiki/Wavefront_.obj_file

you can calculate normals, but it takes time to compute them. When you have a lot of meshes and have to render at 60 fps (or more), its more performant to load precomputed normals into the GPU. also crossproduct between the vector point1-point2 and point1-point3, just gives the face normal. to get the per vertex normals that are required for Goraud shading, you have to average the face normals at every vertex. so you can see the computation gets deeper.

Related

How to count value greater than or equal to 0.5 continuous for 5 or greater than 5 rows python

I am trying to count values in column x greater than or equal to 0.5 for continuous for 5 times or greater. i also need to use groupby function for my data .
i used this function work fine , but this function can not count continuous occurrence of value , its just count all values greater than or equal 0.5
data['points_greater_0.5'] = data[abs(data['x'])>=0.5].groupby(['y','z','n'])['x'].count()
but i want to count if greater than or equal to 0.5 value occurs continuous for 5 times or more
As the source DataFrame I took:
x y z n
0 0.1 1.0 1.0 1.0
1 0.5 1.0 1.0 1.0
2 0.6 1.0 1.0 1.0
3 0.7 1.0 1.0 1.0
4 0.6 1.0 1.0 1.0
5 0.5 1.0 1.0 1.0
6 0.1 1.0 1.0 1.0
7 0.5 1.0 1.0 1.0
8 0.6 1.0 1.0 1.0
9 0.7 1.0 1.0 1.0
10 0.1 1.0 1.0 1.0
11 0.5 1.0 1.0 1.0
12 0.6 1.0 1.0 1.0
13 0.7 1.0 1.0 1.0
14 0.7 1.0 1.0 1.0
15 0.6 1.0 1.0 1.0
16 0.5 1.0 1.0 1.0
17 0.1 1.0 1.0 1.0
18 0.5 2.0 1.0 1.0
19 0.6 2.0 1.0 1.0
20 0.7 2.0 1.0 1.0
21 0.6 2.0 1.0 1.0
22 0.5 2.0 1.0 1.0
(one group for (y, z, n) == (1.0, 1.0, 1.0) and another for (2.0, 1.0, 1.0)).
Start from import itertools as it.
Then define the following function to get the count of your "wanted"
elements from the current group:
def getCnt(grp):
return sum(filter(lambda x: x >= 5, [ len(list(group))
for key, group in it.groupby(grp.x, lambda elem: elem >= 0.5)
if key ]))
Note that it contains it.groupby, i.e. groupby function from itertools
(not the pandasonic version of it).
The difference is that the itertools version starts a new group on each change
of the grouping key (by default, the value of the source element).
Steps:
it.groupby(grp.x, lambda elem: elem >= 0.5) - create an iterator,
returning pairs (key, group), from x column of the current group.
The key states whether the current group (from itertools grouping)
contains your "wanted" elements (>= 0.5) and the group contains these
elements.
[ len(list(group)) for key, group in … if key ] - get a list of
lengths of groups, excluding groups of "smaller" elements.
filter(lambda x: x >= 5, …) - filter the above list, leaving only counts
of groups with 5 or more members.
sum(…) - sum the above counts.
Then, to get your expected result, as a DataFrame, apply this function to
each group of rows, this time grouping with the pandasonic version of
groupby.
Then set the name of the resulting Series (it will be the column name
in the final result) and reset the index, to convert it to a DataFrame.
The code to do it is:
result = df.groupby(['y','z','n']).apply(getCnt).rename('Cnt').reset_index()
The result is:
y z n Cnt
0 1.0 1.0 1.0 11
1 2.0 1.0 1.0 5

Define data at cell centers using VTK format

I would like to write a post-processor in order to open some flow field data in paraview (using vtk legacy format). I am fine with the mesh loading, but I have a question on the variables arrangement.
I need to put a value in every cell center and not in the cell nodes. Thus, I have one value for each cell and no way to have a value for each node. Do you know a way to fix this problem?
Thank you very much for your kind help
Sure, you can specify cell data in the legacy ASCII VTK file format. Here's a simple example of a rectilinear grid with two cell data arrays with vector elements:
# vtk DataFile Version 2.0
ASCII
DATASET RECTILINEAR_GRID
DIMENSIONS 4 2 2
X_COORDINATES 4 double
0.0 10.0 20.0 30.0
Y_COORDINATES 2 double
0.0 10.0
Z_COORDINATES 2 double
0.0 10.0
CELL_DATA 3
VECTORS first_array double
-1.0 0.0 0.0
0.0 1.0 0.0
1.0 0.0 0.0
VECTORS second_array double
-1.0 0.0 0.0
0.0 1.0 0.0
1.0 0.0 0.0

2D plots from several input data files

My code is returning 1000 snapshot_XXXX.dat files (XXXX = 0001, 0002,...). They are two columns data files that take a picture of the system I am running at a specific time. I would like to mix them in the order they are created to build a 2D plot (or heatmap) that will show the evolution of the quantity I am following over time.
How can I do this using gnuplot?
Assuming you want the time axis going from bottom to top, you could try the following:
n=4 # Number of snapshots
set palette defined (0 "white", 1 "red")
unset key
set style fill solid
set ylabel "Snapshot/Time"
set yrange [0.5:n+0.5]
set ytics 1
# This functions gives the name of the snapshot file
snapshot(i) = sprintf("snapshot_%04d.dat", i)
# Plot all snapshot files.
# - "with boxes" fakes the heat map
# - "linecolor palette" takes the third column in the "using"
# instruction which is the second column in the datafiles
# Plot from top to bottom because each boxplot overlays the previous ones.
plot for [i=1:n] snapshot(n+1-i) using 1:(n+1.5-i):2 with boxes linecolor palette
This example data
snapshot_0001.dat snapshot_0002.dat snapshot_0003.dat snapshot_0004.dat
1.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0
1.5 0.0 1.5 0.0 1.5 0.0 1.5 0.0
2.0 0.5 2.0 0.7 2.0 0.7 2.0 0.7
2.5 1.0 2.5 1.5 2.5 1.5 2.5 1.5
3.0 0.5 3.0 0.7 3.0 1.1 3.0 1.5
3.5 0.0 3.5 0.0 3.5 0.7 3.5 1.1
4.0 0.0 4.0 0.0 4.0 0.0 4.0 0.7
4.5 0.0 4.5 0.0 4.5 0.0 4.5 0.0
5.0 0.0 5.0 0.0 5.0 0.0 5.0 0.0
results in this image (tested with Gnuplot 5.0):
You can change the order of the plots if you want to go from top to bottom. If you want to go from left to right, maybe this can help (not tested).

Haskell: can't understand the bottleneck

I solved a Project Euler problem and then confronted my solution with the one on the Haskell wiki. They were pretty similar, but mine was taking 7.5 seconds, while the other 0.6! I compiled them both.
Mine looks as follows:
main = print . maximumBy (compare `on` cycleLength) $ [1..999]
where cycleLength d = remainders d 10 []
and the one of the wiki:
main = print . fst $ maximumBy (comparing snd) [(n, cycleLength n) | n <- [1..999]]
where cycleLength d = remainders d 10 []
I also tried to change compare `on` with comparing cycleLength but the performance remained the same.
So I must conclude that all the difference lays in computing values on the fly vs. doing the transformation in the list comprehension.
The difference in time is pretty huge though: the second version has 12.5x speedup!
The maximumBy function will repeatedly check the same number in your list multiple times — and every time it checks a number, it will have to re-compute cycleLength. And that's an expensive operation!
The wiki algorithm thus uses a technique known as decorate-sort-undecorate. Now, here you're not sorting, but it's close enough. You first precompute the cycleLength values for all numbers, (i.e. you make a 'cache') then you do the maximum operation, and then you undecorate them (using fst.) That way, you save yourself a lot of computing!
EDIT: to illustrate it, have a look at the maximumBy function in the Data.List source:
-- | The 'maximumBy' function takes a comparison function and a list
-- and returns the greatest element of the list by the comparison function.
-- The list must be finite and non-empty.
maximumBy :: (a -> a -> Ordering) -> [a] -> a
maximumBy _ [] = error "List.maximumBy: empty list"
maximumBy cmp xs = foldl1 maxBy xs
where
maxBy x y = case cmp x y of
GT -> x
_ -> y
It moves in a window of 2; every number is requested (and in your case computed) twice.
This means that for 999 iterations, your version will call cycleLength d 1996 times (n*2-2), whereas the wiki version would call it 999 (n) times.
This doesn't explain the full delay — only a factor of 2, but the factor was closer to about 10.
Here's the profile of your version,
COST CENTRE entries %time %alloc %time %alloc
MAIN 0 0.0 0.0 100.0 100.0
CAF 0 0.0 0.0 100.0 100.0
main 1 0.0 0.0 100.0 100.0
f 1 0.0 0.0 100.0 100.0
maximumBy 1 0.0 0.0 100.0 99.9
maximumBy.maxBy 998 0.0 0.1 100.0 99.9
cycleLength 1996 0.1 0.2 100.0 99.8
remainders 581323 99.3 94.4 99.9 99.7
remainders.r' 581294 0.7 5.2 0.7 5.2
and the wiki version:
COST CENTRE entries %time %alloc %time %alloc
MAIN 0 0.0 0.0 100.0 100.0
CAF 0 0.0 0.0 100.0 99.9
main 1 0.0 0.1 100.0 99.9
f' 1 0.0 0.8 100.0 99.8
cycleLength 999 0.2 0.5 100.0 98.6
remainders 95845 98.3 93.0 99.8 98.2
remainders.r' 95817 1.5 5.2 1.5 5.2
maximumBy 1 0.0 0.1 0.0 0.4
maximumBy.maxBy 998 0.0 0.2 0.0 0.2
Looking at the profile here, it seems that your version goes through a lot more allocations (around 10-12 times as many,) but doesn't use a lot more RAM overall. So we need to explain about a cumulative factor of 5 or 6 in terms of allocations.
Remainders is recursive. In your example, it gets called 581294 times. In the wiki example, it gets called 95817 times. There's our 5-6 fold increase!
So I think the compare call here is also a problem. Since it applies cycleLength to both things we want to compare as well! In the wiki problem, cycleLength gets applied to every number, but here, we have it applied to every number twice, and the comparison seems to be applied more often, and that is a problem especially with the bigger numbers, since remainders has a bad complexity (it seems exponential, but I'm not sure.)
Since the maximum memory consumption of both programs isn't that dramatically different, I don't think this has anything to do with the heap.

Optimizing sum, ZipList, Vector, and unboxed types

I have identified the following hotspot function that is currently 25% of my program execution time:
type EncodeLookup = [(GF256Elm, [GF256Elm])]
-- | Given the coefficients of a Polynomial and an x value,
-- calculate its corresponding y value.
-- coefficients are in ascending order [d, a1, a2, a3...] where y = d + a1*x + a2*x^2 ...
calc :: EncodeLookup -> [GF256Elm] -> [GF256Elm]
calc xsLookup poly =
map f xsLookup
where
f (_, pList) =
let zl = (*) <$> ZipList (pList) <*> ZipList poly
lst = getZipList zl
s = sum lst
in s
Where GF256Elm is just a newtype wrapper around an Int, with custom * and other operations defined for it (FiniteFields).
Here are the related profiling data for this function:
individual inherited
COST CENTRE no. entries %time %alloc %time %alloc
calc 544 794418 1.6 3.1 27.5 19.7
calc.f 698 3972090 0.9 0.0 25.9 16.6
calc.f.s 709 3972090 7.4 6.2 11.0 7.8
fromInteger 711 3972090 0.7 0.0 0.7 0.0
+ 710 11916270 2.9 1.6 2.9 1.6
calc.f.lst 708 3972090 0.0 0.0 0.0 0.0
calc.f.zl 699 3972090 6.8 8.8 14.0 8.8
* 712 11916270 7.2 0.0 7.2 0.0
My observations:
sum's slowness probably came from the lazy list thunks
* calculation takes a while too. You can see the full implementation of GF256Elm here. * is basically a vector lookup of pregenerated table and some bit flipping.
'ZipList` seems to take a significant amount of time as well.
My questions:
How would I go about optimizing this function? Especially regarding sum - would using deepSeq on the list make it faster?
Should I be using unboxed Int# type for GF256Elm? What other ways can I improve the speed of GF256Elm's operations?
Thanks!

Resources